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);
}
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,
* 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];
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)
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
{
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;
}
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);
}
NSRect bounds = [view bounds];
NSRect visibleRect = [view visibleRect];
gint viewport_dim[4];
+ GstVideoRectangle viewport;
gl = context->gl_vtable;
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);
return TRUE;
}
+static gboolean
+gst_gl_window_cocoa_controls_viewport (GstGLWindow * window)
+{
+ return TRUE;
+}
+
/* =============================================================*/
/* */
/* GstGLNSWindow implementation */
gint i;
gboolean ret = TRUE;
- GLint viewport_dim[4] = { 0 };
-
GLenum multipleRT[] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
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);
/* 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;
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;
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))
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;
GstGLFuncs *gl;
guint out_width, out_height;
gint out_views, i;
- GLint viewport_dim[4] = { 0 };
GLenum multipleRT[] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
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);
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;
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);
* @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;
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
gint y,
gint width,
gint height);
+GST_GL_API
+gboolean gst_gl_window_controls_viewport (GstGLWindow * window);
/* subclass usage only */
GST_GL_API
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)
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
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);
return TRUE;
}
+
+static gboolean
+gst_gl_window_viv_fb_egl_controls_viewport (GstGLWindow * window)
+{
+ return TRUE;
+}
gint window_width, window_height;
GstVideoRectangle render_rectangle;
+ GstVideoRectangle viewport;
};
struct _GstGLWindowVivFBEGLClass {