[891/906] context: add support for wrapping external contexts

This commit is contained in:
Matthew Waters 2014-02-11 08:57:29 +11:00
parent 0d1d42b205
commit 3ad466945e
7 changed files with 326 additions and 60 deletions

View file

@ -33,6 +33,7 @@ static void gst_gl_context_cocoa_destroy_context (GstGLContext *context);
static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_cocoa_get_gl_platform (GstGLContext * context);
#define GST_GL_CONTEXT_COCOA_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_COCOA, GstGLContextCocoaPrivate))
@ -85,6 +86,8 @@ gst_gl_context_cocoa_class_init (GstGLContextCocoaClass * klass)
context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_activate);
context_class->get_gl_api =
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_api);
context_class->get_gl_platform =
GST_DEBUG_FUNCPTR (gst_gl_context_cocoa_get_gl_platform);
#ifndef GNUSTEP
pool = [[NSAutoreleasePool alloc] init];
@ -255,3 +258,9 @@ gst_gl_context_cocoa_get_gl_api (GstGLContext * context)
{
return GST_GL_API_OPENGL;
}
static GstGLPlatform
gst_gl_context_cocoa_get_gl_platform (GstGLContext * context)
{
return GST_GL_API_COCOA;
}

View file

@ -48,6 +48,8 @@ static gboolean gst_gl_context_egl_activate (GstGLContext * context,
static void gst_gl_context_egl_swap_buffers (GstGLContext * context);
static guintptr gst_gl_context_egl_get_gl_context (GstGLContext * context);
static GstGLAPI gst_gl_context_egl_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_egl_get_gl_platform (GstGLContext *
context);
static gpointer gst_gl_context_egl_get_proc_address (GstGLContext * context,
const gchar * name);
@ -71,6 +73,8 @@ gst_gl_context_egl_class_init (GstGLContextEGLClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_context_egl_swap_buffers);
context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_api);
context_class->get_gl_platform =
GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_platform);
context_class->get_proc_address =
GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_proc_address);
}
@ -213,12 +217,14 @@ gst_gl_context_egl_create_context (GstGLContext * context,
const gchar *egl_exts;
gboolean need_surface = TRUE;
guintptr external_gl_context = 0;
guintptr native_display;
GstGLDisplay *display;
egl = GST_GL_CONTEXT_EGL (context);
window = gst_gl_context_get_window (context);
if (other_context) {
if (!GST_GL_IS_CONTEXT_EGL (other_context)) {
if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_EGL) {
g_set_error (error, GST_GL_CONTEXT_ERROR,
GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
"Cannot share context with non-EGL context");
@ -462,6 +468,12 @@ gst_gl_context_egl_get_gl_api (GstGLContext * context)
return GST_GL_CONTEXT_EGL (context)->gl_api;
}
static GstGLPlatform
gst_gl_context_egl_get_gl_platform (GstGLContext * context)
{
return GST_GL_PLATFORM_EGL;
}
static gpointer
gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name)
{

View file

@ -95,6 +95,31 @@ struct _GstGLContextPrivate
GError **error;
};
typedef struct
{
GstGLContext parent;
guintptr handle;
GstGLPlatform platform;
GstGLAPI available_apis;
} GstGLWrappedContext;
typedef struct
{
GstGLContextClass parent;
} GstGLWrappedContextClass;
#define GST_GL_TYPE_WRAPPED_CONTEXT (gst_gl_wrapped_context_get_type())
GType gst_gl_wrapped_context_get_type (void);
G_DEFINE_TYPE (GstGLWrappedContext, gst_gl_wrapped_context,
GST_GL_TYPE_CONTEXT);
#define GST_GL_WRAPPED_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WRAPPED_CONTEXT, GstGLWrappedContext))
#define GST_GL_WRAPPED_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT, GstGLContextClass))
#define GST_GL_IS_WRAPPED_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WRAPPED_CONTEXT))
#define GST_GL_IS_WRAPPED_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WRAPPED_CONTEXT))
#define GST_GL_WRAPPED_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WRAPPED_CONTEXT, GstGLWrappedContextClass))
GQuark
gst_gl_context_error_quark (void)
{
@ -142,6 +167,18 @@ gst_gl_context_class_init (GstGLContextClass * klass)
G_OBJECT_CLASS (klass)->finalize = gst_gl_context_finalize;
}
static void
_init_debug (void)
{
static volatile gsize _init = 0;
if (g_once_init_enter (&_init)) {
GST_DEBUG_CATEGORY_INIT (gst_gl_context_debug, "glcontext", 0,
"glcontext element");
g_once_init_leave (&_init, 1);
}
}
/**
* gst_gl_context_new:
* @display: a #GstGLDisplay
@ -155,13 +192,8 @@ gst_gl_context_new (GstGLDisplay * display)
{
GstGLContext *context = NULL;
const gchar *user_choice;
static volatile gsize _init = 0;
if (g_once_init_enter (&_init)) {
GST_DEBUG_CATEGORY_INIT (gst_gl_context_debug, "glcontext", 0,
"glcontext element");
g_once_init_leave (&_init, 1);
}
_init_debug ();
user_choice = g_getenv ("GST_GL_PLATFORM");
GST_INFO ("creating a context, user choice:%s", user_choice);
@ -196,35 +228,77 @@ gst_gl_context_new (GstGLDisplay * display)
return context;
}
/**
* gst_gl_context_new_wrapped:
* @display: a #GstGLDisplay
* @handle: the OpenGL context to wrap
* @context_type: a #GstGLPlatform specifying the type of context in @handle
* @available_apis: a #GstGLAPI containing the available OpenGL apis in @handle
*
* Wraps an existing OpenGL context into a #GstGLContext.
*
* Returns: a #GstGLContext wrapping @handle
*/
GstGLContext *
gst_gl_context_new_wrapped (GstGLDisplay * display, guintptr handle,
GstGLPlatform context_type, GstGLAPI available_apis)
{
GstGLContext *context;
GstGLWrappedContext *context_wrap = NULL;
_init_debug ();
context_wrap = g_object_new (GST_GL_TYPE_WRAPPED_CONTEXT, NULL);
if (!context_wrap) {
/* subclass returned a NULL context */
GST_ERROR ("Could not wrap existing context");
return NULL;
}
context = (GstGLContext *) context_wrap;
context->priv->display = gst_object_ref (display);
context_wrap->handle = handle;
context_wrap->platform = context_type;
context_wrap->available_apis = available_apis;
return context;
}
static void
gst_gl_context_finalize (GObject * object)
{
GstGLContext *context = GST_GL_CONTEXT (object);
gst_gl_window_set_resize_callback (context->window, NULL, NULL, NULL);
gst_gl_window_set_draw_callback (context->window, NULL, NULL, NULL);
if (context->window) {
gst_gl_window_set_resize_callback (context->window, NULL, NULL, NULL);
gst_gl_window_set_draw_callback (context->window, NULL, NULL, NULL);
if (context->priv->alive) {
g_mutex_lock (&context->priv->render_lock);
GST_INFO ("send quit gl window loop");
gst_gl_window_quit (context->window);
while (context->priv->alive) {
g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
if (context->priv->alive) {
g_mutex_lock (&context->priv->render_lock);
GST_INFO ("send quit gl window loop");
gst_gl_window_quit (context->window);
while (context->priv->alive) {
g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
}
g_mutex_unlock (&context->priv->render_lock);
}
g_mutex_unlock (&context->priv->render_lock);
gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
if (context->priv->gl_thread) {
gpointer ret = g_thread_join (context->priv->gl_thread);
GST_INFO ("gl thread joined");
if (ret != NULL)
GST_ERROR ("gl thread returned a non-null pointer");
context->priv->gl_thread = NULL;
}
gst_object_unref (context->window);
}
gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
if (context->priv->gl_thread) {
gpointer ret = g_thread_join (context->priv->gl_thread);
GST_INFO ("gl thread joined");
if (ret != NULL)
GST_ERROR ("gl thread returned a non-null pointer");
context->priv->gl_thread = NULL;
}
gst_object_unref (context->window);
gst_object_unref (context->priv->display);
if (context->gl_vtable) {
@ -310,6 +384,7 @@ gst_gl_context_get_proc_address (GstGLContext * context, const gchar * name)
GstGLContextClass *context_class;
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
g_return_val_if_fail (!GST_GL_IS_WRAPPED_CONTEXT (context), NULL);
context_class = GST_GL_CONTEXT_GET_CLASS (context);
g_return_val_if_fail (context_class->get_proc_address != NULL, NULL);
@ -383,6 +458,8 @@ gst_gl_context_default_get_proc_address (GstGLContext * context,
gboolean
gst_gl_context_set_window (GstGLContext * context, GstGLWindow * window)
{
g_return_val_if_fail (!GST_GL_IS_WRAPPED_CONTEXT (context), NULL);
/* we can't change the window while we are running */
if (context->priv->alive)
return FALSE;
@ -413,6 +490,9 @@ gst_gl_context_get_window (GstGLContext * context)
{
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
if (GST_GL_IS_WRAPPED_CONTEXT (context))
return NULL;
_ensure_window (context);
return gst_object_ref (context->window);
@ -442,7 +522,7 @@ gst_gl_context_create (GstGLContext * context,
gboolean alive = FALSE;
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE);
g_return_val_if_fail (!GST_GL_IS_WRAPPED_CONTEXT (context), FALSE);
_ensure_window (context);
g_mutex_lock (&context->priv->render_lock);
@ -497,9 +577,6 @@ _create_context_gles2 (GstGLContext * context, gint * gl_major, gint * gl_minor,
}
#endif
_gst_gl_feature_check_ext_functions (context, 0, 0,
(const gchar *) gl->GetString (GL_EXTENSIONS));
if (gl_major)
*gl_major = 2;
if (gl_minor)
@ -546,9 +623,6 @@ _create_context_opengl (GstGLContext * context, gint * gl_major,
return FALSE;
}
_gst_gl_feature_check_ext_functions (context, maj, min,
(const gchar *) gl->GetString (GL_EXTENSIONS));
if (gl_major)
*gl_major = maj;
if (gl_minor)
@ -587,7 +661,7 @@ gst_gl_context_create_thread (GstGLContext * context)
GstGLWindowClass *window_class;
GstGLDisplay *display;
GstGLFuncs *gl;
gint gl_major = 0;
gint gl_major = 0, gl_minor = 0;
gboolean ret = FALSE;
GstGLAPI compiled_api, user_api;
gchar *api_string;
@ -692,13 +766,16 @@ gst_gl_context_create_thread (GstGLContext * context)
/* gl api specific code */
if (!ret && USING_OPENGL (display))
ret = _create_context_opengl (context, &gl_major, NULL, error);
ret = _create_context_opengl (context, &gl_major, &gl_minor, error);
if (!ret && USING_GLES2 (display))
ret = _create_context_gles2 (context, &gl_major, NULL, error);
ret = _create_context_gles2 (context, &gl_major, &gl_minor, error);
if (!ret)
goto failure;
_gst_gl_feature_check_ext_functions (context, gl_major, gl_minor,
(const gchar *) gl->GetString (GL_EXTENSIONS));
context->priv->alive = TRUE;
g_cond_signal (&context->priv->create_cond);
@ -763,6 +840,26 @@ gst_gl_context_get_gl_context (GstGLContext * context)
return result;
}
/**
* gst_gl_context_get_gl_platform:
* @context: a #GstGLContext:
*
* Gets the OpenGL platform that used by @context.
*
* Returns: The platform specific backing OpenGL context
*/
GstGLPlatform
gst_gl_context_get_gl_platform (GstGLContext * context)
{
GstGLContextClass *context_class;
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), 0);
context_class = GST_GL_CONTEXT_GET_CLASS (context);
g_return_val_if_fail (context_class->get_gl_platform != NULL, 0);
return context_class->get_gl_platform (context);
}
/**
* gst_gl_context_get_display:
* @context: a #GstGLContext:
@ -811,6 +908,7 @@ gst_gl_context_thread_add (GstGLContext * context,
g_return_if_fail (GST_GL_IS_CONTEXT (context));
g_return_if_fail (func != NULL);
g_return_if_fail (!GST_GL_IS_WRAPPED_CONTEXT (context));
rdata.context = context;
rdata.data = data;
@ -823,3 +921,65 @@ gst_gl_context_thread_add (GstGLContext * context,
gst_object_unref (window);
}
static GstGLAPI
gst_gl_wrapped_context_get_gl_api (GstGLContext * context)
{
GstGLWrappedContext *context_wrap = GST_GL_WRAPPED_CONTEXT (context);
return context_wrap->available_apis;
}
static guintptr
gst_gl_wrapped_context_get_gl_context (GstGLContext * context)
{
GstGLWrappedContext *context_wrap = GST_GL_WRAPPED_CONTEXT (context);
return context_wrap->handle;
}
static GstGLPlatform
gst_gl_wrapped_context_get_gl_platform (GstGLContext * context)
{
GstGLWrappedContext *context_wrap = GST_GL_WRAPPED_CONTEXT (context);
return context_wrap->platform;
}
static gboolean
gst_gl_wrapped_context_activate (GstGLContext * context, gboolean activate)
{
g_assert_not_reached ();
return FALSE;
}
static void
gst_gl_wrapped_context_class_init (GstGLWrappedContextClass * klass)
{
GstGLContextClass *context_class = (GstGLContextClass *) klass;
context_class->get_gl_context =
GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_get_gl_context);
context_class->get_gl_api =
GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_get_gl_api);
context_class->get_gl_platform =
GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_get_gl_platform);
context_class->activate = GST_DEBUG_FUNCPTR (gst_gl_wrapped_context_activate);
}
static void
gst_gl_wrapped_context_init (GstGLWrappedContext * context)
{
}
/* Must be called in the gl thread */
GstGLWrappedContext *
gst_gl_wrapped_context_new (void)
{
GstGLWrappedContext *context =
g_object_new (GST_GL_TYPE_WRAPPED_CONTEXT, NULL);
return context;
}

View file

@ -47,6 +47,10 @@ GQuark gst_gl_context_error_quark (void);
*/
typedef void (*GstGLContextThreadFunc) (GstGLContext * context, gpointer data);
#define GST_GL_CONTEXT_TYPE_GLX "gst.gl.context.GLX"
#define GST_GL_CONTEXT_TYPE_EGL "gst.gl.context.EGL"
#define GST_GL_CONTEXT_TYPE_WGL "gst.gl.context.WGL"
typedef enum
{
GST_GL_CONTEXT_ERROR_FAILED,
@ -89,15 +93,16 @@ struct _GstGLContext {
struct _GstGLContextClass {
GObjectClass parent_class;
guintptr (*get_gl_context) (GstGLContext *context);
GstGLAPI (*get_gl_api) (GstGLContext *context);
gpointer (*get_proc_address) (GstGLContext *context, const gchar *name);
gboolean (*activate) (GstGLContext *context, gboolean activate);
gboolean (*choose_format) (GstGLContext *context, GError **error);
gboolean (*create_context) (GstGLContext *context, GstGLAPI gl_api,
GstGLContext *other_context, GError ** error);
void (*destroy_context) (GstGLContext *context);
void (*swap_buffers) (GstGLContext *context);
guintptr (*get_gl_context) (GstGLContext *context);
GstGLAPI (*get_gl_api) (GstGLContext *context);
GstGLPlatform (*get_gl_platform) (GstGLContext *context);
gpointer (*get_proc_address) (GstGLContext *context, const gchar *name);
gboolean (*activate) (GstGLContext *context, gboolean activate);
gboolean (*choose_format) (GstGLContext *context, GError **error);
gboolean (*create_context) (GstGLContext *context, GstGLAPI gl_api,
GstGLContext *other_context, GError ** error);
void (*destroy_context) (GstGLContext *context);
void (*swap_buffers) (GstGLContext *context);
/*< private >*/
gpointer _reserved[GST_PADDING];
@ -106,12 +111,16 @@ struct _GstGLContextClass {
/* methods */
GstGLContext * gst_gl_context_new (GstGLDisplay *display);
GstGLContext * gst_gl_context_new_wrapped (GstGLDisplay *display,
guintptr handle,
GstGLPlatform context_type,
GstGLAPI available_apis);
gboolean gst_gl_context_activate (GstGLContext *context, gboolean activate);
GstGLDisplay * gst_gl_context_get_display (GstGLContext *context);
gpointer gst_gl_context_get_proc_address (GstGLContext *context, const gchar *name);
GstGLPlatform gst_gl_context_get_platform (GstGLContext *context);
GstGLPlatform gst_gl_context_get_gl_platform (GstGLContext *context);
GstGLAPI gst_gl_context_get_gl_api (GstGLContext *context);
guintptr gst_gl_context_get_gl_context (GstGLContext *context);

View file

@ -43,6 +43,8 @@ static gboolean gst_gl_context_wgl_create_context (GstGLContext * context,
GstGLAPI gl_api, GstGLContext * other_context, GError ** error);
static void gst_gl_context_wgl_destroy_context (GstGLContext * context);
GstGLAPI gst_gl_context_wgl_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_wgl_get_gl_platform (GstGLContext *
context);
static gpointer gst_gl_context_wgl_get_proc_address (GstGLContext * context,
const gchar * name);
@ -66,6 +68,8 @@ gst_gl_context_wgl_class_init (GstGLContextWGLClass * klass)
context_class->get_proc_address =
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_proc_address);
context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_api);
context_class->get_gl_platform =
GST_DEBUG_FUNCPTR (gst_gl_context_wgl_get_gl_platform);
}
static void
@ -88,7 +92,7 @@ gst_gl_context_wgl_create_context (GstGLContext * context,
{
GstGLWindow *window;
GstGLContextWGL *context_wgl;
GstGLContextWGL *other_wgl = NULL;
HGLRC external_gl_context = NULL;
HDC device;
context_wgl = GST_GL_CONTEXT_WGL (context);
@ -102,7 +106,7 @@ gst_gl_context_wgl_create_context (GstGLContext * context,
"Cannot share context with a non-WGL context");
goto failure;
}
other_wgl = (GstGLContextWGL *) other_context;
external_gl_context = (HGLRC) gst_gl_context_get_gl_context (other_context);
}
context_wgl->wgl_context = wglCreateContext (device);
@ -120,8 +124,8 @@ gst_gl_context_wgl_create_context (GstGLContext * context,
GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
(guintptr) context_wgl->wgl_context);
if (other_wgl) {
if (!wglShareLists (other_wgl->wgl_context, context_wgl->wgl_context)) {
if (external_gl_context) {
if (!wglShareLists (external_gl_context, context_wgl->wgl_context)) {
g_set_error (error, GST_GL_CONTEXT_ERROR,
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "failed to share contexts 0x%x",
(unsigned int) GetLastError ());
@ -253,6 +257,12 @@ gst_gl_context_wgl_get_gl_api (GstGLContext * context)
return GST_GL_API_OPENGL;
}
static GstGLPlatform
gst_gl_context_wgl_get_gl_platform (GstGLContext * context)
{
return GST_GL_PLATFORM_WGL;
}
static gpointer
gst_gl_context_wgl_get_proc_address (GstGLContext * context, const gchar * name)
{

View file

@ -55,6 +55,8 @@ static void gst_gl_context_glx_destroy_context (GstGLContext * context);
static gboolean gst_gl_context_glx_choose_format (GstGLContext *
context, GError ** error);
GstGLAPI gst_gl_context_glx_get_gl_api (GstGLContext * context);
static GstGLPlatform gst_gl_context_glx_get_gl_platform (GstGLContext *
context);
static gpointer gst_gl_context_glx_get_proc_address (GstGLContext * context,
const gchar * name);
@ -90,6 +92,8 @@ gst_gl_context_glx_class_init (GstGLContextGLXClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_context_glx_swap_buffers);
context_class->get_gl_api = GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_gl_api);
context_class->get_gl_platform =
GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_gl_platform);
context_class->get_proc_address =
GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_proc_address);
}
@ -149,23 +153,17 @@ gst_gl_context_glx_create_context (GstGLContext * context,
window_x11 = GST_GL_WINDOW_X11 (window);
if (other_context) {
GstGLWindow *other_window;
if (!GST_GL_IS_CONTEXT_GLX (other_context)) {
if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_GLX) {
g_set_error (error, GST_GL_CONTEXT_ERROR,
GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
"Cannot share context with non-GLX context");
goto failure;
}
other_window = gst_gl_context_get_window (other_context);
external_gl_context = gst_gl_context_get_gl_context (other_context);
device = (Display *) gst_gl_window_get_display (other_window);
gst_object_unref (other_window);
} else {
device = (Display *) gst_gl_window_get_display (window);
}
device = (Display *) gst_gl_window_get_display (window);
glx_exts = glXQueryExtensionsString (device, DefaultScreen (device));
create_context = gst_gl_check_extension ("GLX_ARB_create_context", glx_exts);
@ -408,6 +406,12 @@ gst_gl_context_glx_get_gl_api (GstGLContext * context)
return context_glx->priv->context_api;
}
static GstGLPlatform
gst_gl_context_glx_get_gl_platform (GstGLContext * context)
{
return GST_GL_PLATFORM_GLX;
}
static gpointer
gst_gl_context_glx_get_proc_address (GstGLContext * context, const gchar * name)
{

View file

@ -117,7 +117,8 @@ deinit (gpointer data)
gl->DeleteTextures (1, &tex);;
gst_object_unref (fbo);
#if GST_GL_HAVE_GLES2
gst_object_unref (shader);
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2)
gst_object_unref (shader);
#endif
}
@ -281,6 +282,66 @@ GST_START_TEST (test_share)
GST_END_TEST;
GST_START_TEST (test_wrapped_context)
{
GstGLContext *context, *other_context, *wrapped_context;
GstGLWindow *window, *other_window;
GError *error = NULL;
gint i = 0;
guintptr handle;
GstGLPlatform platform;
GstGLAPI apis;
display = gst_gl_display_new ();
context = gst_gl_context_new (display);
window = gst_gl_window_new (display);
gst_gl_context_set_window (context, window);
gst_gl_context_create (context, 0, &error);
fail_if (error != NULL, "Error creating master context %s\n",
error ? error->message : "Unknown Error");
handle = gst_gl_context_get_gl_context (context);
platform = gst_gl_context_get_gl_platform (context);
apis = gst_gl_context_get_gl_api (context);
wrapped_context =
gst_gl_context_new_wrapped (display, handle, platform, apis);
other_context = gst_gl_context_new (display);
other_window = gst_gl_window_new (display);
gst_gl_context_set_window (other_context, other_window);
gst_gl_context_create (other_context, wrapped_context, &error);
fail_if (error != NULL, "Error creating secondary context %s\n",
error ? error->message : "Unknown Error");
/* make the window visible */
gst_gl_window_draw (window, 320, 240);
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (init), context);
while (i < 1000) {
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (draw_tex),
context);
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
context);
i++;
}
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit), context);
gst_object_unref (window);
gst_object_unref (other_window);
gst_object_unref (other_context);
gst_object_unref (context);
}
GST_END_TEST;
Suite *
gst_gl_memory_suite (void)
@ -291,6 +352,7 @@ gst_gl_memory_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_checked_fixture (tc_chain, setup, teardown);
tcase_add_test (tc_chain, test_share);
tcase_add_test (tc_chain, test_wrapped_context);
return s;
}