From b37e08cb29ddca72161a8098690ba52e5594153d Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 6 Jan 2008 03:01:39 +0000 Subject: sys/glsink/: Handle xoverlay exposes correctly. This means glimagesink works correctly most of the time in totem (fu... Original commit message from CVS: * sys/glsink/glimagesink.c: * sys/glsink/glimagesink.h: * sys/glsink/gstglbuffer.h: * sys/glsink/gstgldisplay.c: * sys/glsink/gstgldisplay.h: * sys/glsink/gstglupload.c: Handle xoverlay exposes correctly. This means glimagesink works correctly most of the time in totem (fullscreening being an execption). Doesn't handle expose events directly to the GL window. --- sys/glsink/glimagesink.c | 25 +++++++++++++++++-- sys/glsink/glimagesink.h | 2 ++ sys/glsink/gstglbuffer.h | 3 +++ sys/glsink/gstgldisplay.c | 63 +++++++++++++++++++++++++++++++++++++++-------- sys/glsink/gstgldisplay.h | 9 +++---- sys/glsink/gstglupload.c | 2 +- 6 files changed, 86 insertions(+), 18 deletions(-) (limited to 'sys/glsink') diff --git a/sys/glsink/glimagesink.c b/sys/glsink/glimagesink.c index 0ce65a27..250a4efc 100644 --- a/sys/glsink/glimagesink.c +++ b/sys/glsink/glimagesink.c @@ -310,6 +310,10 @@ gst_glimage_sink_stop (GstBaseSink * bsink) glimage_sink = GST_GLIMAGE_SINK (bsink); + if (glimage_sink->stored_buffer) { + gst_buffer_unref (glimage_sink->stored_buffer); + glimage_sink->stored_buffer = NULL; + } if (glimage_sink->display) { gst_gl_display_set_visible (glimage_sink->display, FALSE); g_object_unref (glimage_sink->display); @@ -425,6 +429,10 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) glimage_sink = GST_GLIMAGE_SINK (bsink); + if (glimage_sink->stored_buffer) { + gst_buffer_unref (glimage_sink->stored_buffer); + glimage_sink->stored_buffer = NULL; + } if (glimage_sink->is_gl) { gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); @@ -463,8 +471,9 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) GST_BUFFER_DATA (buf)); } + glimage_sink->stored_buffer = gst_gl_buffer_ref (gl_buffer); gst_gl_display_draw_texture (display, gl_buffer->texture, - gl_buffer->width, gl_buffer->height); + gl_buffer->width, gl_buffer->height, TRUE); gst_buffer_unref (GST_BUFFER (gl_buffer)); @@ -505,8 +514,20 @@ gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay, XID window_id) static void gst_glimage_sink_expose (GstXOverlay * overlay) { - /* FIXME */ + GstGLImageSink *glimagesink = GST_GLIMAGE_SINK (overlay); + GST_DEBUG ("expose"); + + if (glimagesink->display) { + gst_gl_display_update_window (glimagesink->display); + } + + if (glimagesink->stored_buffer) { + GstGLBuffer *gl_buffer = glimagesink->stored_buffer; + + gst_gl_display_draw_texture (gl_buffer->display, gl_buffer->texture, + gl_buffer->width, gl_buffer->height, FALSE); + } } static void diff --git a/sys/glsink/glimagesink.h b/sys/glsink/glimagesink.h index 74ec3308..093bc1ca 100644 --- a/sys/glsink/glimagesink.h +++ b/sys/glsink/glimagesink.h @@ -27,6 +27,7 @@ #include #include "gstgldisplay.h" +#include "gstglbuffer.h" GST_DEBUG_CATEGORY_EXTERN (gst_debug_glimage_sink); @@ -61,6 +62,7 @@ struct _GstGLImageSink int par_n, par_d; GstGLDisplay *display; + GstGLBuffer *stored_buffer; XID window_id; }; diff --git a/sys/glsink/gstglbuffer.h b/sys/glsink/gstglbuffer.h index cf2e0141..0cf27def 100644 --- a/sys/glsink/gstglbuffer.h +++ b/sys/glsink/gstglbuffer.h @@ -41,6 +41,9 @@ struct _GstGLBuffer { GType gst_gl_buffer_get_type (void); +#define gst_gl_buffer_ref(x) ((GstGLBuffer *)(gst_buffer_ref((GstBuffer *)(x)))) +#define gst_gl_buffer_unref(x) (gst_buffer_unref((GstBuffer *)(x))) + GstGLBuffer * gst_gl_buffer_new (GstGLDisplay *display, int width, int height); GstGLBuffer * gst_gl_buffer_new_with_format (GstGLDisplay *display, diff --git a/sys/glsink/gstgldisplay.c b/sys/glsink/gstgldisplay.c index d90e5e72..99a732e2 100644 --- a/sys/glsink/gstgldisplay.c +++ b/sys/glsink/gstgldisplay.c @@ -345,17 +345,48 @@ gst_gl_display_set_window (GstGLDisplay * display, Window window) { g_mutex_lock (display->lock); - if (window != display->parent_window) { - gst_gl_display_destroy_tmp_window (display); - + if (display->display == NULL) { display->parent_window = window; + } else { + if (window != display->parent_window) { + XSync (display->display, False); + + gst_gl_display_destroy_tmp_window (display); - gst_gl_display_init_tmp_window (display); + display->parent_window = window; + + gst_gl_display_init_tmp_window (display); + } } g_mutex_unlock (display->lock); } +void +gst_gl_display_update_window (GstGLDisplay * display) +{ + XWindowAttributes attr; + + g_return_if_fail (display != NULL); + + g_mutex_lock (display->lock); + if (display->window != None && display->parent_window != None) { + XSync (display->display, False); + XGetWindowAttributes (display->display, display->parent_window, &attr); + + GST_DEBUG ("new size %d %d", attr.width, attr.height); + + if (display->win_width != attr.width || display->win_height != attr.height) { + XResizeWindow (display->display, display->window, + attr.width, attr.height); + //XSync (display->display, False); + } + display->win_width = attr.width; + display->win_height = attr.height; + } + g_mutex_unlock (display->lock); +} + void gst_gl_display_update_attributes (GstGLDisplay * display) { @@ -375,6 +406,17 @@ gst_gl_display_update_attributes (GstGLDisplay * display) } } +void +gst_gl_display_set_window_size (GstGLDisplay * display, int width, int height) +{ + if (display->win_width != width || display->win_height != height) { + display->win_width = width; + display->win_height = height; + XResizeWindow (display->display, display->window, width, height); + XSync (display->display, False); + } +} + void gst_gl_display_clear (GstGLDisplay * display) { @@ -752,7 +794,7 @@ gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, void gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, - int width, int height) + int width, int height, gboolean sync) { g_return_if_fail (width > 0); g_return_if_fail (height > 0); @@ -763,7 +805,7 @@ gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, g_assert (display->window != None); g_assert (display->context != NULL); - gst_gl_display_update_attributes (display); + //gst_gl_display_update_attributes (display); #if 0 /* Doesn't work */ { @@ -778,10 +820,11 @@ gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, } #endif -#if 1 - /* Doesn't work */ - glXSwapIntervalSGI (1); -#endif + if (sync) { + glXSwapIntervalSGI (1); + } else { + glXSwapIntervalSGI (0); + } glViewport (0, 0, display->win_width, display->win_height); diff --git a/sys/glsink/gstgldisplay.h b/sys/glsink/gstgldisplay.h index 5886884d..1b2c9df5 100644 --- a/sys/glsink/gstgldisplay.h +++ b/sys/glsink/gstgldisplay.h @@ -71,16 +71,15 @@ void gst_gl_display_unlock (GstGLDisplay *display); void gst_gl_display_set_window (GstGLDisplay *display, Window window); void gst_gl_display_update_attributes (GstGLDisplay *display); void gst_gl_display_clear (GstGLDisplay *display); -void gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, - void *data, int width, int height); -void gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, - int width, int height); void gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, - int width, int height); + int width, int height, gboolean sync); void gst_gl_display_check_error (GstGLDisplay *display, int line); GLuint gst_gl_display_upload_texture_rectangle (GstGLDisplay *display, GstVideoFormat type, void *data, int width, int height); void gst_gl_display_set_visible (GstGLDisplay *display, gboolean visible); +void gst_gl_display_set_window_size (GstGLDisplay *display, int width, + int height); +void gst_gl_display_update_window (GstGLDisplay * display); #endif diff --git a/sys/glsink/gstglupload.c b/sys/glsink/gstglupload.c index 036fe55f..ff2b220e 100644 --- a/sys/glsink/gstglupload.c +++ b/sys/glsink/gstglupload.c @@ -430,7 +430,7 @@ gst_gl_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf, if (upload->peek) { gst_gl_display_draw_texture (gl_outbuf->display, gl_outbuf->texture, - gl_outbuf->width, gl_outbuf->height); + gl_outbuf->width, gl_outbuf->height, FALSE); } return GST_FLOW_OK; -- cgit v1.2.1