diff options
author | Alessandro Decina <alessandro.d@gmail.com> | 2015-04-02 18:05:55 +1100 |
---|---|---|
committer | Alessandro Decina <alessandro.d@gmail.com> | 2015-04-02 18:29:39 +1100 |
commit | 6981a8d15b17094cde8a2cec0a2c821c6eaa9547 (patch) | |
tree | 51a1e1e3c7ea49eaef4131c38f5ad813e5a9b821 /gst-libs/gst/gl/eagl | |
parent | 5a6024850c2b6bb4e235ce2c71a127b2ea9871a5 (diff) | |
download | gstreamer-plugins-bad-6981a8d15b17094cde8a2cec0a2c821c6eaa9547.tar.gz |
libgstgl: fix rendering on iOS
Stop assuming that the handle has been set by the time ->create_context is
called. After bc7a7259f357b0065dd94e0668b5a895d83fa53a set_window_handle always
happens after ->create_context in fact.
See also https://bugzilla.gnome.org/show_bug.cgi?id=745090
Diffstat (limited to 'gst-libs/gst/gl/eagl')
-rw-r--r-- | gst-libs/gst/gl/eagl/gstglcontext_eagl.h | 1 | ||||
-rw-r--r-- | gst-libs/gst/gl/eagl/gstglcontext_eagl.m | 194 | ||||
-rw-r--r-- | gst-libs/gst/gl/eagl/gstglwindow_eagl.m | 4 |
3 files changed, 115 insertions, 84 deletions
diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h index b621b3504..c8997ff0e 100644 --- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h +++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h @@ -59,6 +59,7 @@ GType gst_gl_context_eagl_get_type (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_prepare_draw (GstGLContextEagl * context); void gst_gl_context_eagl_finish_draw (GstGLContextEagl * context); diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m index e01fa6216..9fb29e65e 100644 --- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m +++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m @@ -115,14 +115,114 @@ gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context) height); } +static void +gst_gl_context_eagl_release_layer (GstGLContext * context) +{ + GstGLContextEagl *context_eagl; + + context_eagl = GST_GL_CONTEXT_EAGL (context); + + if (context_eagl->priv->eagl_layer) { + 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); + } +} + +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; - GstGLWindow *window = gst_gl_context_get_window (context); - UIView *window_handle = nil; dispatch_sync (dispatch_get_main_queue (), ^{ if (other_context) { @@ -136,73 +236,14 @@ gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api, priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; } }); + + priv->eagl_layer = NULL; + priv->framebuffer = 0; + priv->color_renderbuffer = 0; + priv->depth_renderbuffer = 0; - 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); + GST_INFO_OBJECT (context, "context created, updating layer"); + gst_gl_context_eagl_update_layer (context); return TRUE; } @@ -217,22 +258,7 @@ gst_gl_context_eagl_destroy_context (GstGLContext * context) if (!context_eagl->priv->eagl_context) return; - if (context_eagl->priv->eagl_layer) { - 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); - } + gst_gl_context_eagl_release_layer (context); [context_eagl->priv->eagl_context release]; context_eagl->priv->eagl_context = nil; diff --git a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m index f1fc8b8f5..e1d06fdb1 100644 --- a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m +++ b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m @@ -139,10 +139,14 @@ static void gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle) { GstGLWindowEagl *window_eagl; + GstGLContext *context; window_eagl = GST_GL_WINDOW_EAGL (window); + context = gst_gl_window_get_context (window); window_eagl->priv->view = (UIView *) handle; + GST_INFO_OBJECT (context, "handle set, updating layer"); + gst_gl_context_eagl_update_layer (context); } static gboolean |