[330/906] Can now share textures with an external gl context

The external opengl context must be specify when creating
our OpenGL context (glx) or just after (wgl).
When calling glXCreateContext or wglShareLists, the
external opengl context must not be current.
Then our gl context can be current in the gl thread while
the external gl context is current in an other thread.
See tests/examples/clutter/cluttershare.c
This commit is contained in:
Julien Isorce 2009-04-18 13:57:44 +02:00 committed by Tim-Philipp Müller
parent 09704b9e70
commit 2eb9cb551c
8 changed files with 33 additions and 43 deletions

View file

@ -158,6 +158,9 @@ gst_gl_display_init (GstGLDisplay * display, GstGLDisplayClass * klass)
display->upload_data_height = 0;
display->upload_data = NULL;
//foreign gl context
display->external_gl_context = 0;
//filter gen fbo
display->gen_fbo_width = 0;
display->gen_fbo_height = 0;
@ -527,7 +530,8 @@ gst_gl_display_thread_create_context (GstGLDisplay * display)
GLenum err = 0;
display->gl_window =
gst_gl_window_new (display->upload_width, display->upload_height);
gst_gl_window_new (display->upload_width, display->upload_height,
display->external_gl_context);
if (!display->gl_window) {
display->isAlive = FALSE;
@ -2065,12 +2069,13 @@ gst_gl_display_new (void)
* Called by the first gl element of a video/x-raw-gl flow */
void
gst_gl_display_create_context (GstGLDisplay * display,
GLint width, GLint height)
GLint width, GLint height, guint64 external_gl_context)
{
gst_gl_display_lock (display);
display->upload_width = width;
display->upload_height = height;
display->external_gl_context = external_gl_context;
display->gl_thread = g_thread_create (
(GThreadFunc) gst_gl_display_thread_create_context, display, TRUE, NULL);

View file

@ -135,6 +135,9 @@ struct _GstGLDisplay
gint upload_data_height;
gpointer upload_data;
//foreign gl context
guint64 external_gl_context;
//filter gen fbo
GLuint gen_fbo_width;
GLuint gen_fbo_height;
@ -236,7 +239,7 @@ GType gst_gl_display_get_type (void);
GstGLDisplay *gst_gl_display_new (void);
void gst_gl_display_create_context (GstGLDisplay * display,
GLint width, GLint height);
GLint width, GLint height, guint64 external_gl_context);
gboolean gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture,
gint width, gint height);

View file

@ -79,10 +79,9 @@ struct _GstGLWindowClass {
GQuark gst_gl_window_error_quark (void);
GType gst_gl_window_get_type (void);
GstGLWindow * gst_gl_window_new (gint width, gint height);
GstGLWindow * gst_gl_window_new (gint width, gint height, guint64 external_gl_context);
void gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id);
void gst_gl_window_set_external_gl_context (GstGLWindow *window, guint64 context);
void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback, gpointer data);
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);

View file

@ -146,7 +146,7 @@ gst_gl_window_init (GstGLWindow * window)
/* Must be called in the gl thread */
GstGLWindow *
gst_gl_window_new (gint width, gint height)
gst_gl_window_new (gint width, gint height, guint64 external_gl_context)
{
GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL);
GstGLWindowPrivate *priv = window->priv;
@ -229,12 +229,6 @@ gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
g_debug ("failed to register current thread, cannot set external window id");
}
void
gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
}
/* Must be called in the gl thread */
void
gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,

View file

@ -51,6 +51,7 @@ struct _GstGLWindowPrivate
HWND internal_win_id;
HDC device;
HGLRC gl_context;
HGLRC external_gl_context;
GstGLWindowCB draw_cb;
gpointer draw_data;
GstGLWindowCB2 resize_cb;
@ -143,7 +144,7 @@ gst_gl_window_init (GstGLWindow * window)
/* Must be called in the gl thread */
GstGLWindow *
gst_gl_window_new (gint width, gint height)
gst_gl_window_new (gint width, gint height, guint64 external_gl_context)
{
GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL);
GstGLWindowPrivate *priv = window->priv;
@ -160,6 +161,7 @@ gst_gl_window_new (gint width, gint height)
priv->internal_win_id = 0;
priv->device = 0;
priv->gl_context = 0;
priv->external_gl_context = (HGLRC) external_gl_context;
priv->draw_cb = NULL;
priv->draw_data = NULL;
priv->resize_cb = NULL;
@ -226,12 +228,6 @@ gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
rect.bottom, FALSE);
}
void
gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
}
/* Must be called in the gl thread */
void
gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
@ -411,6 +407,14 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (!wglMakeCurrent (priv->device, priv->gl_context))
g_debug ("failed to make opengl context current %d, %x\r\n", hWnd,
GetLastError ());
if (priv->external_gl_context) {
if (!wglShareLists (priv->gl_context, priv->external_gl_context))
g_debug ("failed to share opengl context %lud with %lud\n",
priv->gl_context, priv->external_gl_context);
else
g_debug ("share opengl context succeed\n");
}
}
SetProp (hWnd, "gl_window", window);

View file

@ -48,6 +48,7 @@ struct _GstGLWindowPrivate
EGLDisplay display;
EGLSurface surface;
EGLContext gl_context;
EGLContext external_gl_context;
GstGLWindowCB draw_cb;
gpointer draw_data;
GstGLWindowCB2 resize_cb;
@ -140,7 +141,7 @@ gst_gl_window_init (GstGLWindow * window)
/* Must be called in the gl thread */
GstGLWindow *
gst_gl_window_new (gint width, gint height)
gst_gl_window_new (gint width, gint height, guint64 external_gl_context)
{
GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL);
GstGLWindowPrivate *priv = window->priv;
@ -158,6 +159,7 @@ gst_gl_window_new (gint width, gint height)
priv->display = 0;
priv->surface = 0;
priv->gl_context = 0;
priv->external_gl_context = (EGLContext) external_gl_context;
priv->draw_cb = NULL;
priv->draw_data = NULL;
priv->resize_cb = NULL;
@ -224,12 +226,6 @@ gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
rect.bottom, FALSE);
}
void
gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
}
/* Must be called in the gl thread */
void
gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
@ -402,7 +398,7 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
priv->surface, hWnd, EGLErrorString ());
priv->gl_context =
eglCreateContext (priv->display, config, EGL_NO_CONTEXT,
eglCreateContext (priv->display, config, priv->external_gl_context,
contextAttribs);
if (priv->gl_context != EGL_NO_CONTEXT)
g_debug ("gl context created: %d\n", priv->gl_context);

View file

@ -242,7 +242,7 @@ gst_gl_window_init (GstGLWindow * window)
/* Must be called in the gl thread */
GstGLWindow *
gst_gl_window_new (gint width, gint height)
gst_gl_window_new (gint width, gint height, guint64 external_gl_context)
{
GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL);
GstGLWindowPrivate *priv = window->priv;
@ -379,7 +379,8 @@ gst_gl_window_new (gint width, gint height)
XSetWMProtocols (priv->device, priv->internal_win_id, wm_atoms, 2);
priv->gl_context =
glXCreateContext (priv->device, priv->visual_info, NULL, TRUE);
glXCreateContext (priv->device, priv->visual_info,
(GLXContext) external_gl_context, TRUE);
g_debug ("gl context id: %ld\n", (gulong) priv->gl_context);
@ -446,12 +447,6 @@ gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
}
}
void
gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
}
void
gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)

View file

@ -247,7 +247,7 @@ gst_gl_window_init (GstGLWindow * window)
/* Must be called in the gl thread */
GstGLWindow *
gst_gl_window_new (gint width, gint height)
gst_gl_window_new (gint width, gint height, guint64 external_gl_context)
{
GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL);
GstGLWindowPrivate *priv = window->priv;
@ -395,7 +395,7 @@ gst_gl_window_new (gint width, gint height)
(gulong) priv->gl_display, EGLErrorString ());
priv->gl_context =
eglCreateContext (priv->gl_display, config, EGL_NO_CONTEXT,
eglCreateContext (priv->gl_display, config, (EGLContext) external_gl_context,
context_attrib);
if (priv->gl_context != EGL_NO_CONTEXT)
g_debug ("gl context created: %ld\n", (gulong) priv->gl_context);
@ -448,12 +448,6 @@ gst_gl_window_set_external_window_id (GstGLWindow * window, guint64 id)
}
}
void
gst_gl_window_set_external_gl_context (GstGLWindow * window, guint64 context)
{
g_warning ("gst_gl_window_set_external_gl_context: not implemented\n");
}
void
gst_gl_window_set_draw_callback (GstGLWindow * window, GstGLWindowCB callback,
gpointer data)