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:
Alessandro Decina 2015-04-02 18:05:55 +11:00 committed by Tim-Philipp Müller
parent 36419f2f79
commit 83990b491e
3 changed files with 127 additions and 96 deletions

View file

@ -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);

View file

@ -115,32 +115,34 @@ gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context)
height); height);
} }
static gboolean static void
gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api, gst_gl_context_eagl_release_layer (GstGLContext * context)
GstGLContext * other_context, GError ** error)
{ {
GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context); GstGLContextEagl *context_eagl;
GstGLContextEaglPrivate *priv = context_eagl->priv;
GstGLWindow *window = gst_gl_context_get_window (context);
UIView *window_handle = nil;
dispatch_sync (dispatch_get_main_queue (), ^{ context_eagl = GST_GL_CONTEXT_EAGL (context);
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]; if (context_eagl->priv->eagl_layer) {
[share_group release]; gst_gl_context_eagl_activate (context, TRUE);
} else {
priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; [context_eagl->priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:nil];
glDeleteFramebuffers (1, &context_eagl->priv->framebuffer);
context_eagl->priv->framebuffer = 0;
glDeleteRenderbuffers (1, &context_eagl->priv->depth_renderbuffer);
context_eagl->priv->depth_renderbuffer = 0;
glDeleteRenderbuffers (1, &context_eagl->priv->color_renderbuffer);
context_eagl->priv->color_renderbuffer = 0;
context_eagl->priv->eagl_layer = nil;
gst_gl_context_eagl_activate (context, FALSE);
}
} }
});
if (window) void
window_handle = (UIView *) gst_gl_window_get_window_handle (window); gst_gl_context_eagl_update_layer (GstGLContext * context)
{
if (window_handle) {
__block GLuint framebuffer; __block GLuint framebuffer;
__block GLuint color_renderbuffer; __block GLuint color_renderbuffer;
__block GLuint depth_renderbuffer; __block GLuint depth_renderbuffer;
@ -148,6 +150,23 @@ gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
__block GLint height; __block GLint height;
__block CAEAGLLayer *eagl_layer; __block CAEAGLLayer *eagl_layer;
GLenum status; 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 (), ^{ dispatch_sync (dispatch_get_main_queue (), ^{
eagl_layer = (CAEAGLLayer *)[window_handle layer]; eagl_layer = (CAEAGLLayer *)[window_handle layer];
@ -184,9 +203,7 @@ gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
status = glCheckFramebufferStatus (GL_FRAMEBUFFER); status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) { if (status != GL_FRAMEBUFFER_COMPLETE) {
GST_ERROR ("Failed to make complete framebuffer object %x", status); GST_ERROR ("Failed to make complete framebuffer object %x", status);
if (window) goto out;
gst_object_unref (window);
return FALSE;
} }
glBindFramebuffer (GL_FRAMEBUFFER, 0); glBindFramebuffer (GL_FRAMEBUFFER, 0);
@ -194,15 +211,39 @@ gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
priv->framebuffer = framebuffer; priv->framebuffer = framebuffer;
priv->color_renderbuffer = color_renderbuffer; priv->color_renderbuffer = color_renderbuffer;
priv->depth_renderbuffer = depth_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 { } else {
priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
}
});
priv->eagl_layer = NULL; priv->eagl_layer = NULL;
priv->framebuffer = 0; priv->framebuffer = 0;
priv->color_renderbuffer = 0; priv->color_renderbuffer = 0;
priv->depth_renderbuffer = 0; priv->depth_renderbuffer = 0;
}
if (window) GST_INFO_OBJECT (context, "context created, updating layer");
gst_object_unref (window); gst_gl_context_eagl_update_layer (context);
return TRUE; return TRUE;
} }
@ -217,22 +258,7 @@ gst_gl_context_eagl_destroy_context (GstGLContext * context)
if (!context_eagl->priv->eagl_context) if (!context_eagl->priv->eagl_context)
return; return;
if (context_eagl->priv->eagl_layer) { gst_gl_context_eagl_release_layer (context);
gst_gl_context_eagl_activate (context, TRUE);
[context_eagl->priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:nil];
glDeleteFramebuffers (1, &context_eagl->priv->framebuffer);
context_eagl->priv->framebuffer = 0;
glDeleteRenderbuffers (1, &context_eagl->priv->depth_renderbuffer);
context_eagl->priv->depth_renderbuffer = 0;
glDeleteRenderbuffers (1, &context_eagl->priv->color_renderbuffer);
context_eagl->priv->color_renderbuffer = 0;
context_eagl->priv->eagl_layer = nil;
gst_gl_context_eagl_activate (context, FALSE);
}
[context_eagl->priv->eagl_context release]; [context_eagl->priv->eagl_context release];
context_eagl->priv->eagl_context = nil; context_eagl->priv->eagl_context = nil;

View file

@ -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