From 6899b8bb6d8ef5b3a0e5b702595f2a0cb28a194d Mon Sep 17 00:00:00 2001 From: David Schleef Date: Mon, 24 Dec 2007 21:04:46 +0000 Subject: sys/glsink/: Rename glvideo.[ch] to gstgldisplay.[ch]. Original commit message from CVS: * sys/glsink/Makefile.am: * sys/glsink/glimagesink.h: * sys/glsink/glvideo.c: * sys/glsink/glvideo.h: * sys/glsink/gstglbuffer.c: * sys/glsink/gstglbuffer.h: * sys/glsink/gstgldisplay.c: * sys/glsink/gstgldisplay.h: Rename glvideo.[ch] to gstgldisplay.[ch]. --- sys/glsink/Makefile.am | 4 +- sys/glsink/glimagesink.h | 2 +- sys/glsink/glvideo.c | 870 ---------------------------------------------- sys/glsink/glvideo.h | 84 ----- sys/glsink/gstglbuffer.c | 2 +- sys/glsink/gstglbuffer.h | 3 +- sys/glsink/gstgldisplay.c | 870 ++++++++++++++++++++++++++++++++++++++++++++++ sys/glsink/gstgldisplay.h | 84 +++++ 8 files changed, 959 insertions(+), 960 deletions(-) delete mode 100644 sys/glsink/glvideo.c delete mode 100644 sys/glsink/glvideo.h create mode 100644 sys/glsink/gstgldisplay.c create mode 100644 sys/glsink/gstgldisplay.h (limited to 'sys') diff --git a/sys/glsink/Makefile.am b/sys/glsink/Makefile.am index 49d8ac4f..ab1a6536 100644 --- a/sys/glsink/Makefile.am +++ b/sys/glsink/Makefile.am @@ -3,7 +3,7 @@ plugin_LTLIBRARIES = libgstglimagesink.la libgstglimagesink_la_SOURCES = \ glimagesink.c \ - glvideo.c \ + gstgldisplay.c \ gstopengl.c \ glextensions.c \ gstglbuffer.c \ @@ -19,6 +19,6 @@ libgstglimagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) noinst_HEADERS = \ glimagesink.h \ - glvideo.h \ + gstgldisplay.h \ glextensions.h \ gstglbuffer.h diff --git a/sys/glsink/glimagesink.h b/sys/glsink/glimagesink.h index ff60955b..3467c619 100644 --- a/sys/glsink/glimagesink.h +++ b/sys/glsink/glimagesink.h @@ -26,7 +26,7 @@ #include #include -#include "glvideo.h" +#include "gstgldisplay.h" GST_DEBUG_CATEGORY_EXTERN (gst_debug_glimage_sink); diff --git a/sys/glsink/glvideo.c b/sys/glsink/glvideo.c deleted file mode 100644 index b574a154..00000000 --- a/sys/glsink/glvideo.c +++ /dev/null @@ -1,870 +0,0 @@ -/* glvideo.c - * Copyright (C) 2007 David A. Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "glvideo.h" -#include "glextensions.h" -#include - -#include - -static void gst_gl_display_finalize (GObject * object); -static void gst_gl_display_init_tmp_window (GstGLDisplay * display); - -GST_BOILERPLATE (GstGLDisplay, gst_gl_display, GObject, G_TYPE_OBJECT); - -static void -gst_gl_display_base_init (gpointer g_class) -{ - -} - -static void -gst_gl_display_class_init (GstGLDisplayClass * klass) -{ - G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize; -} - -static void -gst_gl_display_init (GstGLDisplay * display, GstGLDisplayClass * klass) -{ - - display->lock = g_mutex_new (); - -} - -static void -gst_gl_display_finalize (GObject * object) -{ - GstGLDisplay *display = GST_GL_DISPLAY (object); - - if (display->assigned_window == None) { - XDestroyWindow (display->display, display->window); - } - if (display->context) { - glXDestroyContext (display->display, display->context); - } - if (display->visinfo) { - XFree (display->visinfo); - } - if (display->display) { - XCloseDisplay (display->display); - } - - if (display->lock) { - g_mutex_free (display->lock); - } -} - -static gboolean gst_gl_display_check_features (GstGLDisplay * display); - -GstGLDisplay * -gst_gl_display_new (void) -{ - return g_object_new (GST_TYPE_GL_DISPLAY, NULL); -} - -#define HANDLE_X_ERRORS -#ifdef HANDLE_X_ERRORS -static int -x_error_handler (Display * display, XErrorEvent * event) -{ - g_assert_not_reached (); -} -#endif - -gboolean -gst_gl_display_connect (GstGLDisplay * display, const char *display_name) -{ - gboolean usable; - XGCValues values; - XPixmapFormatValues *px_formats; - int n_formats; - int i; - - display->display = XOpenDisplay (display_name); - if (display->display == NULL) { - return FALSE; - } -#ifdef HANDLE_X_ERRORS - XSynchronize (display->display, True); - XSetErrorHandler (x_error_handler); -#endif - - usable = gst_gl_display_check_features (display); - if (!usable) { - return FALSE; - } - - display->screen = DefaultScreenOfDisplay (display->display); - display->screen_num = DefaultScreen (display->display); - display->visual = DefaultVisual (display->display, display->screen_num); - display->root = DefaultRootWindow (display->display); - display->white = XWhitePixel (display->display, display->screen_num); - display->black = XBlackPixel (display->display, display->screen_num); - display->depth = DefaultDepthOfScreen (display->screen); - - display->gc = XCreateGC (display->display, - DefaultRootWindow (display->display), 0, &values); - - px_formats = XListPixmapFormats (display->display, &n_formats); - for (i = 0; i < n_formats; i++) { - GST_DEBUG ("%d: depth %d bpp %d pad %d", i, - px_formats[i].depth, - px_formats[i].bits_per_pixel, px_formats[i].scanline_pad); - } - - gst_gl_display_init_tmp_window (display); - - return TRUE; -} - -static gboolean -gst_gl_display_check_features (GstGLDisplay * display) -{ - gboolean ret; - XVisualInfo *visinfo; - Screen *screen; - Window root; - int scrnum; - int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, None - }; - XSetWindowAttributes attr; - int error_base; - int event_base; - int mask; - const char *extstring; - Window window; - - screen = XDefaultScreenOfDisplay (display->display); - scrnum = XScreenNumberOfScreen (screen); - root = XRootWindow (display->display, scrnum); - - ret = glXQueryExtension (display->display, &error_base, &event_base); - if (!ret) { - GST_DEBUG ("No GLX extension"); - return FALSE; - } - - visinfo = glXChooseVisual (display->display, scrnum, attrib); - if (visinfo == NULL) { - GST_DEBUG ("No usable visual"); - return FALSE; - } - - display->visinfo = visinfo; - - display->context = glXCreateContext (display->display, visinfo, NULL, True); - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap (display->display, root, - visinfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask; - attr.override_redirect = True; - - mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect; - - window = XCreateWindow (display->display, root, 0, 0, - 100, 100, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); - - XSync (display->display, FALSE); - - glXMakeCurrent (display->display, window, display->context); - - glGetIntegerv (GL_MAX_TEXTURE_SIZE, &display->max_texture_size); - - extstring = (const char *) glGetString (GL_EXTENSIONS); - - display->have_ycbcr_texture = FALSE; -#ifdef GL_YCBCR_MESA - if (strstr (extstring, "GL_MESA_ycbcr_texture")) { - display->have_ycbcr_texture = TRUE; - } -#endif - - display->have_color_matrix = FALSE; -#ifdef GL_POST_COLOR_MATRIX_RED_BIAS - if (strstr (extstring, "GL_SGI_color_matrix")) { - display->have_color_matrix = TRUE; - } -#endif - - display->have_texture_rectangle = FALSE; -#ifdef GL_TEXTURE_RECTANGLE_ARB - if (strstr (extstring, "GL_ARB_texture_rectangle")) { - display->have_texture_rectangle = TRUE; - } -#endif - - glXMakeCurrent (display->display, None, NULL); - XDestroyWindow (display->display, window); - - return TRUE; -} - -gboolean -gst_gl_display_can_handle_type (GstGLDisplay * display, GstVideoFormat type) -{ - switch (type) { - case GST_VIDEO_FORMAT_RGBx: - case GST_VIDEO_FORMAT_BGRx: - case GST_VIDEO_FORMAT_xRGB: - case GST_VIDEO_FORMAT_xBGR: - return TRUE; - case GST_VIDEO_FORMAT_YUY2: - case GST_VIDEO_FORMAT_UYVY: - return display->have_ycbcr_texture; - case GST_VIDEO_FORMAT_AYUV: - return display->have_color_matrix; - default: - return FALSE; - } -} - -void -gst_gl_display_lock (GstGLDisplay * display) -{ - g_mutex_lock (display->lock); - glXMakeCurrent (display->display, display->window, display->context); - gst_gl_display_check_error (display, __LINE__); -} - -void -gst_gl_display_unlock (GstGLDisplay * display) -{ - gst_gl_display_check_error (display, __LINE__); - glXMakeCurrent (display->display, None, NULL); - g_mutex_unlock (display->lock); -} - -static void -gst_gl_display_init_tmp_window (GstGLDisplay * display) -{ - XSetWindowAttributes attr = { 0 }; - int scrnum; - int mask; - Window root; - Screen *screen; - - GST_ERROR ("creating temp window"); - - screen = XDefaultScreenOfDisplay (display->display); - scrnum = XScreenNumberOfScreen (screen); - root = XRootWindow (display->display, scrnum); - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap (display->display, root, - display->visinfo->visual, AllocNone); - attr.override_redirect = False; -#if 0 - if (display->parent_window) { - attr.override_redirect = True; - } -#endif - - mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect; - - display->window = XCreateWindow (display->display, - root, 0, 0, 100, 100, - 0, display->visinfo->depth, InputOutput, - display->visinfo->visual, mask, &attr); - XMapWindow (display->display, display->window); - XSync (display->display, FALSE); -} - -static void -gst_gl_display_destroy_tmp_window (GstGLDisplay * display) -{ - XDestroyWindow (display->display, display->window); -} - -void -gst_gl_display_set_window (GstGLDisplay * display, Window window) -{ - g_mutex_lock (display->lock); - - if (window != display->assigned_window) { - if (display->assigned_window == None) { - gst_gl_display_destroy_tmp_window (display); - } - display->assigned_window = window; - if (display->assigned_window == None) { - gst_gl_display_init_tmp_window (display); - } else { - display->window = window; - } - } - - g_mutex_unlock (display->lock); -} - -void -gst_gl_display_update_attributes (GstGLDisplay * display) -{ - XWindowAttributes attr; - - if (display->window != None) { - XGetWindowAttributes (display->display, display->window, &attr); - display->win_width = attr.width; - display->win_height = attr.height; - } else { - display->win_width = 0; - display->win_height = 0; - } -} - -void -gst_gl_display_clear (GstGLDisplay * display) -{ - gst_gl_display_lock (display); - - glDepthFunc (GL_LESS); - glEnable (GL_DEPTH_TEST); - glClearColor (0.2, 0.2, 0.2, 1.0); - glViewport (0, 0, display->win_width, display->win_height); - - gst_gl_display_unlock (display); -} - -void -gst_gl_display_check_error (GstGLDisplay * display, int line) -{ - GLenum err = glGetError (); - - if (err) { - GST_ERROR ("GL Error 0x%x at line %d", (int) err, line); - g_assert (0); - } -} - - -GLuint -gst_gl_display_upload_texture_rectangle (GstGLDisplay * display, - GstVideoFormat type, void *data, int width, int height) -{ - GLuint texture; - - glGenTextures (1, &texture); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - - switch (type) { - case GST_VIDEO_FORMAT_RGBx: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, data); - break; - case GST_VIDEO_FORMAT_BGRx: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_BYTE, data); - break; - case GST_VIDEO_FORMAT_xRGB: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - case GST_VIDEO_FORMAT_xBGR: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - case GST_VIDEO_FORMAT_YUY2: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); - break; - case GST_VIDEO_FORMAT_UYVY: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); - break; - case GST_VIDEO_FORMAT_AYUV: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - default: - g_assert_not_reached (); - } - - return texture; -} - - -static void -draw_rect_texture (GstGLDisplay * display, GstVideoFormat type, - void *data, int width, int height) -{ - GLuint texture; - - GST_DEBUG ("using rectangular texture"); - -#ifdef GL_TEXTURE_RECTANGLE_ARB - glEnable (GL_TEXTURE_RECTANGLE_ARB); - //glGenTextures (1, &texture); - //glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - - texture = gst_gl_display_upload_texture_rectangle (display, type, - data, width, height); - - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - -#if 0 - switch (type) { - case GST_VIDEO_FORMAT_RGBx: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, data); - break; - case GST_VIDEO_FORMAT_BGRx: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_BYTE, data); - break; - case GST_VIDEO_FORMAT_xRGB: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - case GST_VIDEO_FORMAT_xBGR: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - case GST_VIDEO_FORMAT_YUY2: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); - break; - case GST_VIDEO_FORMAT_UYVY: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); - break; - case GST_VIDEO_FORMAT_AYUV: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - default: - g_assert_not_reached (); - } - -#ifdef GL_POST_COLOR_MATRIX_RED_BIAS - if (type == GST_VIDEO_FORMAT_AYUV) { - const double matrix[16] = { - 1, 1, 1, 0, - 0, -0.344 * 1, 1.770 * 1, 0, - 1.403 * 1, -0.714 * 1, 0, 0, - 0, 0, 0, 1 - }; - glMatrixMode (GL_COLOR); - glLoadMatrixd (matrix); - glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2); - glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2); - glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2); - } -#endif -#endif - - glColor4f (1, 0, 1, 1); - glBegin (GL_QUADS); - - glNormal3f (0, 0, -1); - - glTexCoord2f (width, 0); - glVertex3f (1.0, 1.0, 0); - glTexCoord2f (0, 0); - glVertex3f (-1.0, 1.0, 0); - glTexCoord2f (0, height); - glVertex3f (-1.0, -1.0, 0); - glTexCoord2f (width, height); - glVertex3f (1.0, -1.0, 0); - glEnd (); - glDeleteTextures (1, &texture); -#else - g_assert_not_reached (); -#endif -} - -static void -draw_pow2_texture (GstGLDisplay * display, GstVideoFormat type, - void *data, int width, int height) -{ - int pow2_width; - int pow2_height; - double x, y; - GLuint texture; - - GST_DEBUG ("using power-of-2 texture"); - - for (pow2_height = 64; - pow2_height < height && pow2_height > 0; pow2_height <<= 1); - for (pow2_width = 64; pow2_width < width && pow2_width > 0; pow2_width <<= 1); - - glEnable (GL_TEXTURE_2D); - glGenTextures (1, &texture); - glBindTexture (GL_TEXTURE_2D, texture); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - switch (type) { - case GST_VIDEO_FORMAT_RGBx: - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, data); - break; - case GST_VIDEO_FORMAT_BGRx: - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_BYTE, data); - break; - case GST_VIDEO_FORMAT_xRGB: - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - case GST_VIDEO_FORMAT_xBGR: - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - case GST_VIDEO_FORMAT_YUY2: - glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); - break; - case GST_VIDEO_FORMAT_UYVY: - glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); - break; - case GST_VIDEO_FORMAT_AYUV: - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); - break; - default: - g_assert_not_reached (); - } - -#ifdef GL_POST_COLOR_MATRIX_RED_BIAS - if (type == GST_VIDEO_FORMAT_AYUV) { - const double matrix[16] = { - 1, 1, 1, 0, - 0, -0.344 * 1, 1.770 * 1, 0, - 1.403 * 1, -0.714 * 1, 0, 0, - 0, 0, 0, 1 - }; - glMatrixMode (GL_COLOR); - glLoadMatrixd (matrix); - glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2); - glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2); - glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2); - } -#endif - - glColor4f (1, 0, 1, 1); - glBegin (GL_QUADS); - - glNormal3f (0, 0, -1); - - x = (double) width / pow2_width; - y = (double) height / pow2_height; - - glTexCoord2f (x, 0); - glVertex3f (1.0, 1.0, 0); - glTexCoord2f (0, 0); - glVertex3f (-1.0, 1.0, 0); - glTexCoord2f (0, y); - glVertex3f (-1.0, -1.0, 0); - glTexCoord2f (x, y); - glVertex3f (1.0, -1.0, 0); - glEnd (); - glDeleteTextures (1, &texture); -} - -void -gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, - void *data, int width, int height) -{ - g_return_if_fail (data != NULL); - g_return_if_fail (width > 0); - g_return_if_fail (height > 0); - - gst_gl_display_lock (display); - -#if 0 - /* Doesn't work */ - { - int64_t ust = 1234; - int64_t mst = 1234; - int64_t sbc = 1234; - gboolean ret; - - ret = glXGetSyncValuesOML (display->display, display->window, - &ust, &mst, &sbc); - GST_DEBUG ("sync values %d %lld %lld %lld", ret, ust, mst, sbc); - } -#endif - -#if 0 - /* Does work, but is not relevant */ - { - int32_t num = 1234; - int32_t den = 1234; - gboolean ret; - - ret = glXGetMscRateOML (display->display, display->window, &num, &den); - GST_DEBUG ("rate %d %d %d", ret, num, den); - } -#endif - - gst_gl_display_update_attributes (display); - - //glXSwapIntervalSGI (1); - glViewport (0, 0, display->win_width, display->win_height); - - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glColor4f (1, 1, 1, 1); - - if (display->have_texture_rectangle) { - draw_rect_texture (display, type, data, width, height); - } else { - draw_pow2_texture (display, type, data, width, height); - } - - glXSwapBuffers (display->display, display->window); -#if 0 - /* Doesn't work */ - { - ret = glXSwapBuffersMscOML (display->display, display->window, 0, 1, 0); - if (ret == 0) { - GST_DEBUG ("glXSwapBuffersMscOML failed"); - } - } -#endif - - gst_gl_display_unlock (display); -} - -void -gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, - int width, int height) -{ - GLuint texture; - GLuint fbo; - - g_return_if_fail (width > 0); - g_return_if_fail (height > 0); - g_return_if_fail (rbo != None); - - gst_gl_display_lock (display); - - g_assert (display->window != None); - g_assert (display->context != NULL); - - gst_gl_display_update_attributes (display); - - glViewport (0, 0, display->win_width, display->win_height); - - glClearColor (0.3, 0.3, 0.3, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glColor4f (1, 1, 1, 1); - - glGenFramebuffersEXT (1, &fbo); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo); - - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rbo); - - glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); - glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); - - g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == - GL_FRAMEBUFFER_COMPLETE_EXT); - -#if 1 - { - void *buffer; - - buffer = malloc (320 * 240 * 4); - memset (buffer, random (), 320 * 240 * 4); - free (buffer); - } -#endif - - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glGenTextures (1, &texture); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, - GL_RGB, GL_UNSIGNED_BYTE, NULL); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_RECTANGLE_ARB, texture, 0); - - glDrawBuffer (0); - glReadBuffer (0); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); - glColor4f (1, 0, 1, 1); - gst_gl_display_check_error (display, __LINE__); -//glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); - glBegin (GL_QUADS); - - glNormal3f (0, 0, -1); - - glTexCoord2f (width, 0); - glVertex3f (0.9, 0.9, 0); - glTexCoord2f (0, 0); - glVertex3f (-0.9, 0.9, 0); - glTexCoord2f (0, height); - glVertex3f (-0.9, -0.9, 0); - glTexCoord2f (width, height); - glVertex3f (0.9, -0.9, 0); - glEnd (); - gst_gl_display_check_error (display, __LINE__); - glDeleteTextures (1, &texture); - - glDeleteFramebuffersEXT (1, &fbo); - gst_gl_display_check_error (display, __LINE__); - - glXSwapBuffers (display->display, display->window); - - gst_gl_display_unlock (display); -} - -void -gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, - int width, int height) -{ - g_return_if_fail (width > 0); - g_return_if_fail (height > 0); - g_return_if_fail (texture != None); - - gst_gl_display_lock (display); - - g_assert (display->window != None); - g_assert (display->context != NULL); - - gst_gl_display_update_attributes (display); - - glViewport (0, 0, display->win_width, display->win_height); - - glClearColor (0.3, 0.3, 0.3, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glColor4f (1, 1, 1, 1); - - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glColor4f (1, 0, 1, 1); - gst_gl_display_check_error (display, __LINE__); - glBegin (GL_QUADS); - - glNormal3f (0, 0, -1); - - glTexCoord2f (width, 0); - glVertex3f (0.9, 0.9, 0); - glTexCoord2f (0, 0); - glVertex3f (-0.9, 0.9, 0); - glTexCoord2f (0, height); - glVertex3f (-0.9, -0.9, 0); - glTexCoord2f (width, height); - glVertex3f (0.9, -0.9, 0); - glEnd (); - gst_gl_display_check_error (display, __LINE__); - - glXSwapBuffers (display->display, display->window); - - gst_gl_display_unlock (display); -} diff --git a/sys/glsink/glvideo.h b/sys/glsink/glvideo.h deleted file mode 100644 index 677c569f..00000000 --- a/sys/glsink/glvideo.h +++ /dev/null @@ -1,84 +0,0 @@ - -#ifndef __GST_GL_H__ -#define __GST_GL_H__ - -#include -#include -#include -#include - -typedef struct _GstGLDisplay GstGLDisplay; -typedef struct _GstGLDisplayClass GstGLDisplayClass; - -#define GST_TYPE_GL_DISPLAY \ - (gst_gl_display_get_type()) -#define GST_GL_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY,GstGLDisplay)) -#define GST_GL_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_DISPLAY,GstGLDisplayClass)) -#define GST_IS_GL_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY)) -#define GST_IS_GL_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_DISPLAY)) - - -struct _GstGLDisplay { - GObject object; - - Display *display; - GC gc; - XVisualInfo *visinfo; - GLXContext context; - GMutex *lock; - - Screen *screen; - int screen_num; - Visual *visual; - Window root; - guint32 white; - guint32 black; - int depth; - - int max_texture_size; - - gboolean have_ycbcr_texture; - gboolean have_texture_rectangle; - gboolean have_color_matrix; - - Window window; - Window assigned_window; - - int win_width; - int win_height; - -}; - -struct _GstGLDisplayClass { - GObjectClass object_class; -}; - -GType gst_gl_display_get_type (void); - - -GstGLDisplay *gst_gl_display_new (void); -gboolean gst_gl_display_connect (GstGLDisplay *display, - const char *display_name); -gboolean gst_gl_display_can_handle_type (GstGLDisplay *display, - GstVideoFormat type); -void gst_gl_display_lock (GstGLDisplay *display); -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); -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); - -#endif - diff --git a/sys/glsink/gstglbuffer.c b/sys/glsink/gstglbuffer.c index f85179bc..9285a7af 100644 --- a/sys/glsink/gstglbuffer.c +++ b/sys/glsink/gstglbuffer.c @@ -4,7 +4,7 @@ #endif #include -#include +#include #include #include #include "glextensions.h" diff --git a/sys/glsink/gstglbuffer.h b/sys/glsink/gstglbuffer.h index 3bb4437c..e24b70f0 100644 --- a/sys/glsink/gstglbuffer.h +++ b/sys/glsink/gstglbuffer.h @@ -4,8 +4,7 @@ #include #include -#include -#include +#include typedef struct _GstGLBuffer GstGLBuffer; diff --git a/sys/glsink/gstgldisplay.c b/sys/glsink/gstgldisplay.c new file mode 100644 index 00000000..7b1c39b2 --- /dev/null +++ b/sys/glsink/gstgldisplay.c @@ -0,0 +1,870 @@ +/* gstgldisplay.c + * Copyright (C) 2007 David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstgldisplay.h" +#include "glextensions.h" +#include + +#include + +static void gst_gl_display_finalize (GObject * object); +static void gst_gl_display_init_tmp_window (GstGLDisplay * display); + +GST_BOILERPLATE (GstGLDisplay, gst_gl_display, GObject, G_TYPE_OBJECT); + +static void +gst_gl_display_base_init (gpointer g_class) +{ + +} + +static void +gst_gl_display_class_init (GstGLDisplayClass * klass) +{ + G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize; +} + +static void +gst_gl_display_init (GstGLDisplay * display, GstGLDisplayClass * klass) +{ + + display->lock = g_mutex_new (); + +} + +static void +gst_gl_display_finalize (GObject * object) +{ + GstGLDisplay *display = GST_GL_DISPLAY (object); + + if (display->assigned_window == None) { + XDestroyWindow (display->display, display->window); + } + if (display->context) { + glXDestroyContext (display->display, display->context); + } + if (display->visinfo) { + XFree (display->visinfo); + } + if (display->display) { + XCloseDisplay (display->display); + } + + if (display->lock) { + g_mutex_free (display->lock); + } +} + +static gboolean gst_gl_display_check_features (GstGLDisplay * display); + +GstGLDisplay * +gst_gl_display_new (void) +{ + return g_object_new (GST_TYPE_GL_DISPLAY, NULL); +} + +#define HANDLE_X_ERRORS +#ifdef HANDLE_X_ERRORS +static int +x_error_handler (Display * display, XErrorEvent * event) +{ + g_assert_not_reached (); +} +#endif + +gboolean +gst_gl_display_connect (GstGLDisplay * display, const char *display_name) +{ + gboolean usable; + XGCValues values; + XPixmapFormatValues *px_formats; + int n_formats; + int i; + + display->display = XOpenDisplay (display_name); + if (display->display == NULL) { + return FALSE; + } +#ifdef HANDLE_X_ERRORS + XSynchronize (display->display, True); + XSetErrorHandler (x_error_handler); +#endif + + usable = gst_gl_display_check_features (display); + if (!usable) { + return FALSE; + } + + display->screen = DefaultScreenOfDisplay (display->display); + display->screen_num = DefaultScreen (display->display); + display->visual = DefaultVisual (display->display, display->screen_num); + display->root = DefaultRootWindow (display->display); + display->white = XWhitePixel (display->display, display->screen_num); + display->black = XBlackPixel (display->display, display->screen_num); + display->depth = DefaultDepthOfScreen (display->screen); + + display->gc = XCreateGC (display->display, + DefaultRootWindow (display->display), 0, &values); + + px_formats = XListPixmapFormats (display->display, &n_formats); + for (i = 0; i < n_formats; i++) { + GST_DEBUG ("%d: depth %d bpp %d pad %d", i, + px_formats[i].depth, + px_formats[i].bits_per_pixel, px_formats[i].scanline_pad); + } + + gst_gl_display_init_tmp_window (display); + + return TRUE; +} + +static gboolean +gst_gl_display_check_features (GstGLDisplay * display) +{ + gboolean ret; + XVisualInfo *visinfo; + Screen *screen; + Window root; + int scrnum; + int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, None + }; + XSetWindowAttributes attr; + int error_base; + int event_base; + int mask; + const char *extstring; + Window window; + + screen = XDefaultScreenOfDisplay (display->display); + scrnum = XScreenNumberOfScreen (screen); + root = XRootWindow (display->display, scrnum); + + ret = glXQueryExtension (display->display, &error_base, &event_base); + if (!ret) { + GST_DEBUG ("No GLX extension"); + return FALSE; + } + + visinfo = glXChooseVisual (display->display, scrnum, attrib); + if (visinfo == NULL) { + GST_DEBUG ("No usable visual"); + return FALSE; + } + + display->visinfo = visinfo; + + display->context = glXCreateContext (display->display, visinfo, NULL, True); + + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap (display->display, root, + visinfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask; + attr.override_redirect = True; + + mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect; + + window = XCreateWindow (display->display, root, 0, 0, + 100, 100, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); + + XSync (display->display, FALSE); + + glXMakeCurrent (display->display, window, display->context); + + glGetIntegerv (GL_MAX_TEXTURE_SIZE, &display->max_texture_size); + + extstring = (const char *) glGetString (GL_EXTENSIONS); + + display->have_ycbcr_texture = FALSE; +#ifdef GL_YCBCR_MESA + if (strstr (extstring, "GL_MESA_ycbcr_texture")) { + display->have_ycbcr_texture = TRUE; + } +#endif + + display->have_color_matrix = FALSE; +#ifdef GL_POST_COLOR_MATRIX_RED_BIAS + if (strstr (extstring, "GL_SGI_color_matrix")) { + display->have_color_matrix = TRUE; + } +#endif + + display->have_texture_rectangle = FALSE; +#ifdef GL_TEXTURE_RECTANGLE_ARB + if (strstr (extstring, "GL_ARB_texture_rectangle")) { + display->have_texture_rectangle = TRUE; + } +#endif + + glXMakeCurrent (display->display, None, NULL); + XDestroyWindow (display->display, window); + + return TRUE; +} + +gboolean +gst_gl_display_can_handle_type (GstGLDisplay * display, GstVideoFormat type) +{ + switch (type) { + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: + return TRUE; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: + return display->have_ycbcr_texture; + case GST_VIDEO_FORMAT_AYUV: + return display->have_color_matrix; + default: + return FALSE; + } +} + +void +gst_gl_display_lock (GstGLDisplay * display) +{ + g_mutex_lock (display->lock); + glXMakeCurrent (display->display, display->window, display->context); + gst_gl_display_check_error (display, __LINE__); +} + +void +gst_gl_display_unlock (GstGLDisplay * display) +{ + gst_gl_display_check_error (display, __LINE__); + glXMakeCurrent (display->display, None, NULL); + g_mutex_unlock (display->lock); +} + +static void +gst_gl_display_init_tmp_window (GstGLDisplay * display) +{ + XSetWindowAttributes attr = { 0 }; + int scrnum; + int mask; + Window root; + Screen *screen; + + GST_ERROR ("creating temp window"); + + screen = XDefaultScreenOfDisplay (display->display); + scrnum = XScreenNumberOfScreen (screen); + root = XRootWindow (display->display, scrnum); + + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap (display->display, root, + display->visinfo->visual, AllocNone); + attr.override_redirect = False; +#if 0 + if (display->parent_window) { + attr.override_redirect = True; + } +#endif + + mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect; + + display->window = XCreateWindow (display->display, + root, 0, 0, 100, 100, + 0, display->visinfo->depth, InputOutput, + display->visinfo->visual, mask, &attr); + XMapWindow (display->display, display->window); + XSync (display->display, FALSE); +} + +static void +gst_gl_display_destroy_tmp_window (GstGLDisplay * display) +{ + XDestroyWindow (display->display, display->window); +} + +void +gst_gl_display_set_window (GstGLDisplay * display, Window window) +{ + g_mutex_lock (display->lock); + + if (window != display->assigned_window) { + if (display->assigned_window == None) { + gst_gl_display_destroy_tmp_window (display); + } + display->assigned_window = window; + if (display->assigned_window == None) { + gst_gl_display_init_tmp_window (display); + } else { + display->window = window; + } + } + + g_mutex_unlock (display->lock); +} + +void +gst_gl_display_update_attributes (GstGLDisplay * display) +{ + XWindowAttributes attr; + + if (display->window != None) { + XGetWindowAttributes (display->display, display->window, &attr); + display->win_width = attr.width; + display->win_height = attr.height; + } else { + display->win_width = 0; + display->win_height = 0; + } +} + +void +gst_gl_display_clear (GstGLDisplay * display) +{ + gst_gl_display_lock (display); + + glDepthFunc (GL_LESS); + glEnable (GL_DEPTH_TEST); + glClearColor (0.2, 0.2, 0.2, 1.0); + glViewport (0, 0, display->win_width, display->win_height); + + gst_gl_display_unlock (display); +} + +void +gst_gl_display_check_error (GstGLDisplay * display, int line) +{ + GLenum err = glGetError (); + + if (err) { + GST_ERROR ("GL Error 0x%x at line %d", (int) err, line); + g_assert (0); + } +} + + +GLuint +gst_gl_display_upload_texture_rectangle (GstGLDisplay * display, + GstVideoFormat type, void *data, int width, int height) +{ + GLuint texture; + + glGenTextures (1, &texture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + + switch (type) { + case GST_VIDEO_FORMAT_RGBx: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, data); + break; + case GST_VIDEO_FORMAT_BGRx: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_BYTE, data); + break; + case GST_VIDEO_FORMAT_xRGB: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + case GST_VIDEO_FORMAT_xBGR: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + case GST_VIDEO_FORMAT_YUY2: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); + break; + case GST_VIDEO_FORMAT_UYVY: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); + break; + case GST_VIDEO_FORMAT_AYUV: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + default: + g_assert_not_reached (); + } + + return texture; +} + + +static void +draw_rect_texture (GstGLDisplay * display, GstVideoFormat type, + void *data, int width, int height) +{ + GLuint texture; + + GST_DEBUG ("using rectangular texture"); + +#ifdef GL_TEXTURE_RECTANGLE_ARB + glEnable (GL_TEXTURE_RECTANGLE_ARB); + //glGenTextures (1, &texture); + //glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + + texture = gst_gl_display_upload_texture_rectangle (display, type, + data, width, height); + + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + +#if 0 + switch (type) { + case GST_VIDEO_FORMAT_RGBx: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, data); + break; + case GST_VIDEO_FORMAT_BGRx: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_BYTE, data); + break; + case GST_VIDEO_FORMAT_xRGB: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + case GST_VIDEO_FORMAT_xBGR: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + case GST_VIDEO_FORMAT_YUY2: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); + break; + case GST_VIDEO_FORMAT_UYVY: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); + break; + case GST_VIDEO_FORMAT_AYUV: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + default: + g_assert_not_reached (); + } + +#ifdef GL_POST_COLOR_MATRIX_RED_BIAS + if (type == GST_VIDEO_FORMAT_AYUV) { + const double matrix[16] = { + 1, 1, 1, 0, + 0, -0.344 * 1, 1.770 * 1, 0, + 1.403 * 1, -0.714 * 1, 0, 0, + 0, 0, 0, 1 + }; + glMatrixMode (GL_COLOR); + glLoadMatrixd (matrix); + glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2); + glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2); + glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2); + } +#endif +#endif + + glColor4f (1, 0, 1, 1); + glBegin (GL_QUADS); + + glNormal3f (0, 0, -1); + + glTexCoord2f (width, 0); + glVertex3f (1.0, 1.0, 0); + glTexCoord2f (0, 0); + glVertex3f (-1.0, 1.0, 0); + glTexCoord2f (0, height); + glVertex3f (-1.0, -1.0, 0); + glTexCoord2f (width, height); + glVertex3f (1.0, -1.0, 0); + glEnd (); + glDeleteTextures (1, &texture); +#else + g_assert_not_reached (); +#endif +} + +static void +draw_pow2_texture (GstGLDisplay * display, GstVideoFormat type, + void *data, int width, int height) +{ + int pow2_width; + int pow2_height; + double x, y; + GLuint texture; + + GST_DEBUG ("using power-of-2 texture"); + + for (pow2_height = 64; + pow2_height < height && pow2_height > 0; pow2_height <<= 1); + for (pow2_width = 64; pow2_width < width && pow2_width > 0; pow2_width <<= 1); + + glEnable (GL_TEXTURE_2D); + glGenTextures (1, &texture); + glBindTexture (GL_TEXTURE_2D, texture); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + switch (type) { + case GST_VIDEO_FORMAT_RGBx: + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, data); + break; + case GST_VIDEO_FORMAT_BGRx: + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_BYTE, data); + break; + case GST_VIDEO_FORMAT_xRGB: + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + case GST_VIDEO_FORMAT_xBGR: + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + case GST_VIDEO_FORMAT_YUY2: + glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); + break; + case GST_VIDEO_FORMAT_UYVY: + glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); + break; + case GST_VIDEO_FORMAT_AYUV: + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); + break; + default: + g_assert_not_reached (); + } + +#ifdef GL_POST_COLOR_MATRIX_RED_BIAS + if (type == GST_VIDEO_FORMAT_AYUV) { + const double matrix[16] = { + 1, 1, 1, 0, + 0, -0.344 * 1, 1.770 * 1, 0, + 1.403 * 1, -0.714 * 1, 0, 0, + 0, 0, 0, 1 + }; + glMatrixMode (GL_COLOR); + glLoadMatrixd (matrix); + glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2); + glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2); + glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2); + } +#endif + + glColor4f (1, 0, 1, 1); + glBegin (GL_QUADS); + + glNormal3f (0, 0, -1); + + x = (double) width / pow2_width; + y = (double) height / pow2_height; + + glTexCoord2f (x, 0); + glVertex3f (1.0, 1.0, 0); + glTexCoord2f (0, 0); + glVertex3f (-1.0, 1.0, 0); + glTexCoord2f (0, y); + glVertex3f (-1.0, -1.0, 0); + glTexCoord2f (x, y); + glVertex3f (1.0, -1.0, 0); + glEnd (); + glDeleteTextures (1, &texture); +} + +void +gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type, + void *data, int width, int height) +{ + g_return_if_fail (data != NULL); + g_return_if_fail (width > 0); + g_return_if_fail (height > 0); + + gst_gl_display_lock (display); + +#if 0 + /* Doesn't work */ + { + int64_t ust = 1234; + int64_t mst = 1234; + int64_t sbc = 1234; + gboolean ret; + + ret = glXGetSyncValuesOML (display->display, display->window, + &ust, &mst, &sbc); + GST_DEBUG ("sync values %d %lld %lld %lld", ret, ust, mst, sbc); + } +#endif + +#if 0 + /* Does work, but is not relevant */ + { + int32_t num = 1234; + int32_t den = 1234; + gboolean ret; + + ret = glXGetMscRateOML (display->display, display->window, &num, &den); + GST_DEBUG ("rate %d %d %d", ret, num, den); + } +#endif + + gst_gl_display_update_attributes (display); + + //glXSwapIntervalSGI (1); + glViewport (0, 0, display->win_width, display->win_height); + + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glDisable (GL_CULL_FACE); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + glColor4f (1, 1, 1, 1); + + if (display->have_texture_rectangle) { + draw_rect_texture (display, type, data, width, height); + } else { + draw_pow2_texture (display, type, data, width, height); + } + + glXSwapBuffers (display->display, display->window); +#if 0 + /* Doesn't work */ + { + ret = glXSwapBuffersMscOML (display->display, display->window, 0, 1, 0); + if (ret == 0) { + GST_DEBUG ("glXSwapBuffersMscOML failed"); + } + } +#endif + + gst_gl_display_unlock (display); +} + +void +gst_gl_display_draw_rbo (GstGLDisplay * display, GLuint rbo, + int width, int height) +{ + GLuint texture; + GLuint fbo; + + g_return_if_fail (width > 0); + g_return_if_fail (height > 0); + g_return_if_fail (rbo != None); + + gst_gl_display_lock (display); + + g_assert (display->window != None); + g_assert (display->context != NULL); + + gst_gl_display_update_attributes (display); + + glViewport (0, 0, display->win_width, display->win_height); + + glClearColor (0.3, 0.3, 0.3, 1.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glDisable (GL_CULL_FACE); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + glColor4f (1, 1, 1, 1); + + glGenFramebuffersEXT (1, &fbo); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo); + + glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rbo); + + glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); + glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); + + g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == + GL_FRAMEBUFFER_COMPLETE_EXT); + +#if 1 + { + void *buffer; + + buffer = malloc (320 * 240 * 4); + memset (buffer, random (), 320 * 240 * 4); + free (buffer); + } +#endif + + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glGenTextures (1, &texture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_RECTANGLE_ARB, texture, 0); + + glDrawBuffer (0); + glReadBuffer (0); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); + glColor4f (1, 0, 1, 1); + gst_gl_display_check_error (display, __LINE__); +//glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); + glBegin (GL_QUADS); + + glNormal3f (0, 0, -1); + + glTexCoord2f (width, 0); + glVertex3f (0.9, 0.9, 0); + glTexCoord2f (0, 0); + glVertex3f (-0.9, 0.9, 0); + glTexCoord2f (0, height); + glVertex3f (-0.9, -0.9, 0); + glTexCoord2f (width, height); + glVertex3f (0.9, -0.9, 0); + glEnd (); + gst_gl_display_check_error (display, __LINE__); + glDeleteTextures (1, &texture); + + glDeleteFramebuffersEXT (1, &fbo); + gst_gl_display_check_error (display, __LINE__); + + glXSwapBuffers (display->display, display->window); + + gst_gl_display_unlock (display); +} + +void +gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture, + int width, int height) +{ + g_return_if_fail (width > 0); + g_return_if_fail (height > 0); + g_return_if_fail (texture != None); + + gst_gl_display_lock (display); + + g_assert (display->window != None); + g_assert (display->context != NULL); + + gst_gl_display_update_attributes (display); + + glViewport (0, 0, display->win_width, display->win_height); + + glClearColor (0.3, 0.3, 0.3, 1.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glDisable (GL_CULL_FACE); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + glColor4f (1, 1, 1, 1); + + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glColor4f (1, 0, 1, 1); + gst_gl_display_check_error (display, __LINE__); + glBegin (GL_QUADS); + + glNormal3f (0, 0, -1); + + glTexCoord2f (width, 0); + glVertex3f (0.9, 0.9, 0); + glTexCoord2f (0, 0); + glVertex3f (-0.9, 0.9, 0); + glTexCoord2f (0, height); + glVertex3f (-0.9, -0.9, 0); + glTexCoord2f (width, height); + glVertex3f (0.9, -0.9, 0); + glEnd (); + gst_gl_display_check_error (display, __LINE__); + + glXSwapBuffers (display->display, display->window); + + gst_gl_display_unlock (display); +} diff --git a/sys/glsink/gstgldisplay.h b/sys/glsink/gstgldisplay.h new file mode 100644 index 00000000..677c569f --- /dev/null +++ b/sys/glsink/gstgldisplay.h @@ -0,0 +1,84 @@ + +#ifndef __GST_GL_H__ +#define __GST_GL_H__ + +#include +#include +#include +#include + +typedef struct _GstGLDisplay GstGLDisplay; +typedef struct _GstGLDisplayClass GstGLDisplayClass; + +#define GST_TYPE_GL_DISPLAY \ + (gst_gl_display_get_type()) +#define GST_GL_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY,GstGLDisplay)) +#define GST_GL_DISPLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_DISPLAY,GstGLDisplayClass)) +#define GST_IS_GL_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY)) +#define GST_IS_GL_DISPLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_DISPLAY)) + + +struct _GstGLDisplay { + GObject object; + + Display *display; + GC gc; + XVisualInfo *visinfo; + GLXContext context; + GMutex *lock; + + Screen *screen; + int screen_num; + Visual *visual; + Window root; + guint32 white; + guint32 black; + int depth; + + int max_texture_size; + + gboolean have_ycbcr_texture; + gboolean have_texture_rectangle; + gboolean have_color_matrix; + + Window window; + Window assigned_window; + + int win_width; + int win_height; + +}; + +struct _GstGLDisplayClass { + GObjectClass object_class; +}; + +GType gst_gl_display_get_type (void); + + +GstGLDisplay *gst_gl_display_new (void); +gboolean gst_gl_display_connect (GstGLDisplay *display, + const char *display_name); +gboolean gst_gl_display_can_handle_type (GstGLDisplay *display, + GstVideoFormat type); +void gst_gl_display_lock (GstGLDisplay *display); +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); +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); + +#endif + -- cgit v1.2.1