mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
[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:
parent
09704b9e70
commit
2eb9cb551c
8 changed files with 33 additions and 43 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue