mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
[801/906] context: Reimplement GL context sharing
https://bugzilla.gnome.org/show_bug.cgi?id=704806
This commit is contained in:
parent
2d876dfb70
commit
b24021b1ac
6 changed files with 131 additions and 49 deletions
|
@ -28,7 +28,7 @@
|
||||||
#include "gstgl_cocoa_private.h"
|
#include "gstgl_cocoa_private.h"
|
||||||
|
|
||||||
static gboolean gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
static gboolean gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
||||||
guintptr external_opengl_context, GError **error);
|
GstGLContext * other_context, GError **error);
|
||||||
static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
|
static guintptr gst_gl_context_cocoa_get_gl_context (GstGLContext * window);
|
||||||
static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
|
static gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
|
||||||
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
|
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
|
||||||
|
@ -84,7 +84,7 @@ gst_gl_context_cocoa_new (void)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
||||||
guintptr external_gl_context, GError **error)
|
GstGLContext *other_context, GError **error)
|
||||||
{
|
{
|
||||||
GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
|
GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context);
|
||||||
GstGLContextCocoaPrivate *priv = context_cocoa->priv;
|
GstGLContextCocoaPrivate *priv = context_cocoa->priv;
|
||||||
|
@ -103,7 +103,10 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
||||||
};
|
};
|
||||||
|
|
||||||
priv->gl_context = nil;
|
priv->gl_context = nil;
|
||||||
priv->external_gl_context = (NSOpenGLContext *) external_gl_context;
|
if (other_context)
|
||||||
|
priv->external_gl_context = (NSOpenGLContext *) gst_gl_context_get_gl_context (other_context);
|
||||||
|
else
|
||||||
|
priv->external_gl_context = NULL;
|
||||||
|
|
||||||
GSRegisterCurrentThread();
|
GSRegisterCurrentThread();
|
||||||
|
|
||||||
|
@ -146,7 +149,9 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
|
||||||
context_cocoa->priv->gl_context = glContext;
|
context_cocoa->priv->gl_context = glContext;
|
||||||
|
|
||||||
[glView setOpenGLContext:glContext];
|
[glView setOpenGLContext:glContext];
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
/* FIXME try to make context sharing work in GNUstep */
|
||||||
context_cocoa->priv->gl_context = [glView openGLContext];
|
context_cocoa->priv->gl_context = [glView openGLContext];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: Sharing contexts requires the EGLDisplay & EGLConfig to be the same
|
||||||
|
* may need to box it.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "gstglcontext_egl.h"
|
#include "gstglcontext_egl.h"
|
||||||
#include <gst/gl/gl.h>
|
#include <gst/gl/gl.h>
|
||||||
|
|
||||||
|
@ -33,7 +37,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean gst_gl_context_egl_create_context (GstGLContext * context,
|
static gboolean gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
GstGLAPI gl_api, GstGLContext * other_context, GError ** error);
|
||||||
static void gst_gl_context_egl_destroy_context (GstGLContext * context);
|
static void gst_gl_context_egl_destroy_context (GstGLContext * context);
|
||||||
static gboolean gst_gl_context_egl_choose_format (GstGLContext * context,
|
static gboolean gst_gl_context_egl_choose_format (GstGLContext * context,
|
||||||
GError ** error);
|
GError ** error);
|
||||||
|
@ -150,27 +154,40 @@ gst_gl_context_egl_choose_format (GstGLContext * context, GError ** error)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_context_egl_choose_config (GstGLContextEGL * egl, GError ** error)
|
gst_gl_context_egl_choose_config (GstGLContextEGL * egl,
|
||||||
|
GstGLContext * other_context, GError ** error)
|
||||||
{
|
{
|
||||||
EGLint numConfigs;
|
EGLint numConfigs;
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
EGLint config_attrib[20];
|
EGLint config_attrib[20];
|
||||||
|
|
||||||
config_attrib[i++] = EGL_SURFACE_TYPE;
|
if (other_context) {
|
||||||
config_attrib[i++] = EGL_WINDOW_BIT;
|
GstGLContextEGL *other_context_egl = GST_GL_CONTEXT_EGL (other_context);
|
||||||
config_attrib[i++] = EGL_RENDERABLE_TYPE;
|
EGLint config_id;
|
||||||
if (egl->gl_api & GST_GL_API_GLES2)
|
|
||||||
config_attrib[i++] = EGL_OPENGL_ES2_BIT;
|
eglGetConfigAttrib (egl->egl_display, other_context_egl->egl_config,
|
||||||
else
|
EGL_CONFIG_ID, &config_id);
|
||||||
config_attrib[i++] = EGL_OPENGL_BIT;
|
|
||||||
config_attrib[i++] = EGL_DEPTH_SIZE;
|
config_attrib[i++] = EGL_CONFIG_ID;
|
||||||
config_attrib[i++] = 16;
|
config_attrib[i++] = config_id;
|
||||||
config_attrib[i++] = EGL_NONE;
|
config_attrib[i++] = EGL_NONE;
|
||||||
|
} else {
|
||||||
|
config_attrib[i++] = EGL_SURFACE_TYPE;
|
||||||
|
config_attrib[i++] = EGL_WINDOW_BIT;
|
||||||
|
config_attrib[i++] = EGL_RENDERABLE_TYPE;
|
||||||
|
if (egl->gl_api & GST_GL_API_GLES2)
|
||||||
|
config_attrib[i++] = EGL_OPENGL_ES2_BIT;
|
||||||
|
else
|
||||||
|
config_attrib[i++] = EGL_OPENGL_BIT;
|
||||||
|
config_attrib[i++] = EGL_DEPTH_SIZE;
|
||||||
|
config_attrib[i++] = 16;
|
||||||
|
config_attrib[i++] = EGL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (eglChooseConfig (egl->egl_display, config_attrib,
|
if (eglChooseConfig (egl->egl_display, config_attrib,
|
||||||
&egl->egl_config, 1, &numConfigs)) {
|
&egl->egl_config, 1, &numConfigs)) {
|
||||||
GST_INFO ("config set: %ld, %ld", (gulong) egl->egl_config,
|
GST_INFO ("config set: %" G_GUINTPTR_FORMAT ", %u",
|
||||||
(gulong) numConfigs);
|
(guintptr) egl->egl_config, (unsigned int) numConfigs);
|
||||||
} else {
|
} else {
|
||||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
|
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
|
||||||
"Failed to set window configuration: %s",
|
"Failed to set window configuration: %s",
|
||||||
|
@ -186,7 +203,7 @@ failure:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_context_egl_create_context (GstGLContext * context,
|
gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
|
||||||
{
|
{
|
||||||
GstGLContextEGL *egl;
|
GstGLContextEGL *egl;
|
||||||
GstGLWindow *window = NULL;
|
GstGLWindow *window = NULL;
|
||||||
|
@ -197,19 +214,33 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
EGLint minorVersion;
|
EGLint minorVersion;
|
||||||
const gchar *egl_exts;
|
const gchar *egl_exts;
|
||||||
gboolean need_surface = TRUE;
|
gboolean need_surface = TRUE;
|
||||||
|
guintptr external_gl_context = 0;
|
||||||
|
|
||||||
egl = GST_GL_CONTEXT_EGL (context);
|
egl = GST_GL_CONTEXT_EGL (context);
|
||||||
window = gst_gl_context_get_window (context);
|
window = gst_gl_context_get_window (context);
|
||||||
|
|
||||||
if ((gl_api & GST_GL_API_OPENGL) == GST_GL_API_NONE &&
|
if (other_context) {
|
||||||
(gl_api & GST_GL_API_GLES2) == GST_GL_API_NONE) {
|
if (!GST_GL_IS_CONTEXT_EGL (other_context)) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||||
|
"Cannot share context with non-EGL context");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
external_gl_context = gst_gl_context_get_gl_context (other_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((gl_api & (GST_GL_API_OPENGL | GST_GL_API_GLES2)) == GST_GL_API_NONE) {
|
||||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
|
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
|
||||||
"xEGL supports opengl or gles2");
|
"EGL supports opengl or gles2");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl->egl_display =
|
if (other_context) {
|
||||||
eglGetDisplay ((EGLNativeDisplayType) gst_gl_window_get_display (window));
|
GstGLContextEGL *other_egl = (GstGLContextEGL *) other_context;
|
||||||
|
egl->egl_display = other_egl->egl_display;
|
||||||
|
} else {
|
||||||
|
egl->egl_display = eglGetDisplay ((EGLNativeDisplayType)
|
||||||
|
gst_gl_window_get_display (window));
|
||||||
|
}
|
||||||
|
|
||||||
if (eglInitialize (egl->egl_display, &majorVersion, &minorVersion)) {
|
if (eglInitialize (egl->egl_display, &majorVersion, &minorVersion)) {
|
||||||
GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion);
|
GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion);
|
||||||
|
@ -245,11 +276,12 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
|
|
||||||
if (!eglBindAPI (EGL_OPENGL_API)) {
|
if (!eglBindAPI (EGL_OPENGL_API)) {
|
||||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||||
"Failed to bind OpenGL|ES API: %s",
|
"Failed to bind OpenGL API: %s",
|
||||||
gst_gl_context_egl_get_error_string ());
|
gst_gl_context_egl_get_error_string ());
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_INFO ("Using OpenGL");
|
||||||
egl->gl_api = GST_GL_API_OPENGL;
|
egl->gl_api = GST_GL_API_OPENGL;
|
||||||
} else if (gl_api & GST_GL_API_GLES2) {
|
} else if (gl_api & GST_GL_API_GLES2) {
|
||||||
try_gles2:
|
try_gles2:
|
||||||
|
@ -260,10 +292,11 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_INFO ("Using OpenGL|ES 2.0");
|
||||||
egl->gl_api = GST_GL_API_GLES2;
|
egl->gl_api = GST_GL_API_GLES2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_gl_context_egl_choose_config (egl, error)) {
|
if (!gst_gl_context_egl_choose_config (egl, other_context, error)) {
|
||||||
g_assert (error == NULL || *error != NULL);
|
g_assert (error == NULL || *error != NULL);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +314,8 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
(EGLContext) external_gl_context, context_attrib);
|
(EGLContext) external_gl_context, context_attrib);
|
||||||
|
|
||||||
if (egl->egl_context != EGL_NO_CONTEXT) {
|
if (egl->egl_context != EGL_NO_CONTEXT) {
|
||||||
GST_INFO ("gl context created: %ld", (gulong) egl->egl_context);
|
GST_INFO ("gl context created: %" G_GUINTPTR_FORMAT,
|
||||||
|
(guintptr) egl->egl_context);
|
||||||
} else {
|
} else {
|
||||||
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
||||||
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
|
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
|
||||||
|
@ -292,17 +326,19 @@ gst_gl_context_egl_create_context (GstGLContext * context,
|
||||||
|
|
||||||
egl_exts = eglQueryString (egl->egl_display, EGL_EXTENSIONS);
|
egl_exts = eglQueryString (egl->egl_display, EGL_EXTENSIONS);
|
||||||
|
|
||||||
/* FIXME do we want a window vfunc ? */
|
if (other_context == NULL) {
|
||||||
|
/* FIXME do we want a window vfunc ? */
|
||||||
#if GST_GL_HAVE_WINDOW_X11
|
#if GST_GL_HAVE_WINDOW_X11
|
||||||
if (GST_GL_IS_WINDOW_X11 (context->window)) {
|
if (GST_GL_IS_WINDOW_X11 (context->window)) {
|
||||||
gst_gl_window_x11_create_window ((GstGLWindowX11 *) context->window);
|
gst_gl_window_x11_create_window ((GstGLWindowX11 *) context->window);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if GST_GL_HAVE_WINDOW_WIN32
|
#if GST_GL_HAVE_WINDOW_WIN32
|
||||||
if (GST_GL_IS_WINDOW_WIN32 (context->window)) {
|
if (GST_GL_IS_WINDOW_WIN32 (context->window)) {
|
||||||
gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window);
|
gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
window_handle = gst_gl_window_get_window_handle (window);
|
window_handle = gst_gl_window_get_window_handle (window);
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct _GstGLContextPrivate
|
||||||
gboolean created;
|
gboolean created;
|
||||||
gboolean alive;
|
gboolean alive;
|
||||||
|
|
||||||
guintptr external_gl_context;
|
GstGLContext *other_context;
|
||||||
GstGLAPI gl_api;
|
GstGLAPI gl_api;
|
||||||
GError **error;
|
GError **error;
|
||||||
};
|
};
|
||||||
|
@ -299,7 +299,7 @@ gst_gl_context_get_window (GstGLContext * context)
|
||||||
/* Create an opengl context (one context for one GstGLDisplay) */
|
/* Create an opengl context (one context for one GstGLDisplay) */
|
||||||
gboolean
|
gboolean
|
||||||
gst_gl_context_create (GstGLContext * context,
|
gst_gl_context_create (GstGLContext * context,
|
||||||
guintptr external_gl_context, GError ** error)
|
GstGLContext * other_context, GError ** error)
|
||||||
{
|
{
|
||||||
gboolean alive = FALSE;
|
gboolean alive = FALSE;
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ gst_gl_context_create (GstGLContext * context,
|
||||||
g_mutex_lock (&context->priv->render_lock);
|
g_mutex_lock (&context->priv->render_lock);
|
||||||
|
|
||||||
if (!context->priv->created) {
|
if (!context->priv->created) {
|
||||||
context->priv->external_gl_context = external_gl_context;
|
context->priv->other_context = other_context;
|
||||||
context->priv->error = error;
|
context->priv->error = error;
|
||||||
|
|
||||||
context->priv->gl_thread = g_thread_new ("gstglcontext",
|
context->priv->gl_thread = g_thread_new ("gstglcontext",
|
||||||
|
@ -476,7 +476,7 @@ _parse_gl_api (const gchar * apis_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
//gboolean
|
//gboolean
|
||||||
//gst_gl_context_create (GstGLContext * context, guintptr external_gl_context, GError ** error)
|
//gst_gl_context_create (GstGLContext * context, GstGLContext * other_context, GError ** error)
|
||||||
static gpointer
|
static gpointer
|
||||||
gst_gl_context_create_thread (GstGLContext * context)
|
gst_gl_context_create_thread (GstGLContext * context)
|
||||||
{
|
{
|
||||||
|
@ -492,12 +492,12 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
gchar *user_api_string;
|
gchar *user_api_string;
|
||||||
const gchar *user_choice;
|
const gchar *user_choice;
|
||||||
GError **error;
|
GError **error;
|
||||||
guintptr external_gl_context;
|
GstGLContext *other_context;
|
||||||
|
|
||||||
g_mutex_lock (&context->priv->render_lock);
|
g_mutex_lock (&context->priv->render_lock);
|
||||||
|
|
||||||
error = context->priv->error;
|
error = context->priv->error;
|
||||||
external_gl_context = context->priv->external_gl_context;
|
other_context = context->priv->other_context;
|
||||||
|
|
||||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||||
|
@ -539,7 +539,7 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
"compiled api support (%s)", user_api_string, compiled_api_s);
|
"compiled api support (%s)", user_api_string, compiled_api_s);
|
||||||
|
|
||||||
if (!context_class->create_context (context, compiled_api & user_api,
|
if (!context_class->create_context (context, compiled_api & user_api,
|
||||||
external_gl_context, error)) {
|
other_context, error)) {
|
||||||
g_assert (error == NULL || *error != NULL);
|
g_assert (error == NULL || *error != NULL);
|
||||||
g_free (compiled_api_s);
|
g_free (compiled_api_s);
|
||||||
g_free (user_api_string);
|
g_free (user_api_string);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include <gst/gl/gstgl_fwd.h>
|
#include <gst/gl/gl.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ struct _GstGLContextClass {
|
||||||
gboolean (*activate) (GstGLContext *context, gboolean activate);
|
gboolean (*activate) (GstGLContext *context, gboolean activate);
|
||||||
gboolean (*choose_format) (GstGLContext *context, GError **error);
|
gboolean (*choose_format) (GstGLContext *context, GError **error);
|
||||||
gboolean (*create_context) (GstGLContext *context, GstGLAPI gl_api,
|
gboolean (*create_context) (GstGLContext *context, GstGLAPI gl_api,
|
||||||
guintptr external_gl_context, GError ** error);
|
GstGLContext *other_context, GError ** error);
|
||||||
void (*destroy_context) (GstGLContext *context);
|
void (*destroy_context) (GstGLContext *context);
|
||||||
void (*swap_buffers) (GstGLContext *context);
|
void (*swap_buffers) (GstGLContext *context);
|
||||||
|
|
||||||
|
@ -88,8 +88,9 @@ gboolean gst_gl_context_activate (GstGLContext *context, gboolean a
|
||||||
gpointer gst_gl_context_get_proc_address (GstGLContext *context, const gchar *name);
|
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_platform (GstGLContext *context);
|
||||||
GstGLAPI gst_gl_context_get_gl_api (GstGLContext *context);
|
GstGLAPI gst_gl_context_get_gl_api (GstGLContext *context);
|
||||||
|
guintptr gst_gl_context_get_gl_context (GstGLContext *context);
|
||||||
|
|
||||||
gboolean gst_gl_context_create (GstGLContext *context, guintptr external_gl_context, GError ** error);
|
gboolean gst_gl_context_create (GstGLContext *context, GstGLContext *other_context, GError ** error);
|
||||||
|
|
||||||
gpointer gst_gl_context_default_get_proc_address (GstGLContext *context, const gchar *name);
|
gpointer gst_gl_context_default_get_proc_address (GstGLContext *context, const gchar *name);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ static gboolean gst_gl_context_wgl_choose_format (GstGLContext * context,
|
||||||
static gboolean gst_gl_context_wgl_activate (GstGLContext * context,
|
static gboolean gst_gl_context_wgl_activate (GstGLContext * context,
|
||||||
gboolean activate);
|
gboolean activate);
|
||||||
static gboolean gst_gl_context_wgl_create_context (GstGLContext * context,
|
static gboolean gst_gl_context_wgl_create_context (GstGLContext * context,
|
||||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
GstGLAPI gl_api, GstGLContext * other_context, GError ** error);
|
||||||
static void gst_gl_context_wgl_destroy_context (GstGLContext * context);
|
static void gst_gl_context_wgl_destroy_context (GstGLContext * context);
|
||||||
GstGLAPI gst_gl_context_wgl_get_gl_api (GstGLContext * context);
|
GstGLAPI gst_gl_context_wgl_get_gl_api (GstGLContext * context);
|
||||||
static gpointer gst_gl_context_wgl_get_proc_address (GstGLContext * context,
|
static gpointer gst_gl_context_wgl_get_proc_address (GstGLContext * context,
|
||||||
|
@ -84,23 +84,33 @@ gst_gl_context_wgl_new (void)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_context_wgl_create_context (GstGLContext * context,
|
gst_gl_context_wgl_create_context (GstGLContext * context,
|
||||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
|
||||||
{
|
{
|
||||||
GstGLWindow *window;
|
GstGLWindow *window;
|
||||||
GstGLContextWGL *context_wgl;
|
GstGLContextWGL *context_wgl;
|
||||||
|
GstGLContextWGL *other_wgl = NULL;
|
||||||
HDC device;
|
HDC device;
|
||||||
|
|
||||||
context_wgl = GST_GL_CONTEXT_WGL (context);
|
context_wgl = GST_GL_CONTEXT_WGL (context);
|
||||||
window = gst_gl_context_get_window (context);
|
window = gst_gl_context_get_window (context);
|
||||||
device = (HDC) gst_gl_window_get_display (window);
|
device = (HDC) gst_gl_window_get_display (window);
|
||||||
|
|
||||||
|
if (other_context) {
|
||||||
|
if (!GST_GL_IS_CONTEXT_WGL (other_context)) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_CONFIG,
|
||||||
|
"Cannot share context with a non-WGL context");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
other_wgl = (GstGLContextWGL *) other_context;
|
||||||
|
}
|
||||||
|
|
||||||
context_wgl->wgl_context = wglCreateContext (device);
|
context_wgl->wgl_context = wglCreateContext (device);
|
||||||
if (context_wgl->wgl_context)
|
if (context_wgl->wgl_context)
|
||||||
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
|
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
|
||||||
(guintptr) context_wgl->wgl_context);
|
(guintptr) context_wgl->wgl_context);
|
||||||
else {
|
else {
|
||||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_CREATE_CONTEXT,
|
||||||
"failed to create glcontext:%lu", GetLastError ());
|
"failed to create glcontext:0x%x", (unsigned int) GetLastError ());
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
g_assert (context_wgl->wgl_context);
|
g_assert (context_wgl->wgl_context);
|
||||||
|
@ -108,6 +118,15 @@ gst_gl_context_wgl_create_context (GstGLContext * context,
|
||||||
GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
|
GST_LOG ("gl context id: %" G_GUINTPTR_FORMAT,
|
||||||
(guintptr) context_wgl->wgl_context);
|
(guintptr) context_wgl->wgl_context);
|
||||||
|
|
||||||
|
if (other_wgl) {
|
||||||
|
if (!wglShareLists (other_wgl->wgl_context, context_wgl->wgl_context)) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR,
|
||||||
|
GST_GL_WINDOW_ERROR_CREATE_CONTEXT, "failed to share contexts 0x%x",
|
||||||
|
(unsigned int) GetLastError ());
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gst_object_unref (window);
|
gst_object_unref (window);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: Sharing contexts requires the Display to be the same.
|
||||||
|
* May need to box it
|
||||||
|
*/
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include "../gstgl_fwd.h"
|
#include "../gstgl_fwd.h"
|
||||||
|
@ -46,7 +50,7 @@ static void gst_gl_context_glx_swap_buffers (GstGLContext * context);
|
||||||
static gboolean gst_gl_context_glx_activate (GstGLContext * context,
|
static gboolean gst_gl_context_glx_activate (GstGLContext * context,
|
||||||
gboolean activate);
|
gboolean activate);
|
||||||
static gboolean gst_gl_context_glx_create_context (GstGLContext *
|
static gboolean gst_gl_context_glx_create_context (GstGLContext *
|
||||||
context, GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
|
context, GstGLAPI gl_api, GstGLContext * other_context, GError ** error);
|
||||||
static void gst_gl_context_glx_destroy_context (GstGLContext * context);
|
static void gst_gl_context_glx_destroy_context (GstGLContext * context);
|
||||||
static gboolean gst_gl_context_glx_choose_format (GstGLContext *
|
static gboolean gst_gl_context_glx_choose_format (GstGLContext *
|
||||||
context, GError ** error);
|
context, GError ** error);
|
||||||
|
@ -129,7 +133,7 @@ _describe_fbconfig (Display * display, GLXFBConfig config)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_context_glx_create_context (GstGLContext * context,
|
gst_gl_context_glx_create_context (GstGLContext * context,
|
||||||
GstGLAPI gl_api, guintptr external_gl_context, GError ** error)
|
GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
|
||||||
{
|
{
|
||||||
GstGLContextGLX *context_glx;
|
GstGLContextGLX *context_glx;
|
||||||
GstGLWindow *window;
|
GstGLWindow *window;
|
||||||
|
@ -138,11 +142,28 @@ gst_gl_context_glx_create_context (GstGLContext * context,
|
||||||
const char *glx_exts;
|
const char *glx_exts;
|
||||||
int x_error;
|
int x_error;
|
||||||
Display *device;
|
Display *device;
|
||||||
|
guintptr external_gl_context = 0;
|
||||||
|
|
||||||
context_glx = GST_GL_CONTEXT_GLX (context);
|
context_glx = GST_GL_CONTEXT_GLX (context);
|
||||||
window = gst_gl_context_get_window (context);
|
window = gst_gl_context_get_window (context);
|
||||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||||
device = (Display *) gst_gl_window_get_display (window);
|
|
||||||
|
if (other_context) {
|
||||||
|
GstGLWindow *other_window;
|
||||||
|
|
||||||
|
if (!GST_GL_IS_CONTEXT_GLX (other_context)) {
|
||||||
|
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_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);
|
||||||
|
}
|
||||||
|
|
||||||
glx_exts = glXQueryExtensionsString (device, DefaultScreen (device));
|
glx_exts = glXQueryExtensionsString (device, DefaultScreen (device));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue