mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 12:41:05 +00:00
libgstgl: fix rendering on iOS
Stop assuming that the handle has been set by the time ->create_context is
called. After bc7a7259f3
set_window_handle always
happens after ->create_context in fact.
See also https://bugzilla.gnome.org/show_bug.cgi?id=745090
This commit is contained in:
parent
36419f2f79
commit
83990b491e
3 changed files with 127 additions and 96 deletions
|
@ -59,6 +59,7 @@ GType gst_gl_context_eagl_get_type (void);
|
||||||
|
|
||||||
GstGLContextEagl * gst_gl_context_eagl_new (void);
|
GstGLContextEagl * gst_gl_context_eagl_new (void);
|
||||||
|
|
||||||
|
void gst_gl_context_eagl_update_layer (GstGLContext * context);
|
||||||
void gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context);
|
void gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context);
|
||||||
void gst_gl_context_eagl_prepare_draw (GstGLContextEagl * context);
|
void gst_gl_context_eagl_prepare_draw (GstGLContextEagl * context);
|
||||||
void gst_gl_context_eagl_finish_draw (GstGLContextEagl * context);
|
void gst_gl_context_eagl_finish_draw (GstGLContextEagl * context);
|
||||||
|
|
|
@ -115,108 +115,13 @@ gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context)
|
||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
|
|
||||||
GstGLContext * other_context, GError ** error)
|
|
||||||
{
|
|
||||||
GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
|
|
||||||
GstGLContextEaglPrivate *priv = context_eagl->priv;
|
|
||||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
|
||||||
UIView *window_handle = nil;
|
|
||||||
|
|
||||||
dispatch_sync (dispatch_get_main_queue (), ^{
|
|
||||||
if (other_context) {
|
|
||||||
EAGLContext *external_gl_context = (EAGLContext *)
|
|
||||||
gst_gl_context_get_gl_context (other_context);
|
|
||||||
EAGLSharegroup *share_group = [external_gl_context sharegroup];
|
|
||||||
|
|
||||||
priv->eagl_context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
|
|
||||||
[share_group release];
|
|
||||||
} else {
|
|
||||||
priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (window)
|
|
||||||
window_handle = (UIView *) gst_gl_window_get_window_handle (window);
|
|
||||||
|
|
||||||
if (window_handle) {
|
|
||||||
__block GLuint framebuffer;
|
|
||||||
__block GLuint color_renderbuffer;
|
|
||||||
__block GLuint depth_renderbuffer;
|
|
||||||
__block GLint width;
|
|
||||||
__block GLint height;
|
|
||||||
__block CAEAGLLayer *eagl_layer;
|
|
||||||
GLenum status;
|
|
||||||
|
|
||||||
dispatch_sync (dispatch_get_main_queue (), ^{
|
|
||||||
eagl_layer = (CAEAGLLayer *)[window_handle layer];
|
|
||||||
[EAGLContext setCurrentContext:priv->eagl_context];
|
|
||||||
|
|
||||||
/* Allocate framebuffer */
|
|
||||||
glGenFramebuffers (1, &framebuffer);
|
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
|
||||||
/* Allocate color render buffer */
|
|
||||||
glGenRenderbuffers (1, &color_renderbuffer);
|
|
||||||
glBindRenderbuffer (GL_RENDERBUFFER, color_renderbuffer);
|
|
||||||
[priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
|
|
||||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
GL_RENDERBUFFER, color_renderbuffer);
|
|
||||||
/* Get renderbuffer width/height */
|
|
||||||
glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
|
|
||||||
&width);
|
|
||||||
glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
|
|
||||||
&height);
|
|
||||||
/* allocate depth render buffer */
|
|
||||||
glGenRenderbuffers (1, &depth_renderbuffer);
|
|
||||||
glBindRenderbuffer (GL_RENDERBUFFER, depth_renderbuffer);
|
|
||||||
glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
|
|
||||||
height);
|
|
||||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
|
||||||
GL_RENDERBUFFER, depth_renderbuffer);
|
|
||||||
[EAGLContext setCurrentContext:nil];
|
|
||||||
});
|
|
||||||
|
|
||||||
[EAGLContext setCurrentContext:priv->eagl_context];
|
|
||||||
|
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
|
||||||
/* check creation status */
|
|
||||||
status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
|
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
GST_ERROR ("Failed to make complete framebuffer object %x", status);
|
|
||||||
if (window)
|
|
||||||
gst_object_unref (window);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
|
||||||
|
|
||||||
priv->eagl_layer = eagl_layer;
|
|
||||||
priv->framebuffer = framebuffer;
|
|
||||||
priv->color_renderbuffer = color_renderbuffer;
|
|
||||||
priv->depth_renderbuffer = depth_renderbuffer;
|
|
||||||
} else {
|
|
||||||
priv->eagl_layer = NULL;
|
|
||||||
priv->framebuffer = 0;
|
|
||||||
priv->color_renderbuffer = 0;
|
|
||||||
priv->depth_renderbuffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window)
|
|
||||||
gst_object_unref (window);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_context_eagl_destroy_context (GstGLContext * context)
|
gst_gl_context_eagl_release_layer (GstGLContext * context)
|
||||||
{
|
{
|
||||||
GstGLContextEagl *context_eagl;
|
GstGLContextEagl *context_eagl;
|
||||||
|
|
||||||
context_eagl = GST_GL_CONTEXT_EAGL (context);
|
context_eagl = GST_GL_CONTEXT_EAGL (context);
|
||||||
|
|
||||||
if (!context_eagl->priv->eagl_context)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (context_eagl->priv->eagl_layer) {
|
if (context_eagl->priv->eagl_layer) {
|
||||||
gst_gl_context_eagl_activate (context, TRUE);
|
gst_gl_context_eagl_activate (context, TRUE);
|
||||||
|
|
||||||
|
@ -233,6 +138,127 @@ gst_gl_context_eagl_destroy_context (GstGLContext * context)
|
||||||
context_eagl->priv->eagl_layer = nil;
|
context_eagl->priv->eagl_layer = nil;
|
||||||
gst_gl_context_eagl_activate (context, FALSE);
|
gst_gl_context_eagl_activate (context, FALSE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_gl_context_eagl_update_layer (GstGLContext * context)
|
||||||
|
{
|
||||||
|
__block GLuint framebuffer;
|
||||||
|
__block GLuint color_renderbuffer;
|
||||||
|
__block GLuint depth_renderbuffer;
|
||||||
|
__block GLint width;
|
||||||
|
__block GLint height;
|
||||||
|
__block CAEAGLLayer *eagl_layer;
|
||||||
|
GLenum status;
|
||||||
|
GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
|
||||||
|
GstGLContextEaglPrivate *priv = context_eagl->priv;
|
||||||
|
UIView *window_handle = nil;
|
||||||
|
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||||
|
if (window)
|
||||||
|
window_handle = (UIView *) gst_gl_window_get_window_handle (window);
|
||||||
|
|
||||||
|
if (!window_handle) {
|
||||||
|
GST_INFO_OBJECT (context, "window handle not set yet, not updating layer");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (context, "updating layer, frame %fx%f",
|
||||||
|
window_handle.frame.size.width, window_handle.frame.size.height);
|
||||||
|
|
||||||
|
if (priv->eagl_layer)
|
||||||
|
gst_gl_context_eagl_release_layer (context);
|
||||||
|
|
||||||
|
dispatch_sync (dispatch_get_main_queue (), ^{
|
||||||
|
eagl_layer = (CAEAGLLayer *)[window_handle layer];
|
||||||
|
[EAGLContext setCurrentContext:priv->eagl_context];
|
||||||
|
|
||||||
|
/* Allocate framebuffer */
|
||||||
|
glGenFramebuffers (1, &framebuffer);
|
||||||
|
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||||
|
/* Allocate color render buffer */
|
||||||
|
glGenRenderbuffers (1, &color_renderbuffer);
|
||||||
|
glBindRenderbuffer (GL_RENDERBUFFER, color_renderbuffer);
|
||||||
|
[priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
|
||||||
|
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_RENDERBUFFER, color_renderbuffer);
|
||||||
|
/* Get renderbuffer width/height */
|
||||||
|
glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
|
||||||
|
&width);
|
||||||
|
glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
|
||||||
|
&height);
|
||||||
|
/* allocate depth render buffer */
|
||||||
|
glGenRenderbuffers (1, &depth_renderbuffer);
|
||||||
|
glBindRenderbuffer (GL_RENDERBUFFER, depth_renderbuffer);
|
||||||
|
glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
|
||||||
|
height);
|
||||||
|
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||||
|
GL_RENDERBUFFER, depth_renderbuffer);
|
||||||
|
[EAGLContext setCurrentContext:nil];
|
||||||
|
});
|
||||||
|
|
||||||
|
[EAGLContext setCurrentContext:priv->eagl_context];
|
||||||
|
|
||||||
|
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||||
|
/* check creation status */
|
||||||
|
status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
GST_ERROR ("Failed to make complete framebuffer object %x", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
priv->eagl_layer = eagl_layer;
|
||||||
|
priv->framebuffer = framebuffer;
|
||||||
|
priv->color_renderbuffer = color_renderbuffer;
|
||||||
|
priv->depth_renderbuffer = depth_renderbuffer;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (window)
|
||||||
|
gst_object_unref (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
|
||||||
|
GstGLContext * other_context, GError ** error)
|
||||||
|
{
|
||||||
|
GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
|
||||||
|
GstGLContextEaglPrivate *priv = context_eagl->priv;
|
||||||
|
|
||||||
|
dispatch_sync (dispatch_get_main_queue (), ^{
|
||||||
|
if (other_context) {
|
||||||
|
EAGLContext *external_gl_context = (EAGLContext *)
|
||||||
|
gst_gl_context_get_gl_context (other_context);
|
||||||
|
EAGLSharegroup *share_group = [external_gl_context sharegroup];
|
||||||
|
|
||||||
|
priv->eagl_context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
|
||||||
|
[share_group release];
|
||||||
|
} else {
|
||||||
|
priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
priv->eagl_layer = NULL;
|
||||||
|
priv->framebuffer = 0;
|
||||||
|
priv->color_renderbuffer = 0;
|
||||||
|
priv->depth_renderbuffer = 0;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (context, "context created, updating layer");
|
||||||
|
gst_gl_context_eagl_update_layer (context);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gl_context_eagl_destroy_context (GstGLContext * context)
|
||||||
|
{
|
||||||
|
GstGLContextEagl *context_eagl;
|
||||||
|
|
||||||
|
context_eagl = GST_GL_CONTEXT_EAGL (context);
|
||||||
|
|
||||||
|
if (!context_eagl->priv->eagl_context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gst_gl_context_eagl_release_layer (context);
|
||||||
|
|
||||||
[context_eagl->priv->eagl_context release];
|
[context_eagl->priv->eagl_context release];
|
||||||
context_eagl->priv->eagl_context = nil;
|
context_eagl->priv->eagl_context = nil;
|
||||||
|
|
|
@ -139,10 +139,14 @@ static void
|
||||||
gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle)
|
gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle)
|
||||||
{
|
{
|
||||||
GstGLWindowEagl *window_eagl;
|
GstGLWindowEagl *window_eagl;
|
||||||
|
GstGLContext *context;
|
||||||
|
|
||||||
window_eagl = GST_GL_WINDOW_EAGL (window);
|
window_eagl = GST_GL_WINDOW_EAGL (window);
|
||||||
|
context = gst_gl_window_get_context (window);
|
||||||
|
|
||||||
window_eagl->priv->view = (UIView *) handle;
|
window_eagl->priv->view = (UIView *) handle;
|
||||||
|
GST_INFO_OBJECT (context, "handle set, updating layer");
|
||||||
|
gst_gl_context_eagl_update_layer (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
Loading…
Reference in a new issue