diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index 38883c5aa5..15074f83ab 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -2187,6 +2187,16 @@ gst_glimage_sink_on_resize (GstGLImageSink * gl_sink, gint width, gint height) GST_DEBUG_OBJECT (gl_sink, "GL output area now %u,%u %ux%u", gl_sink->display_rect.x, gl_sink->display_rect.y, gl_sink->display_rect.w, gl_sink->display_rect.h); + } else { + gint viewport_dims[4]; + + /* save the viewport for use later */ + gl->GetIntegerv (GL_VIEWPORT, viewport_dims); + + gl_sink->display_rect.x = viewport_dims[0]; + gl_sink->display_rect.y = viewport_dims[1]; + gl_sink->display_rect.w = viewport_dims[2]; + gl_sink->display_rect.h = viewport_dims[3]; } GST_GLIMAGE_SINK_UNLOCK (gl_sink); } @@ -2234,6 +2244,10 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink) gst_gl_context_clear_shader (gl_sink->context); gl->BindTexture (gl_target, 0); + if (!gst_gl_window_controls_viewport (window)) + gl->Viewport (gl_sink->display_rect.x, gl_sink->display_rect.y, + gl_sink->display_rect.w, gl_sink->display_rect.h); + sample = gst_sample_new (gl_sink->stored_buffer[0], gl_sink->out_caps, &GST_BASE_SINK (gl_sink)->segment, NULL); g_signal_emit (gl_sink, gst_glimage_sink_signals[CLIENT_DRAW_SIGNAL], 0, diff --git a/gst-libs/gst/gl/cocoa/gstglcaopengllayer.m b/gst-libs/gst/gl/cocoa/gstglcaopengllayer.m index 065d596de7..254a3f21f4 100644 --- a/gst-libs/gst/gl/cocoa/gstglcaopengllayer.m +++ b/gst-libs/gst/gl/cocoa/gstglcaopengllayer.m @@ -206,15 +206,21 @@ _context_ready (gpointer data) * the CA viewport set up on entry to this function */ gl->GetIntegerv (GL_VIEWPORT, ca_viewport); + GST_TRACE ("retrieved viewport from CA %u,%u %ux%u", self->expected_dims[0], + self->expected_dims[1], self->expected_dims[2], self->expected_dims[3]); gst_gl_context_activate (self->draw_context, TRUE); if (self->queue_resize || self->last_bounds.size.width != self.bounds.size.width || self->last_bounds.size.height != self.bounds.size.height) { if (self->resize_cb) { - self->resize_cb (self->resize_data, + self->resize_cb (self->resize_data, self.bounds.size.width*self.contentsScale, self.bounds.size.height*self.contentsScale); gl->GetIntegerv (GL_VIEWPORT, self->expected_dims); + + GST_LOG ("resize callback wants viewport %u,%u %ux%u", + self->expected_dims[0], self->expected_dims[1], + self->expected_dims[2], self->expected_dims[3]); } else { /* default to whatever ca gives us */ self->expected_dims[0] = ca_viewport[0]; @@ -239,6 +245,8 @@ _context_ready (gpointer data) gst_video_sink_center_rect (src, dst, &result, TRUE); + GST_TRACE ("Using viewport %u,%u %ux%u", result.x, result.y, result.w, + result.h); gl->Viewport (result.x, result.y, result.w, result.h); if (self->draw_cb) diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m index 91c1187ef3..996c2ea466 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m @@ -81,6 +81,8 @@ static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window, GstGLWindowCB callback, gpointer data, GDestroyNotify destroy); static gboolean gst_gl_window_cocoa_set_render_rectangle (GstGLWindow * window, gint x, gint y, gint width, gint height); +static gboolean gst_gl_window_cocoa_controls_viewport (GstGLWindow * window); + struct _GstGLWindowCocoaPrivate { @@ -125,6 +127,8 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass) GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_send_message_async); window_class->set_render_rectangle = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_render_rectangle); + window_class->controls_viewport = + GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_controls_viewport); gobject_class->finalize = gst_gl_window_cocoa_finalize; } @@ -387,9 +391,11 @@ gst_gl_cocoa_draw_cb (GstGLWindowCocoa *window_cocoa) GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id; if (internal_win_id && ![internal_win_id isClosed]) { - GstGLWindow *window = GST_GL_WINDOW (window_cocoa); + GstGLWindow *window = GST_GL_WINDOW (window_cocoa); /* draw opengl scene in the back buffer */ + /* We do not need to change viewports like in other window implementations + * as the caopengllayer will take care of that for us. */ if (window->draw) window->draw (window->draw_data); } @@ -409,6 +415,7 @@ gst_gl_cocoa_resize_cb (GstGLNSView * view, guint width, guint height) NSRect bounds = [view bounds]; NSRect visibleRect = [view visibleRect]; gint viewport_dim[4]; + GstVideoRectangle viewport; gl = context->gl_vtable; @@ -417,19 +424,30 @@ gst_gl_cocoa_resize_cb (GstGLNSView * view, guint width, guint height) visibleRect = [view convertRectToBacking:visibleRect]; #endif + /* don't use the default gst_gl_window_resize() as that will marshal through + * the GL thread. We are being called from the main thread by the + * caopengllayer */ + if (window->resize) + window->resize (window->resize_data, width, height); + + gl->GetIntegerv (GL_VIEWPORT, viewport_dim); + GST_DEBUG_OBJECT (window, "Window resized: bounds %lf %lf %lf %lf " - "visibleRect %lf %lf %lf %lf", + "visibleRect %lf %lf %lf %lf, " + "viewport dimensions %i %i %i %i", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height, visibleRect.origin.x, visibleRect.origin.y, - visibleRect.size.width, visibleRect.size.height); + visibleRect.size.width, visibleRect.size.height, + viewport_dim[0], viewport_dim[1], viewport_dim[2], + viewport_dim[3]); - gst_gl_window_resize (window, width, height); - gl->GetIntegerv (GL_VIEWPORT, viewport_dim); + viewport.x = viewport_dim[0] - visibleRect.origin.x; + viewport.x = viewport_dim[1] - visibleRect.origin.y; + viewport.w = viewport_dim[2]; + viewport.h = viewport_dim[3]; - gl->Viewport (viewport_dim[0] - visibleRect.origin.x, - viewport_dim[1] - visibleRect.origin.y, - viewport_dim[2], viewport_dim[3]); + gl->Viewport (viewport.x, viewport.y, viewport.w, viewport.h); } gst_object_unref (context); @@ -532,6 +550,12 @@ gst_gl_window_cocoa_set_render_rectangle (GstGLWindow * window, gint x, gint y, return TRUE; } +static gboolean +gst_gl_window_cocoa_controls_viewport (GstGLWindow * window) +{ + return TRUE; +} + /* =============================================================*/ /* */ /* GstGLNSWindow implementation */ diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index 9fa123a42d..351d8598af 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -2531,8 +2531,6 @@ _do_convert_draw (GstGLContext * context, GstGLColorConvert * convert) gint i; gboolean ret = TRUE; - GLint viewport_dim[4] = { 0 }; - GLenum multipleRT[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, @@ -2555,8 +2553,6 @@ _do_convert_draw (GstGLContext * context, GstGLColorConvert * convert) else if (gl->DrawBuffer) gl->DrawBuffer (GL_COLOR_ATTACHMENT0); - gl->GetIntegerv (GL_VIEWPORT, viewport_dim); - gst_gl_framebuffer_get_effective_dimensions (convert->fbo, &out_width, &out_height); gl->Viewport (0, 0, out_width, out_height); @@ -2598,9 +2594,6 @@ _do_convert_draw (GstGLContext * context, GstGLColorConvert * convert) /* we are done with the shader */ gst_gl_context_clear_shader (context); - gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], - viewport_dim[3]); - if (!gst_gl_context_check_framebuffer_status (context, GL_FRAMEBUFFER)) ret = FALSE; diff --git a/gst-libs/gst/gl/gstglframebuffer.c b/gst-libs/gst/gl/gstglframebuffer.c index 98eee348f4..19307ca0bd 100644 --- a/gst-libs/gst/gl/gstglframebuffer.c +++ b/gst-libs/gst/gl/gstglframebuffer.c @@ -269,7 +269,6 @@ gboolean gst_gl_framebuffer_draw_to_texture (GstGLFramebuffer * fb, GstGLMemory * mem, GstGLFramebufferFunc func, gpointer user_data) { - GLint viewport_dim[4] = { 0 }; const GstGLFuncs *gl; gboolean ret; @@ -285,7 +284,6 @@ gst_gl_framebuffer_draw_to_texture (GstGLFramebuffer * fb, GstGLMemory * mem, gst_gl_framebuffer_bind (fb); gst_gl_framebuffer_attach (fb, GL_COLOR_ATTACHMENT0, (GstGLBaseMemory *) mem); - gl->GetIntegerv (GL_VIEWPORT, viewport_dim); gl->Viewport (0, 0, fb->priv->effective_width, fb->priv->effective_height); if (gst_gl_context_get_gl_api (fb->context) & (GST_GL_API_OPENGL | GST_GL_API_OPENGL3)) @@ -296,8 +294,6 @@ gst_gl_framebuffer_draw_to_texture (GstGLFramebuffer * fb, GstGLMemory * mem, if (gst_gl_context_get_gl_api (fb->context) & (GST_GL_API_OPENGL | GST_GL_API_OPENGL3)) gl->DrawBuffer (GL_COLOR_ATTACHMENT0); - gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], - viewport_dim[3]); gst_gl_context_clear_framebuffer (fb->context); return ret; diff --git a/gst-libs/gst/gl/gstglviewconvert.c b/gst-libs/gst/gl/gstglviewconvert.c index 20a94d03b3..89f2e50e6b 100644 --- a/gst-libs/gst/gl/gstglviewconvert.c +++ b/gst-libs/gst/gl/gstglviewconvert.c @@ -1850,7 +1850,6 @@ _do_view_convert_draw (GstGLContext * context, GstGLViewConvert * viewconvert) GstGLFuncs *gl; guint out_width, out_height; gint out_views, i; - GLint viewport_dim[4] = { 0 }; GLenum multipleRT[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, @@ -1886,7 +1885,6 @@ _do_view_convert_draw (GstGLContext * context, GstGLViewConvert * viewconvert) gst_gl_framebuffer_get_effective_dimensions (viewconvert->fbo, &out_width, &out_height); - gl->GetIntegerv (GL_VIEWPORT, viewport_dim); gl->Viewport (0, 0, out_width, out_height); gst_gl_shader_use (viewconvert->shader); @@ -1934,8 +1932,6 @@ _do_view_convert_draw (GstGLContext * context, GstGLViewConvert * viewconvert) gl->DrawBuffer (GL_COLOR_ATTACHMENT0); /* we are done with the shader */ gst_gl_context_clear_shader (context); - gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], - viewport_dim[3]); gst_gl_context_clear_framebuffer (context); return TRUE; diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c index 17ad5edcce..1044b98580 100644 --- a/gst-libs/gst/gl/gstglwindow.c +++ b/gst-libs/gst/gl/gstglwindow.c @@ -975,6 +975,20 @@ gst_gl_window_resize (GstGLWindow * window, guint width, guint height) window->queue_resize = FALSE; } +gboolean +gst_gl_window_controls_viewport (GstGLWindow * window) +{ + GstGLWindowClass *window_class; + + g_return_val_if_fail (GST_IS_GL_WINDOW (window), FALSE); + window_class = GST_GL_WINDOW_GET_CLASS (window); + + if (!window_class->controls_viewport) + return FALSE; + + return window_class->controls_viewport (window); +} + static GType gst_gl_dummy_window_get_type (void); G_DEFINE_TYPE (GstGLDummyWindow, gst_gl_dummy_window, GST_TYPE_GL_WINDOW); diff --git a/gst-libs/gst/gl/gstglwindow.h b/gst-libs/gst/gl/gstglwindow.h index ece8d315b0..9d68a244c0 100644 --- a/gst-libs/gst/gl/gstglwindow.h +++ b/gst-libs/gst/gl/gstglwindow.h @@ -148,6 +148,8 @@ struct _GstGLWindow { * @show: request that the window be shown to the user * @set_render_rectangle: request a rectangle to render into. See #GstVideoOverlay * @queue_resize: request a resize to occur when possible + * @controls_viewport: Whether the window takes care of glViewport setup. + * and the user does not need to deal with viewports */ struct _GstGLWindowClass { GstObjectClass parent_class; @@ -168,9 +170,10 @@ struct _GstGLWindowClass { void (*show) (GstGLWindow *window); gboolean (*set_render_rectangle)(GstGLWindow *window, gint x, gint y, gint width, gint height); void (*queue_resize) (GstGLWindow *window); + gboolean (*controls_viewport) (GstGLWindow *window); /*< private >*/ - gpointer _reserved[GST_PADDING]; + gpointer _reserved[GST_PADDING-1]; }; GST_GL_API @@ -250,6 +253,8 @@ gboolean gst_gl_window_set_render_rectangle (GstGLWindow * window, gint y, gint width, gint height); +GST_GL_API +gboolean gst_gl_window_controls_viewport (GstGLWindow * window); /* subclass usage only */ GST_GL_API diff --git a/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.c b/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.c index 8d6fceb80b..40b8c73a48 100644 --- a/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.c +++ b/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.c @@ -46,6 +46,8 @@ static void gst_gl_window_viv_fb_egl_draw (GstGLWindow * window); static gboolean gst_gl_window_viv_fb_egl_set_render_rectangle (GstGLWindow * window, gint x, gint y, gint width, gint height); +static gboolean gst_gl_window_viv_fb_egl_controls_viewport (GstGLWindow * + window); static void gst_gl_window_viv_fb_egl_class_init (GstGLWindowVivFBEGLClass * klass) @@ -63,6 +65,8 @@ gst_gl_window_viv_fb_egl_class_init (GstGLWindowVivFBEGLClass * klass) window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_viv_fb_egl_draw); window_class->set_render_rectangle = GST_DEBUG_FUNCPTR (gst_gl_window_viv_fb_egl_set_render_rectangle); + window_class->controls_viewport = + GST_DEBUG_FUNCPTR (gst_gl_window_viv_fb_egl_controls_viewport); } static void @@ -179,12 +183,15 @@ draw_cb (gpointer data) gst_gl_window_resize (window, width, height); gl->GetIntegerv (GL_VIEWPORT, viewport_dim); - viewport_dim[0] += window_egl->render_rectangle.x; - viewport_dim[1] += window_egl->render_rectangle.y; - gl->Viewport (viewport_dim[0], - viewport_dim[1], viewport_dim[2], viewport_dim[3]); + window_egl->viewport.x = viewport_dim[0] + window_egl->render_rectangle.x; + window_egl->viewport.y = viewport_dim[1] + window_egl->render_rectangle.y; + window_egl->viewport.w = viewport_dim[2]; + window_egl->viewport.h = viewport_dim[2]; } + gl->Viewport (window_egl->viewport.x, window_egl->viewport.y, + window_egl->viewport.w, window_egl->viewport.h); + if (window->draw) window->draw (window->draw_data); @@ -263,3 +270,9 @@ gst_gl_window_viv_fb_egl_set_render_rectangle (GstGLWindow * window, return TRUE; } + +static gboolean +gst_gl_window_viv_fb_egl_controls_viewport (GstGLWindow * window) +{ + return TRUE; +} diff --git a/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.h b/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.h index 60205e0dcb..244e66368f 100644 --- a/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.h +++ b/gst-libs/gst/gl/viv-fb/gstglwindow_viv_fb_egl.h @@ -47,6 +47,7 @@ struct _GstGLWindowVivFBEGL { gint window_width, window_height; GstVideoRectangle render_rectangle; + GstVideoRectangle viewport; }; struct _GstGLWindowVivFBEGLClass {