[606/906] determine the GL platform to use at runtime

- Make GstGLWindow subclassablerather than specified at compile time.
- Add GstGLWindowX11 for x11 windows and two subclasses, GstGLWindowX11GLX
  and GstGLWindwX11EGL for GLX and EGL repectively. (win32 and cocoa
  ports to come)
- Also cleanup GL library detection in configure.ac
This commit is contained in:
Matthew Waters 2012-11-13 22:12:20 +11:00 committed by Tim-Philipp Müller
parent 9dd6570ca9
commit 538643e3c0
12 changed files with 1681 additions and 1605 deletions

View file

@ -2,8 +2,6 @@
lib_LTLIBRARIES = libgstgl-@GST_API_VERSION@.la lib_LTLIBRARIES = libgstgl-@GST_API_VERSION@.la
EXTRA_DIST = \ EXTRA_DIST = \
gstglwindow_x11.c \
gstglwindow_x11ES2.c \
gstglwindow_win32.c \ gstglwindow_win32.c \
gstglwindow_winCE.c \ gstglwindow_winCE.c \
gstglwindow_cocoa.m gstglwindow_cocoa.m
@ -17,19 +15,25 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \
gstglshader.c \ gstglshader.c \
gstglshadervariables.c \ gstglshadervariables.c \
gstgldownload.c \ gstgldownload.c \
gstglupload.c gstglupload.c \
gstglwindow.c
if GL_BACKEND_WIN32 #SUBDIRS =
if HAVE_WINDOW_WIN32
libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_win32.c libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_win32.c
endif endif
if GL_BACKEND_COCOA if HAVE_WINDOW_COCOA
libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_cocoa.m libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_cocoa.m
endif endif
if GL_BACKEND_X11 if HAVE_WINDOW_X11
libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_x11.c libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_x11.c
if USE_GLX
libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_x11_glx.c
endif endif
if GL_BACKEND_X11ES2 if USE_EGL
libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_x11ES2.c libgstgl_@GST_API_VERSION@_la_SOURCES += gstglwindow_x11_egl.c
endif
#SUBDIRS += x11
endif endif
libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl
@ -42,7 +46,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \
gstglfilter.h \ gstglfilter.h \
gstglmixer.h \ gstglmixer.h \
gstglmixerpad.h \ gstglmixerpad.h \
gstglshadervariables.h \ gstglshadervariables.h \
gstglshader.h \ gstglshader.h \
gstgldownload.h \ gstgldownload.h \
gstglupload.h gstglupload.h
@ -62,7 +66,7 @@ libgstgl_@GST_API_VERSION@_la_OBJCFLAGS = \
libgstgl_@GST_API_VERSION@_la_LDFLAGS = \ libgstgl_@GST_API_VERSION@_la_LDFLAGS = \
$(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS) $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
if GL_BACKEND_COCOA if HAVE_WINDOW_COCOA
libgstgl_@GST_API_VERSION@_la_LIBTOOLFLAGS = --tag=OBJC libgstgl_@GST_API_VERSION@_la_LIBTOOLFLAGS = --tag=OBJC
else else
libgstgl_@GST_API_VERSION@_la_LIBTOOLFLAGS = --tag=CC libgstgl_@GST_API_VERSION@_la_LIBTOOLFLAGS = --tag=CC

View file

@ -93,8 +93,6 @@ static void
gst_gl_display_class_init (GstGLDisplayClass * klass) gst_gl_display_class_init (GstGLDisplayClass * klass)
{ {
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize; G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
gst_gl_window_init_platform ();
} }
@ -217,7 +215,7 @@ gst_gl_display_finalize (GObject * object)
GST_INFO ("send quit gl window loop"); GST_INFO ("send quit gl window loop");
gst_gl_window_quit_loop (display->gl_window, gst_gl_window_quit (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_thread_destroy_context), display); GST_GL_WINDOW_CB (gst_gl_display_thread_destroy_context), display);
GST_INFO ("quit sent to gl window loop"); GST_INFO ("quit sent to gl window loop");
@ -303,7 +301,9 @@ gst_gl_display_thread_create_context (GstGLDisplay * display)
GLenum err = GLEW_OK; GLenum err = GLEW_OK;
gst_gl_display_lock (display); gst_gl_display_lock (display);
display->gl_window = gst_gl_window_new (display->external_gl_context); display->gl_window =
gst_gl_window_new (GST_GL_RENDERER_API_OPENGL,
display->external_gl_context);
if (!display->gl_window) { if (!display->gl_window) {
gst_gl_display_set_error (display, "Failed to create gl window"); gst_gl_display_set_error (display, "Failed to create gl window");
@ -385,7 +385,7 @@ gst_gl_display_thread_create_context (GstGLDisplay * display)
//setup callbacks //setup callbacks
gst_gl_window_set_resize_callback (display->gl_window, gst_gl_window_set_resize_callback (display->gl_window,
GST_GL_WINDOW_CB2 (gst_gl_display_on_resize), display); GST_GL_WINDOW_RESIZE_CB (gst_gl_display_on_resize), display);
gst_gl_window_set_draw_callback (display->gl_window, gst_gl_window_set_draw_callback (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_on_draw), display); GST_GL_WINDOW_CB (gst_gl_display_on_draw), display);
gst_gl_window_set_close_callback (display->gl_window, gst_gl_window_set_close_callback (display->gl_window,
@ -395,7 +395,7 @@ gst_gl_display_thread_create_context (GstGLDisplay * display)
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
gst_gl_window_run_loop (display->gl_window); gst_gl_window_run (display->gl_window);
GST_INFO ("loop exited\n"); GST_INFO ("loop exited\n");
@ -1302,10 +1302,10 @@ gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
/* Called by the glimagesink */ /* Called by the glimagesink */
void void
gst_gl_display_set_window_id (GstGLDisplay * display, gulong window_id) gst_gl_display_set_window_id (GstGLDisplay * display, guintptr window_id)
{ {
gst_gl_display_lock (display); gst_gl_display_lock (display);
gst_gl_window_set_external_window_id (display->gl_window, window_id); gst_gl_window_set_window_handle (display->gl_window, window_id);
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
} }
@ -1342,8 +1342,7 @@ gst_gl_display_get_internal_gl_context (GstGLDisplay * display)
{ {
gulong external_gl_context = 0; gulong external_gl_context = 0;
gst_gl_display_lock (display); gst_gl_display_lock (display);
external_gl_context = external_gl_context = gst_gl_window_get_gl_context (display->gl_window);
gst_gl_window_get_internal_gl_context (display->gl_window);
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
return external_gl_context; return external_gl_context;
} }
@ -1353,7 +1352,7 @@ gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate)
{ {
if (!activate) if (!activate)
gst_gl_display_lock (display); gst_gl_display_lock (display);
gst_gl_window_activate_gl_context (display->gl_window, activate); gst_gl_window_activate (display->gl_window, activate);
if (activate) if (activate)
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
} }

View file

@ -0,0 +1,103 @@
/*
* GStreamer
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_GL_RENDERER_H__
#define __GST_GL_RENDERER_H__
/* OpenGL 2.0 for Embedded Systems */
#ifdef GST_GL_RENDERER_GLES2
# undef UNICODE
# include <EGL/egl.h>
# define UNICODE
# include <GLES2/gl2.h>
# include "gstgles2.h"
/* OpenGL for usual systems */
#endif
#if GST_GL_RENDERER_GL || GST_GL_RENDERER_GL3
# if __APPLE__
# include <GL/glew.h>
# include <OpenGL/OpenGL.h>
# include <OpenGL/gl.h>
# else
# if HAVE_GLEW
# include <GL/glew.h>
# endif
# include <GL/gl.h>
# endif
#endif
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_GL_TYPE_RENDERER (gst_gl_renderer_get_type())
#define GST_GL_RENDERER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_RENDERER, GstGLRenderer))
#define GST_GL_RENDERER_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_RENDERER, GstGLRendererClass))
#define GST_GL_IS_RENDERER(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_RENDERER))
#define GST_GL_IS_RENDERER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_RENDERER))
#define GST_GL_RENDERER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_RENDERER, GstGLRendererClass))
#define GST_GL_RENDERER_ERROR (gst_gl_renderer_error_quark ())
typedef struct _GstGLRenderer GstGLRenderer;
typedef struct _GstGLRendererPrivate GstGLRendererPrivate;
typedef struct _GstGLRendererClass GstGLRendererClass;
typedef enum {
GST_GL_RENDERER_API_OPENGL = 1,
GST_GL_RENDERER_API_OPENGL3 = 2,
GST_GL_RENDERER_API_GLES = 40,
GST_GL_RENDERER_API_GLES2 = 41,
GST_GL_RENDERER_API_GLES3 = 42,
GST_GL_RENDERER_API_LAST = 255
} GstGLRendererAPI;
struct _GstGLRenderer {
/*< private >*/
GObject parent;
/*< public >*/
GstGLRendererAPI renderer_api;
/*< private >*/
gpointer _reserved[GST_PADDING_LARGE];
};
struct _GstGLRendererClass {
/*< private >*/
GObjectClass parent_class;
/*< private >*/
gpointer _reserved[GST_PADDING_LARGE];
};
/* methods */
GQuark gst_gl_renderer_error_quark (void);
GType gst_gl_renderer_get_type (void);
GstGLRenderer * gst_gl_renderer_new ();
GstGLRendererAPI gst_gl_renderer_get_renderer_api (GstGLRenderer *renderer);
G_END_DECLS
#endif /* __GST_GL_WINDOW_H__ */

View file

@ -0,0 +1,303 @@
/*
* GStreamer
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "gstglwindow.h"
#ifdef HAVE_WINDOW_X11
#include "gstglwindow_x11.h"
#endif
#ifdef HAVE_WINDOW_WIN32
#include "win32/gstglwindow_win32.h"
#endif
#ifdef HAVE_WINDOW_COCOA
#include "osx/gstglwindow_cocoa.h"
#endif
#define GST_CAT_DEFAULT gst_gl_window_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_gl_window_debug, "glwindow", 0, "glwindow element");
#define gst_gl_window_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT,
DEBUG_INIT);
static void
gst_gl_window_init (GstGLWindow * window)
{
g_mutex_init (&window->lock);
window->need_lock = TRUE;
}
static void
gst_gl_window_class_init (GstGLWindowClass * klass)
{
}
GstGLWindow *
gst_gl_window_new (GstGLRendererAPI render_api, guintptr external_gl_context)
{
GstGLWindow *window = NULL;
const gchar *user_choice;
user_choice = g_getenv ("GST_GL_WINDOW");
#ifdef HAVE_WINDOW_X11
if (!window && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
window =
GST_GL_WINDOW (gst_gl_window_x11_new (render_api, external_gl_context));
#endif
#ifdef HAVE_WINDOW_WIN32
if (!window && (!user_choice || g_strstr_len (user_choice, 5, "win32")))
window =
GST_GL_WINDOW (gst_gl_window_win32_new (render_api,
external_gl_context));
#endif
#ifdef HAVE_WINDOW_COCOA
if (!window && (!user_choice || g_strstr_len (user_choice, 5, "cocoa")))
window =
GST_GL_WINDOW (gst_gl_window_cocoa_new (render_api,
external_gl_context));
#endif
if (!window) {
GST_WARNING ("could not create a window, user choice:%s", user_choice);
/* FIXME: set and return a GError */
return NULL;
}
window->external_gl_context = external_gl_context;
return window;
}
GstGLPlatform
gst_gl_window_get_platform (GstGLWindow * window)
{
GstGLWindowClass *window_class;
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_val_if_fail (window_class->get_platform != NULL,
GST_GL_PLATFORM_UNKNOWN);
return window_class->get_platform (window);
}
guintptr
gst_gl_window_get_gl_context (GstGLWindow * window)
{
GstGLWindowClass *window_class;
guintptr result;
g_return_val_if_fail (GST_GL_IS_WINDOW (window), 0);
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_val_if_fail (window_class->get_gl_context != NULL, 0);
GST_GL_WINDOW_LOCK (window);
result = window_class->get_gl_context (window);
GST_GL_WINDOW_UNLOCK (window);
return result;
}
gboolean
gst_gl_window_activate (GstGLWindow * window, gboolean activate)
{
GstGLWindowClass *window_class;
gboolean result;
g_return_val_if_fail (GST_GL_IS_WINDOW (window), FALSE);
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_val_if_fail (window_class->activate != NULL, FALSE);
GST_GL_WINDOW_LOCK (window);
result = window_class->activate (window, activate);
GST_GL_WINDOW_UNLOCK (window);
return result;
}
void
gst_gl_window_set_window_handle (GstGLWindow * window, guintptr handle)
{
GstGLWindowClass *window_class;
g_return_if_fail (GST_GL_IS_WINDOW (window));
g_return_if_fail (handle != 0);
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_if_fail (window_class->set_window_handle != NULL);
GST_GL_WINDOW_LOCK (window);
window_class->set_window_handle (window, handle);
GST_GL_WINDOW_UNLOCK (window);
}
guintptr
gst_gl_window_get_window_handle (GstGLWindow * window)
{
GstGLWindowClass *window_class;
guintptr result;
g_return_val_if_fail (GST_GL_IS_WINDOW (window), 0);
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_val_if_fail (window_class->get_window_handle != NULL, FALSE);
GST_GL_WINDOW_LOCK (window);
result = window_class->get_window_handle (window);
GST_GL_WINDOW_UNLOCK (window);
return result;
}
void
gst_gl_window_draw_unlocked (GstGLWindow * window, guint width, guint height)
{
GstGLWindowClass *window_class;
g_return_if_fail (GST_GL_IS_WINDOW (window));
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_if_fail (window_class->draw_unlocked != NULL);
window_class->draw_unlocked (window, width, height);
}
void
gst_gl_window_draw (GstGLWindow * window, guint width, guint height)
{
GstGLWindowClass *window_class;
g_return_if_fail (GST_GL_IS_WINDOW (window));
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_if_fail (window_class->draw != NULL);
GST_GL_WINDOW_LOCK (window);
window_class->draw (window, width, height);
GST_GL_WINDOW_UNLOCK (window);
}
void
gst_gl_window_run (GstGLWindow * window)
{
GstGLWindowClass *window_class;
g_return_if_fail (GST_GL_IS_WINDOW (window));
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_if_fail (window_class->run != NULL);
GST_GL_WINDOW_LOCK (window);
window_class->run (window);
GST_GL_WINDOW_UNLOCK (window);
}
void
gst_gl_window_quit (GstGLWindow * window, GstGLWindowCB callback, gpointer data)
{
GstGLWindowClass *window_class;
g_return_if_fail (GST_GL_IS_WINDOW (window));
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_if_fail (window_class->quit != NULL);
GST_GL_WINDOW_LOCK (window);
window->close = callback;
window->close_data = data;
window_class->quit (window, callback, data);
GST_GL_WINDOW_UNLOCK (window);
}
void
gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{
GstGLWindowClass *window_class;
g_return_if_fail (GST_GL_IS_WINDOW (window));
g_return_if_fail (callback != NULL);
window_class = GST_GL_WINDOW_GET_CLASS (window);
g_return_if_fail (window_class->quit != NULL);
GST_GL_WINDOW_LOCK (window);
window_class->send_message (window, callback, data);
GST_GL_WINDOW_UNLOCK (window);
}
/**
* gst_gl_window_set_need_lock:
*
* window: a #GstGLWindow
* need_lock: whether the @window needs to lock for concurrent access
*
* This API is intended only for subclasses of #GstGLWindow in order to ensure
* correct interaction with the underlying window system.
*/
void
gst_gl_window_set_need_lock (GstGLWindow * window, gboolean need_lock)
{
g_return_if_fail (GST_GL_IS_WINDOW (window));
window->need_lock = need_lock;
}
void
gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{
g_return_if_fail (GST_GL_IS_WINDOW (window));
GST_GL_WINDOW_LOCK (window);
window->draw = callback;
window->draw_data = data;
GST_GL_WINDOW_UNLOCK (window);
}
void
gst_gl_window_set_resize_callback (GstGLWindow * window,
GstGLWindowResizeCB callback, gpointer data)
{
g_return_if_fail (GST_GL_IS_WINDOW (window));
GST_GL_WINDOW_LOCK (window);
window->resize = callback;
window->resize_data = data;
GST_GL_WINDOW_UNLOCK (window);
}
void
gst_gl_window_set_close_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)
{
g_return_if_fail (GST_GL_IS_WINDOW (window));
GST_GL_WINDOW_LOCK (window);
window->close = callback;
window->close_data = data;
GST_GL_WINDOW_UNLOCK (window);
}

View file

@ -21,25 +21,6 @@
#ifndef __GST_GL_WINDOW_H__ #ifndef __GST_GL_WINDOW_H__
#define __GST_GL_WINDOW_H__ #define __GST_GL_WINDOW_H__
/* OpenGL 2.0 for Embedded Systems */
#ifdef OPENGL_ES2
#undef UNICODE
#include <EGL/egl.h>
#define UNICODE
#include <GLES2/gl2.h>
#include "gstgles2.h"
/* OpenGL for usual systems */
#else
#if __APPLE__
#include <GL/glew.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#else
#include <GL/glew.h>
#include <GL/gl.h>
#endif
#endif
#include <gst/gst.h> #include <gst/gst.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -51,13 +32,38 @@ G_BEGIN_DECLS
#define GST_GL_IS_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW)) #define GST_GL_IS_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW))
#define GST_GL_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW, GstGLWindowClass)) #define GST_GL_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW, GstGLWindowClass))
#define GST_GL_WINDOW_LOCK(w) \
do { \
if (GST_GL_WINDOW(w)->need_lock) \
g_mutex_lock (&GST_GL_WINDOW(w)->lock); \
} while (0)
#define GST_GL_WINDOW_UNLOCK(w) \
do { \
if (GST_GL_WINDOW(w)->need_lock) \
g_mutex_unlock (&GST_GL_WINDOW(w)->lock); \
} while (0)
#define GST_GL_WINDOW_GET_LOCK(w) (&GST_GL_WINDOW(w)->lock)
#define GST_GL_WINDOW_ERROR (gst_gl_window_error_quark ()) #define GST_GL_WINDOW_ERROR (gst_gl_window_error_quark ())
typedef void (* GstGLWindowCB) ( gpointer ); typedef void (*GstGLWindowCB) (gpointer data);
typedef void (* GstGLWindowCB2) ( gpointer, gint, gint ); typedef void (*GstGLWindowResizeCB) (gpointer data, guint width, guint height);
#define GST_GL_WINDOW_CB(f) ((GstGLWindowCB) (f)) #define GST_GL_WINDOW_CB(f) ((GstGLWindowCB) (f))
#define GST_GL_WINDOW_CB2(f) ((GstGLWindowCB2) (f)) #define GST_GL_WINDOW_RESIZE_CB(f) ((GstGLWindowResizeCB) (f))
typedef enum
{
GST_GL_PLATFORM_UNKNOWN = 0,
GST_GL_PLATFORM_EGL,
GST_GL_PLATFORM_GLX,
GST_GL_PLATFORM_WGL,
GST_GL_PLATFORM_CGL,
GST_GL_PLATFORM_LAST = 255
} GstGLPlatform;
typedef struct _GstGLWindow GstGLWindow; typedef struct _GstGLWindow GstGLWindow;
typedef struct _GstGLWindowPrivate GstGLWindowPrivate; typedef struct _GstGLWindowPrivate GstGLWindowPrivate;
@ -66,38 +72,66 @@ typedef struct _GstGLWindowClass GstGLWindowClass;
struct _GstGLWindow { struct _GstGLWindow {
/*< private >*/ /*< private >*/
GObject parent; GObject parent;
GstGLWindowPrivate *priv;
/*< public >*/
GMutex lock;
gboolean need_lock;
guintptr external_gl_context;
GstGLWindowCB draw;
gpointer draw_data;
GstGLWindowCB close;
gpointer close_data;
GstGLWindowResizeCB resize;
gpointer resize_data;
/*< private >*/
gpointer _reserved[GST_PADDING];
}; };
struct _GstGLWindowClass { struct _GstGLWindowClass {
/*< private >*/ /*< private >*/
GObjectClass parent_class; GObjectClass parent_class;
guintptr (*get_gl_context) (GstGLWindow *window);
gboolean (*activate) (GstGLWindow *window, gboolean activate);
void (*set_window_handle) (GstGLWindow *window, guintptr id);
guintptr (*get_window_handle) (GstGLWindow *window);
void (*draw_unlocked) (GstGLWindow *window, guint width, guint height);
void (*draw) (GstGLWindow *window, guint width, guint height);
void (*run) (GstGLWindow *window);
void (*quit) (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void (*send_message) (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
GstGLPlatform (*get_platform) (GstGLWindow *window);
/*< private >*/
gpointer _reserved[GST_PADDING];
}; };
/* methods */ /* methods */
GQuark gst_gl_window_error_quark (void); GQuark gst_gl_window_error_quark (void);
GType gst_gl_window_get_type (void); GType gst_gl_window_get_type (void);
GstGLWindow * gst_gl_window_new (guintptr external_gl_context); GstGLWindow * gst_gl_window_new (GstGLRendererAPI render_api, guintptr external_gl_context);
guintptr gst_gl_window_get_internal_gl_context (GstGLWindow *window); void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_activate_gl_context (GstGLWindow *window, gboolean activate); void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowResizeCB callback, gpointer data);
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_set_need_lock (GstGLWindow *window, gboolean need_lock);
void gst_gl_window_set_external_window_id (GstGLWindow *window, guintptr id); guintptr gst_gl_window_get_gl_context (GstGLWindow *window);
void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data); gboolean gst_gl_window_activate (GstGLWindow *window, gboolean activate);
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback, gpointer data); void gst_gl_window_set_window_handle (GstGLWindow *window, guintptr handle);
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data); guintptr gst_gl_window_get_window_handle (GstGLWindow *window);
void gst_gl_window_draw_unlocked (GstGLWindow *window, guint width, guint height);
void gst_gl_window_draw (GstGLWindow *window, guint width, guint height);
void gst_gl_window_run (GstGLWindow *window);
void gst_gl_window_quit (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_draw_unlocked (GstGLWindow *window, gint width, gint height); GstGLPlatform gst_gl_window_get_platform (GstGLWindow *window);
void gst_gl_window_draw (GstGLWindow *window, gint width, gint height);
void gst_gl_window_run_loop (GstGLWindow *window);
void gst_gl_window_quit_loop (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
/* helper */
void gst_gl_window_init_platform ();
G_END_DECLS G_END_DECLS

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
/*
* GStreamer
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_GL_WINDOW_X11_H__
#define __GST_GL_WINDOW_X11_H__
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "gstglwindow.h"
G_BEGIN_DECLS
#define GST_GL_TYPE_WINDOW_X11 (gst_gl_window_x11_get_type())
#define GST_GL_WINDOW_X11(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_X11, GstGLWindowX11))
#define GST_GL_WINDOW_X11_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_X11, GstGLWindowX11Class))
#define GST_GL_IS_WINDOW_X11(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_X11))
#define GST_GL_IS_WINDOW_X11_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_X11))
#define GST_GL_WINDOW_X11_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_X11, GstGLWindowX11Class))
typedef struct _GstGLWindowX11 GstGLWindowX11;
typedef struct _GstGLWindowX11Private GstGLWindowX11Private;
typedef struct _GstGLWindowX11Class GstGLWindowX11Class;
struct _GstGLWindowX11 {
/*< private >*/
GstGLWindow parent;
GCond cond_send_message;
gboolean running;
gboolean visible;
gboolean allow_extra_expose_events;
/* opengl context */
gchar *display_name;
Display *device;
Screen *screen;
gint screen_num;
Visual *visual;
Window root;
gulong white;
gulong black;
gint depth;
gint device_width;
gint device_height;
gint connection;
XVisualInfo *visual_info;
Window parent_win;
/* We use a specific connection to send events */
Display *disp_send;
/* X window */
Window internal_win_id;
/*< private >*/
GstGLWindowX11Private *priv;
gpointer _reserved[GST_PADDING];
};
struct _GstGLWindowX11Class {
/*< private >*/
GstGLWindowClass parent_class;
gboolean (*choose_visual) (GstGLWindowX11 *window);
gboolean (*create_context) (GstGLWindowX11 *window, GstGLRendererAPI render_api,
guintptr external_gl_context);
void (*swap_buffers) (GstGLWindowX11 *window);
gboolean (*activate) (GstGLWindowX11 *window, gboolean activate);
void (*destroy_context) (GstGLWindowX11 *window);
guintptr (*get_gl_context) (GstGLWindowX11 *window);
/*< private >*/
gpointer _reserved[GST_PADDING_LARGE];
};
GType gst_gl_window_x11_get_type (void);
GstGLWindowX11 * gst_gl_window_x11_new (GstGLRendererAPI render_api,
guintptr external_gl_context);
gboolean gst_gl_window_x11_open_device (GstGLWindowX11 *window_x11,
GstGLRendererAPI render_api,
guintptr external_gl_context);
G_END_DECLS
#endif /* __GST_GL_WINDOW_X11_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,271 @@
/*
* GStreamer
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstglwindow_x11_egl.h"
const gchar *EGLErrorString ();
#define GST_CAT_DEFAULT gst_gl_window_x11_egl_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_x11_egl_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowX11EGL, gst_gl_window_x11_egl,
GST_GL_TYPE_WINDOW_X11, DEBUG_INIT);
static guintptr gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 *
window_x11);
static void gst_gl_window_x11_egl_swap_buffers (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11,
gboolean activate);
static gboolean gst_gl_window_x11_egl_create_context (GstGLWindowX11 *
window_x11, GstGLRendererAPI render_api, guintptr external_gl_context);
static void gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_egl_choose_visual (GstGLWindowX11 *
window_x11);
static GstGLPlatform gst_gl_window_x11_egl_get_platform (GstGLWindow * window);
static void
gst_gl_window_x11_egl_class_init (GstGLWindowX11EGLClass * klass)
{
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
GstGLWindowX11Class *window_x11_class = (GstGLWindowX11Class *) klass;
window_class->get_platform =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_get_platform);
window_x11_class->get_gl_context =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_get_gl_context);
window_x11_class->activate =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_activate);
window_x11_class->create_context =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_create_context);
window_x11_class->destroy_context =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_destroy_context);
window_x11_class->choose_visual =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_choose_visual);
window_x11_class->swap_buffers =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_egl_swap_buffers);
}
static void
gst_gl_window_x11_egl_init (GstGLWindowX11EGL * window)
{
}
/* Must be called in the gl thread */
GstGLWindowX11EGL *
gst_gl_window_x11_egl_new (GstGLRendererAPI render_api,
guintptr external_gl_context)
{
GstGLWindowX11EGL *window = g_object_new (GST_GL_TYPE_WINDOW_X11_EGL, NULL);
gst_gl_window_x11_open_device (GST_GL_WINDOW_X11 (window), render_api,
external_gl_context);
return window;
}
static GstGLPlatform
gst_gl_window_x11_egl_get_platform (GstGLWindow * window)
{
return GST_GL_PLATFORM_EGL;
}
static gboolean
gst_gl_window_x11_egl_choose_visual (GstGLWindowX11 * window_x11)
{
gint ret;
window_x11->visual_info = g_new0 (XVisualInfo, 1);
ret = XMatchVisualInfo (window_x11->device, window_x11->screen_num,
window_x11->depth, TrueColor, window_x11->visual_info);
return ret != 0;
}
static gboolean
gst_gl_window_x11_egl_create_context (GstGLWindowX11 * window_x11,
GstGLRendererAPI render_api, guintptr external_gl_context)
{
GstGLWindowX11EGL *window_egl;
EGLint config_attrib[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_DEPTH_SIZE, 16,
EGL_NONE
};
EGLint context_attrib[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLint majorVersion;
EGLint minorVersion;
EGLint numConfigs;
EGLConfig config;
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
window_egl->egl_display =
eglGetDisplay ((EGLNativeDisplayType) window_x11->device);
if (eglInitialize (window_egl->egl_display, &majorVersion, &minorVersion))
g_debug ("egl initialized: %d.%d\n", majorVersion, minorVersion);
else {
g_debug ("failed to initialize egl %ld, %s\n",
(gulong) window_egl->egl_display, EGLErrorString ());
goto failure;
}
if (eglChooseConfig (window_egl->egl_display, config_attrib, &config, 1,
&numConfigs))
g_debug ("config set: %ld, %ld\n", (gulong) config, (gulong) numConfigs);
else {
g_debug ("failed to set config %ld, %s\n", (gulong) window_egl->egl_display,
EGLErrorString ());
goto failure;
}
window_egl->egl_surface =
eglCreateWindowSurface (window_egl->egl_display, config,
(EGLNativeWindowType) window_x11->internal_win_id, NULL);
if (window_egl->egl_surface != EGL_NO_SURFACE)
g_debug ("surface created: %ld\n", (gulong) window_egl->egl_surface);
else {
g_debug ("failed to create surface %ld, %ld, %ld, %s\n",
(gulong) window_egl->egl_display, (gulong) window_egl->egl_surface,
(gulong) window_egl->egl_display, EGLErrorString ());
goto failure;
}
g_debug ("about to create gl context\n");
window_egl->egl_context =
eglCreateContext (window_egl->egl_display, config,
(EGLContext) external_gl_context, context_attrib);
if (window_egl->egl_context != EGL_NO_CONTEXT)
g_debug ("gl context created: %ld\n", (gulong) window_egl->egl_context);
else {
g_debug ("failed to create glcontext %ld, %ld, %s\n",
(gulong) window_egl->egl_context, (gulong) window_egl->egl_display,
EGLErrorString ());
goto failure;
}
return TRUE;
failure:
return FALSE;
}
static void
gst_gl_window_x11_egl_destroy_context (GstGLWindowX11 * window_x11)
{
GstGLWindowX11EGL *window_egl;
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
if (window_egl->egl_context)
eglDestroyContext (window_x11->device, window_egl->egl_context);
if (window_x11->device)
eglTerminate (window_x11->device);
}
static gboolean
gst_gl_window_x11_egl_activate (GstGLWindowX11 * window_x11, gboolean activate)
{
gboolean result;
GstGLWindowX11EGL *window_egl;
window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
if (activate)
result = eglMakeCurrent (window_egl->egl_display, window_egl->egl_surface,
window_egl->egl_surface, window_egl->egl_context);
else
result = eglMakeCurrent (window_egl->egl_display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
return result;
}
static guintptr
gst_gl_window_x11_egl_get_gl_context (GstGLWindowX11 * window_x11)
{
return (guintptr) GST_GL_WINDOW_X11_EGL (window_x11)->egl_context;
}
static void
gst_gl_window_x11_egl_swap_buffers (GstGLWindowX11 * window_x11)
{
GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window_x11);
eglSwapBuffers (window_egl->egl_display, window_egl->egl_surface);
}
const gchar *
EGLErrorString ()
{
EGLint nErr = eglGetError ();
switch (nErr) {
case EGL_SUCCESS:
return "EGL_SUCCESS";
case EGL_BAD_DISPLAY:
return "EGL_BAD_DISPLAY";
case EGL_NOT_INITIALIZED:
return "EGL_NOT_INITIALIZED";
case EGL_BAD_ACCESS:
return "EGL_BAD_ACCESS";
case EGL_BAD_ALLOC:
return "EGL_BAD_ALLOC";
case EGL_BAD_ATTRIBUTE:
return "EGL_BAD_ATTRIBUTE";
case EGL_BAD_CONFIG:
return "EGL_BAD_CONFIG";
case EGL_BAD_CONTEXT:
return "EGL_BAD_CONTEXT";
case EGL_BAD_CURRENT_SURFACE:
return "EGL_BAD_CURRENT_SURFACE";
case EGL_BAD_MATCH:
return "EGL_BAD_MATCH";
case EGL_BAD_NATIVE_PIXMAP:
return "EGL_BAD_NATIVE_PIXMAP";
case EGL_BAD_NATIVE_WINDOW:
return "EGL_BAD_NATIVE_WINDOW";
case EGL_BAD_PARAMETER:
return "EGL_BAD_PARAMETER";
case EGL_BAD_SURFACE:
return "EGL_BAD_SURFACE";
default:
return "unknown";
}
}

View file

@ -0,0 +1,66 @@
/*
* GStreamer
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_GL_WINDOW_X11_EGL_H__
#define __GST_GL_WINDOW_X11_EGL_H__
#include <EGL/egl.h>
#include "gstglwindow_x11.h"
G_BEGIN_DECLS
#define GST_GL_TYPE_WINDOW_X11_EGL (gst_gl_window_x11_egl_get_type())
#define GST_GL_WINDOW_X11_EGL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_X11_EGL, GstGLWindowX11EGL))
#define GST_GL_WINDOW_X11_EGL_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_X11_EGL, GstGLWindowX11EGLClass))
#define GST_GL_IS_WINDOW_X11_EGL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_X11_EGL))
#define GST_GL_IS_WINDOW_X11_EGL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_X11_EGL))
#define GST_GL_WINDOW_X11_EGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_X11_EGL, GstGLWindowX11EGL_Class))
typedef struct _GstGLWindowX11EGL GstGLWindowX11EGL;
typedef struct _GstGLWindowX11EGLClass GstGLWindowX11EGLClass;
struct _GstGLWindowX11EGL {
/*< private >*/
GstGLWindowX11 parent;
EGLContext egl_context;
EGLDisplay egl_display;
EGLSurface egl_surface;
gpointer _reserved[GST_PADDING];
};
struct _GstGLWindowX11EGLClass {
/*< private >*/
GstGLWindowX11Class parent_class;
/*< private >*/
gpointer _reserved[GST_PADDING];
};
GType gst_gl_window_x11_egl_get_type (void);
GstGLWindowX11EGL * gst_gl_window_x11_egl_new (GstGLRendererAPI render_api,
guintptr external_gl_context);
G_END_DECLS
#endif /* __GST_GL_WINDOW_X11_H__ */

View file

@ -0,0 +1,183 @@
/*
* GStreamer
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstglwindow_x11_glx.h"
#define GST_CAT_DEFAULT gst_gl_window_x11_glx_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_x11_glx_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowX11GLX, gst_gl_window_x11_glx,
GST_GL_TYPE_WINDOW_X11, DEBUG_INIT);
static guintptr gst_gl_window_x11_glx_get_gl_context (GstGLWindowX11 *
window_x11);
static void gst_gl_window_x11_glx_swap_buffers (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_glx_activate (GstGLWindowX11 * window_x11,
gboolean activate);
static gboolean gst_gl_window_x11_glx_create_context (GstGLWindowX11 *
window_x11, GstGLRendererAPI render_api, guintptr external_gl_context);
static void gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11);
static gboolean gst_gl_window_x11_glx_choose_visual (GstGLWindowX11 *
window_x11);
static void
gst_gl_window_x11_glx_class_init (GstGLWindowX11GLXClass * klass)
{
GstGLWindowX11Class *window_x11_class = (GstGLWindowX11Class *) klass;
window_x11_class->get_gl_context =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_get_gl_context);
window_x11_class->activate =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_activate);
window_x11_class->create_context =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_create_context);
window_x11_class->destroy_context =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_destroy_context);
window_x11_class->choose_visual =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_choose_visual);
window_x11_class->swap_buffers =
GST_DEBUG_FUNCPTR (gst_gl_window_x11_glx_swap_buffers);
}
static void
gst_gl_window_x11_glx_init (GstGLWindowX11GLX * window)
{
}
/* Must be called in the gl thread */
GstGLWindowX11GLX *
gst_gl_window_x11_glx_new (GstGLRendererAPI render_api,
guintptr external_gl_context)
{
GstGLWindowX11GLX *window = g_object_new (GST_GL_TYPE_WINDOW_X11_GLX, NULL);
gst_gl_window_x11_open_device (GST_GL_WINDOW_X11 (window), render_api,
external_gl_context);
return window;
}
static gboolean
gst_gl_window_x11_glx_create_context (GstGLWindowX11 * window_x11,
GstGLRendererAPI render_api, guintptr external_gl_context)
{
GstGLWindowX11GLX *window_glx;
window_glx = GST_GL_WINDOW_X11_GLX (window_x11);
window_glx->glx_context =
glXCreateContext (window_x11->device, window_x11->visual_info,
(GLXContext) external_gl_context, TRUE);
if (!window_glx->glx_context) {
GST_WARNING ("failed to create opengl context (glXCreateContext failed)");
goto failure;
}
GST_LOG ("gl context id: %ld", (gulong) window_glx->glx_context);
return TRUE;
failure:
return FALSE;
}
static void
gst_gl_window_x11_glx_destroy_context (GstGLWindowX11 * window_x11)
{
GstGLWindowX11GLX *window_glx;
window_glx = GST_GL_WINDOW_X11_GLX (window_x11);
glXDestroyContext (window_x11->device, window_glx->glx_context);
window_glx->glx_context = 0;
}
static gboolean
gst_gl_window_x11_glx_choose_visual (GstGLWindowX11 * window_x11)
{
gint error_base;
gint event_base;
gint attrib[] = {
GLX_RGBA,
GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
GLX_DEPTH_SIZE, 16,
GLX_DOUBLEBUFFER,
None
};
if (!glXQueryExtension (window_x11->device, &error_base, &event_base)) {
GST_WARNING ("No GLX extension");
goto failure;
}
window_x11->visual_info = glXChooseVisual (window_x11->device,
window_x11->screen_num, attrib);
if (!window_x11->visual_info) {
GST_WARNING ("glx visual is null (bad attributes)");
goto failure;
}
return TRUE;
failure:
return FALSE;
}
static void
gst_gl_window_x11_glx_swap_buffers (GstGLWindowX11 * window_x11)
{
glXSwapBuffers (window_x11->device, window_x11->internal_win_id);
}
static guintptr
gst_gl_window_x11_glx_get_gl_context (GstGLWindowX11 * window_x11)
{
return (guintptr) GST_GL_WINDOW_X11_GLX (window_x11)->glx_context;
}
static gboolean
gst_gl_window_x11_glx_activate (GstGLWindowX11 * window_x11, gboolean activate)
{
gboolean result;
if (activate) {
result = glXMakeCurrent (window_x11->device, window_x11->internal_win_id,
GST_GL_WINDOW_X11_GLX (window_x11)->glx_context);
} else {
result = glXMakeCurrent (window_x11->device, None, NULL);
}
return result;
}

View file

@ -0,0 +1,64 @@
/*
* GStreamer
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_GL_WINDOW_X11_GLX_H__
#define __GST_GL_WINDOW_X11_GLX_H__
#include <GL/glx.h>
#include "gstglwindow_x11.h"
G_BEGIN_DECLS
#define GST_GL_TYPE_WINDOW_X11_GLX (gst_gl_window_x11_glx_get_type())
#define GST_GL_WINDOW_X11_GLX(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLX))
#define GST_GL_WINDOW_X11_GLX_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLXClass))
#define GST_GL_IS_WINDOW_X11_GLX(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_X11_GLX))
#define GST_GL_IS_WINDOW_X11_GLX_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_X11_GLX))
#define GST_GL_WINDOW_X11_GLX_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_X11_GLX, GstGLWindowX11GLX_Class))
typedef struct _GstGLWindowX11GLX GstGLWindowX11GLX;
typedef struct _GstGLWindowX11GLXClass GstGLWindowX11GLXClass;
struct _GstGLWindowX11GLX {
/*< private >*/
GstGLWindowX11 parent;
GLXContext glx_context;
gpointer _reserved[GST_PADDING];
};
struct _GstGLWindowX11GLXClass {
/*< private >*/
GstGLWindowX11Class parent_class;
/*< private >*/
gpointer _reserved[GST_PADDING];
};
GType gst_gl_window_x11_glx_get_type (void);
GstGLWindowX11GLX * gst_gl_window_x11_glx_new (GstGLRendererAPI render_api,
guintptr external_gl_context);
G_END_DECLS
#endif /* __GST_GL_WINDOW_X11_H__ */