#include "gstgl_cocoa_private.h"
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 gboolean gst_gl_context_cocoa_activate (GstGLContext * context, gboolean activate);
static GstGLAPI gst_gl_context_cocoa_get_gl_api (GstGLContext * context);
static gboolean
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);
GstGLContextCocoaPrivate *priv = context_cocoa->priv;
};
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();
context_cocoa->priv->gl_context = glContext;
[glView setOpenGLContext:glContext];
+
#else
+ /* FIXME try to make context sharing work in GNUstep */
context_cocoa->priv->gl_context = [glView openGLContext];
#endif
#include "config.h"
#endif
+/* FIXME: Sharing contexts requires the EGLDisplay & EGLConfig to be the same
+ * may need to box it.
+ */
+
#include "gstglcontext_egl.h"
#include <gst/gl/gl.h>
#endif
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 gboolean gst_gl_context_egl_choose_format (GstGLContext * context,
GError ** error);
}
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;
gint i = 0;
EGLint config_attrib[20];
- 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 (other_context) {
+ GstGLContextEGL *other_context_egl = GST_GL_CONTEXT_EGL (other_context);
+ EGLint config_id;
+
+ eglGetConfigAttrib (egl->egl_display, other_context_egl->egl_config,
+ EGL_CONFIG_ID, &config_id);
+
+ config_attrib[i++] = EGL_CONFIG_ID;
+ config_attrib[i++] = config_id;
+ 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,
&egl->egl_config, 1, &numConfigs)) {
- GST_INFO ("config set: %ld, %ld", (gulong) egl->egl_config,
- (gulong) numConfigs);
+ GST_INFO ("config set: %" G_GUINTPTR_FORMAT ", %u",
+ (guintptr) egl->egl_config, (unsigned int) numConfigs);
} else {
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
"Failed to set window configuration: %s",
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)
{
GstGLContextEGL *egl;
GstGLWindow *window = NULL;
EGLint minorVersion;
const gchar *egl_exts;
gboolean need_surface = TRUE;
+ guintptr external_gl_context = 0;
egl = GST_GL_CONTEXT_EGL (context);
window = gst_gl_context_get_window (context);
- if ((gl_api & GST_GL_API_OPENGL) == GST_GL_API_NONE &&
- (gl_api & GST_GL_API_GLES2) == GST_GL_API_NONE) {
+ if (other_context) {
+ 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,
- "xEGL supports opengl or gles2");
+ "EGL supports opengl or gles2");
goto failure;
}
- egl->egl_display =
- eglGetDisplay ((EGLNativeDisplayType) gst_gl_window_get_display (window));
+ if (other_context) {
+ 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)) {
GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion);
if (!eglBindAPI (EGL_OPENGL_API)) {
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 ());
goto failure;
}
+ GST_INFO ("Using OpenGL");
egl->gl_api = GST_GL_API_OPENGL;
} else if (gl_api & GST_GL_API_GLES2) {
try_gles2:
goto failure;
}
+ GST_INFO ("Using OpenGL|ES 2.0");
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);
goto failure;
}
(EGLContext) external_gl_context, context_attrib);
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 {
g_set_error (error, GST_GL_CONTEXT_ERROR,
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
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_IS_WINDOW_X11 (context->window)) {
- gst_gl_window_x11_create_window ((GstGLWindowX11 *) context->window);
- }
+ if (GST_GL_IS_WINDOW_X11 (context->window)) {
+ gst_gl_window_x11_create_window ((GstGLWindowX11 *) context->window);
+ }
#endif
#if GST_GL_HAVE_WINDOW_WIN32
- if (GST_GL_IS_WINDOW_WIN32 (context->window)) {
- gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window);
- }
+ if (GST_GL_IS_WINDOW_WIN32 (context->window)) {
+ gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window);
+ }
#endif
+ }
window_handle = gst_gl_window_get_window_handle (window);
gboolean created;
gboolean alive;
- guintptr external_gl_context;
+ GstGLContext *other_context;
GstGLAPI gl_api;
GError **error;
};
/* Create an opengl context (one context for one GstGLDisplay) */
gboolean
gst_gl_context_create (GstGLContext * context,
- guintptr external_gl_context, GError ** error)
+ GstGLContext * other_context, GError ** error)
{
gboolean alive = FALSE;
g_mutex_lock (&context->priv->render_lock);
if (!context->priv->created) {
- context->priv->external_gl_context = external_gl_context;
+ context->priv->other_context = other_context;
context->priv->error = error;
context->priv->gl_thread = g_thread_new ("gstglcontext",
}
//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
gst_gl_context_create_thread (GstGLContext * context)
{
gchar *user_api_string;
const gchar *user_choice;
GError **error;
- guintptr external_gl_context;
+ GstGLContext *other_context;
g_mutex_lock (&context->priv->render_lock);
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);
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
"compiled api support (%s)", user_api_string, compiled_api_s);
if (!context_class->create_context (context, compiled_api & user_api,
- external_gl_context, error)) {
+ other_context, error)) {
g_assert (error == NULL || *error != NULL);
g_free (compiled_api_s);
g_free (user_api_string);
#include <gst/gst.h>
-#include <gst/gl/gstgl_fwd.h>
+#include <gst/gl/gl.h>
G_BEGIN_DECLS
gboolean (*activate) (GstGLContext *context, gboolean activate);
gboolean (*choose_format) (GstGLContext *context, GError **error);
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 (*swap_buffers) (GstGLContext *context);
gpointer gst_gl_context_get_proc_address (GstGLContext *context, const gchar *name);
GstGLPlatform gst_gl_context_get_platform (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);
static gboolean gst_gl_context_wgl_activate (GstGLContext * context,
gboolean activate);
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);
GstGLAPI gst_gl_context_wgl_get_gl_api (GstGLContext * context);
static gpointer gst_gl_context_wgl_get_proc_address (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)
{
GstGLWindow *window;
GstGLContextWGL *context_wgl;
+ GstGLContextWGL *other_wgl = NULL;
HDC device;
context_wgl = GST_GL_CONTEXT_WGL (context);
window = gst_gl_context_get_window (context);
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);
if (context_wgl->wgl_context)
GST_DEBUG ("gl context created: %" G_GUINTPTR_FORMAT,
(guintptr) context_wgl->wgl_context);
else {
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;
}
g_assert (context_wgl->wgl_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)) {
+ 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);
return TRUE;
#include "config.h"
#endif
+/* FIXME: Sharing contexts requires the Display to be the same.
+ * May need to box it
+ */
+
#include <gst/gst.h>
#include "../gstgl_fwd.h"
static gboolean gst_gl_context_glx_activate (GstGLContext * context,
gboolean activate);
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 gboolean gst_gl_context_glx_choose_format (GstGLContext *
context, GError ** error);
static gboolean
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;
GstGLWindow *window;
const char *glx_exts;
int x_error;
Display *device;
+ guintptr external_gl_context = 0;
context_glx = GST_GL_CONTEXT_GLX (context);
window = gst_gl_context_get_window (context);
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));