[337/906] Improve cluttershare example

Use clutter_threads_API.
When just using glupload from rgb, we have to be sure that
the upload texture is not in use in our gst gl context.
This commit is contained in:
Julien Isorce 2009-04-30 23:40:38 +02:00 committed by Matthew Waters
parent d0d5eb1f22
commit 58e392f129
4 changed files with 58 additions and 14 deletions

View file

@ -2709,6 +2709,10 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay * display)
default:
g_assert_not_reached ();
}
//make sure no texture is in use in our opengl context
//in case we want to use the upload texture in an other opengl context
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0);
}

View file

@ -403,7 +403,7 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
g_debug ("failed to share opengl context %lud with %lud\n",
(gulong) priv->gl_context, (gulong) priv->external_gl_context);
else
g_debug ("share opengl context succeed\n");
g_debug ("share opengl context succeed %lud\n", (gulong) priv->external_gl_context);
}
}

View file

@ -401,10 +401,12 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
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);
g_debug ("gl context created: %lud, external: %lud\n", (gulong) priv->gl_context,
(gulong) priv->external_gl_context);
else
g_debug ("failed to create glcontext %d, %d, %s\n", priv->gl_context,
hWnd, EGLErrorString ());
g_debug ("failed to create glcontext %lud, extenal: %lud, win: %lud, %s\n",
(gulong) priv->gl_context, (gulong) priv->external_gl_context,
(gulong) hWnd, EGLErrorString ());
ReleaseDC (hWnd, priv->display);

View file

@ -104,6 +104,8 @@ update_texture_actor (gpointer data)
GstGLBuffer *gst_gl_buf = (GstGLBuffer *) data;
CoglHandle cogl_texture = 0;
ClutterTexture *texture_actor = NULL;
GAsyncQueue *queue_buf = NULL;
GstGLBuffer *gst_gl_buf_old = NULL;
ClutterActor *stage = NULL;
/* Create a cogl texture from the gst gl texture */
@ -113,7 +115,7 @@ update_texture_actor (gpointer data)
GL_TEXTURE_2D, gst_gl_buf->width, gst_gl_buf->height, 0, 0,
COGL_PIXEL_FORMAT_RGBA_8888);
cogl_texture_set_filters (cogl_texture, GL_LINEAR, GL_LINEAR);
glDisable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, 0);
/* Previous cogl texture is replaced and so its ref counter discreases to 0.
* According to the source code, glDeleteTexture is not called when the previous
@ -125,10 +127,11 @@ update_texture_actor (gpointer data)
cogl_texture);
cogl_texture_unref (cogl_texture);
/* Keep a ref on the current gst_gl_buffer associated to the texture_actor.
* The old gst_gl_buffer is unref */
g_object_set_data_full (G_OBJECT (texture_actor), "gst_gl_buffer",
gst_gl_buf, (GDestroyNotify) gst_mini_object_unref);
queue_buf = g_object_get_data (G_OBJECT (texture_actor), "queue_buf");
gst_gl_buf_old = g_object_get_data (G_OBJECT (texture_actor), "gst_gl_buf");
if (gst_gl_buf_old)
g_async_queue_push (queue_buf, gst_gl_buf_old);
g_object_set_data (G_OBJECT (texture_actor), "gst_gl_buf", gst_gl_buf);
/* we can now show the clutter scene if not yet visible */
stage = g_object_get_data (G_OBJECT (texture_actor), "stage");
@ -143,6 +146,14 @@ void
on_gst_buffer (GstElement * element, GstBuffer * buf, GstPad * pad,
ClutterActor * texture_actor)
{
/* unref old buffers we have finished to use in clutter */
GAsyncQueue *queue_buf = g_object_get_data (G_OBJECT (texture_actor), "queue_buf");
if (g_async_queue_length (queue_buf) > 0) {
GstGLBuffer *gst_gl_buf_old = g_async_queue_pop (queue_buf);
if (gst_gl_buf_old)
gst_buffer_unref (gst_gl_buf_old);
}
/* increase ref because our pipeline and clutter scene have not a same framerate */
gst_buffer_ref (buf);
@ -176,12 +187,15 @@ main (int argc, char *argv[])
GstState state = 0;
ClutterActor *stage = NULL;
ClutterActor *clutter_texture = NULL;
GAsyncQueue* queue_buf = NULL;
GstElement *fakesink = NULL;
/* init clutter then gstreamer */
/* init gstreamer then clutter */
clutter_init (&argc, &argv);
gst_init (&argc, &argv);
clutter_threads_init ();
clutter_init (&argc, &argv);
clutter_threads_enter ();
/* init glew */
@ -193,6 +207,9 @@ main (int argc, char *argv[])
stage = clutter_stage_get_default ();
clutter_ungrab_keyboard ();
clutter_ungrab_pointer ();
#ifdef WIN32
clutter_gl_context = wglGetCurrentContext ();
clutter_dc = wglGetCurrentDC ();
@ -220,11 +237,11 @@ main (int argc, char *argv[])
/* play pipeline */
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
state = GST_STATE_PLAYING;
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
state = GST_STATE_PAUSED;
if (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,
GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
g_debug ("failed to play pipeline\n");
g_debug ("failed to pause pipeline\n");
return -1;
}
@ -243,6 +260,12 @@ main (int argc, char *argv[])
clutter_stage_set_title (CLUTTER_STAGE (stage), "clutter and gst-plugins-gl");
clutter_texture = setup_stage (CLUTTER_STAGE (stage));
/* append a gst-gl texture to this queue when you do not need it no more */
queue_buf = g_async_queue_new ();
g_object_set_data (G_OBJECT (clutter_texture), "queue_buf", queue_buf);
g_object_set_data (G_OBJECT (clutter_texture), "gst_gl_buf", NULL);
/* set a callback to retrieve the gst gl textures */
fakesink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink0");
@ -251,10 +274,25 @@ main (int argc, char *argv[])
clutter_texture);
g_object_unref (fakesink);
/* play gst */
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
/* main loop */
clutter_main ();
/* before to deinitialize the gst-gl-opengl context,
* no shared context (here the clutter one) must be current
*/
#ifdef WIN32
wglMakeCurrent (0, 0);
#else
glXMakeCurrent (clutter_display, None, 0);
#endif
clutter_threads_leave ();
/* deinit */
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);