mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
[891/906] context: add support for wrapping external contexts
This commit is contained in:
parent
0d1d42b205
commit
3ad466945e
7 changed files with 326 additions and 60 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue