mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
518e8a3fd2
Facilities are given to create fbo's and attach GL memory (renderbuffers or textures). It also keeps track of the renderable size for use with effective use with glViewport().
648 lines
17 KiB
C
648 lines
17 KiB
C
/* GStreamer
|
|
*
|
|
* Copyright (C) 2013 Matthew Waters <ystreet00@gmail.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <gst/check/gstcheck.h>
|
|
|
|
#include <gst/gl/gstglcontext.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
static GstGLDisplay *display;
|
|
|
|
static void
|
|
setup (void)
|
|
{
|
|
display = gst_gl_display_new ();
|
|
}
|
|
|
|
static void
|
|
teardown (void)
|
|
{
|
|
gst_object_unref (display);
|
|
}
|
|
|
|
static GstGLMemory *gl_tex;
|
|
static GLuint vbo, vbo_indices, vao;
|
|
static GstGLFramebuffer *fbo;
|
|
static GstGLShader *shader;
|
|
static GLint shader_attr_position_loc;
|
|
static GLint shader_attr_texture_loc;
|
|
|
|
static const GLfloat vertices[] = {
|
|
/* x, y, z, s, t */
|
|
1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
|
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
|
|
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
|
1.0f, -1.0f, 0.0f, 1.0f, 1.0f
|
|
};
|
|
|
|
static const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
|
|
|
|
static void
|
|
init (gpointer data)
|
|
{
|
|
GstGLContext *context = data;
|
|
GError *error = NULL;
|
|
GstVideoInfo v_info;
|
|
GstGLMemoryAllocator *allocator;
|
|
GstGLVideoAllocationParams *params;
|
|
|
|
gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 320, 240);
|
|
allocator = gst_gl_memory_allocator_get_default (context);
|
|
params =
|
|
gst_gl_video_allocation_params_new (context, NULL, &v_info, 0, NULL,
|
|
GST_GL_TEXTURE_TARGET_2D, GST_VIDEO_GL_TEXTURE_TYPE_RGBA);
|
|
|
|
/* has to be called in the thread that is going to use the framebuffer */
|
|
fbo = gst_gl_framebuffer_new_with_default_depth (context, 320, 240);
|
|
|
|
fail_if (fbo == NULL, "failed to create framebuffer object");
|
|
|
|
gl_tex =
|
|
(GstGLMemory *) gst_gl_base_memory_alloc ((GstGLBaseMemoryAllocator *)
|
|
allocator, (GstGLAllocationParams *) params);
|
|
gst_object_unref (allocator);
|
|
gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
|
|
fail_if (gl_tex == NULL, "failed to create texture");
|
|
|
|
shader = gst_gl_shader_new_default (context, &error);
|
|
fail_if (shader == NULL, "failed to create shader object: %s",
|
|
error->message);
|
|
|
|
shader_attr_position_loc =
|
|
gst_gl_shader_get_attribute_location (shader, "a_position");
|
|
shader_attr_texture_loc =
|
|
gst_gl_shader_get_attribute_location (shader, "a_texcoord");
|
|
}
|
|
|
|
static void
|
|
deinit (gpointer data)
|
|
{
|
|
GstGLContext *context = data;
|
|
GstGLFuncs *gl = context->gl_vtable;
|
|
if (vao)
|
|
gl->DeleteVertexArrays (1, &vao);
|
|
gst_object_unref (fbo);
|
|
gst_object_unref (shader);
|
|
gst_memory_unref (GST_MEMORY_CAST (gl_tex));
|
|
}
|
|
|
|
static gboolean
|
|
clear_tex (gpointer data)
|
|
{
|
|
GstGLContext *context = data;
|
|
GstGLFuncs *gl = context->gl_vtable;
|
|
static gfloat r = 0.0, g = 0.0, b = 0.0;
|
|
|
|
gl->ClearColor (r, g, b, 1.0);
|
|
gl->Clear (GL_COLOR_BUFFER_BIT);
|
|
|
|
r = r > 1.0 ? 0.0 : r + 0.03;
|
|
g = g > 1.0 ? 0.0 : g + 0.01;
|
|
b = b > 1.0 ? 0.0 : b + 0.015;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
draw_tex (gpointer data)
|
|
{
|
|
gst_gl_framebuffer_draw_to_texture (fbo, gl_tex,
|
|
(GstGLFramebufferFunc) clear_tex, data);
|
|
}
|
|
|
|
static void
|
|
_bind_buffer (GstGLContext * context)
|
|
{
|
|
const GstGLFuncs *gl = context->gl_vtable;
|
|
|
|
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
|
|
gl->BindBuffer (GL_ARRAY_BUFFER, vbo);
|
|
|
|
/* Load the vertex position */
|
|
gl->VertexAttribPointer (shader_attr_position_loc, 3, GL_FLOAT, GL_FALSE,
|
|
5 * sizeof (GLfloat), (void *) 0);
|
|
|
|
/* Load the texture coordinate */
|
|
gl->VertexAttribPointer (shader_attr_texture_loc, 2, GL_FLOAT, GL_FALSE,
|
|
5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));
|
|
|
|
gl->EnableVertexAttribArray (shader_attr_position_loc);
|
|
gl->EnableVertexAttribArray (shader_attr_texture_loc);
|
|
}
|
|
|
|
static void
|
|
_unbind_buffer (GstGLContext * context)
|
|
{
|
|
const GstGLFuncs *gl = context->gl_vtable;
|
|
|
|
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
gl->BindBuffer (GL_ARRAY_BUFFER, 0);
|
|
|
|
gl->DisableVertexAttribArray (shader_attr_position_loc);
|
|
gl->DisableVertexAttribArray (shader_attr_texture_loc);
|
|
}
|
|
|
|
static void
|
|
init_blit (gpointer data)
|
|
{
|
|
GstGLContext *context = data;
|
|
const GstGLFuncs *gl = context->gl_vtable;
|
|
|
|
if (!vbo) {
|
|
if (gl->GenVertexArrays) {
|
|
gl->GenVertexArrays (1, &vao);
|
|
gl->BindVertexArray (vao);
|
|
}
|
|
|
|
gl->GenBuffers (1, &vbo);
|
|
gl->BindBuffer (GL_ARRAY_BUFFER, vbo);
|
|
gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices,
|
|
GL_STATIC_DRAW);
|
|
|
|
gl->GenBuffers (1, &vbo_indices);
|
|
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
|
|
gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices,
|
|
GL_STATIC_DRAW);
|
|
|
|
if (gl->GenVertexArrays) {
|
|
_bind_buffer (context);
|
|
gl->BindVertexArray (0);
|
|
}
|
|
|
|
gl->BindBuffer (GL_ARRAY_BUFFER, 0);
|
|
gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
deinit_blit (gpointer data)
|
|
{
|
|
GstGLContext *context = data;
|
|
const GstGLFuncs *gl = context->gl_vtable;
|
|
|
|
if (vbo)
|
|
gl->DeleteBuffers (1, &vbo);
|
|
vbo = 0;
|
|
if (vbo_indices)
|
|
gl->DeleteBuffers (1, &vbo_indices);
|
|
vbo_indices = 0;
|
|
if (vao)
|
|
gl->DeleteVertexArrays (1, &vao);
|
|
vao = 0;
|
|
}
|
|
|
|
static void
|
|
draw_render (gpointer data)
|
|
{
|
|
GstGLContext *context = data;
|
|
GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
|
const GstGLFuncs *gl = context->gl_vtable;
|
|
|
|
gl->Clear (GL_COLOR_BUFFER_BIT);
|
|
|
|
gst_gl_shader_use (shader);
|
|
|
|
gl->ActiveTexture (GL_TEXTURE0);
|
|
gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (gl_tex));
|
|
gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
|
|
|
|
if (gl->GenVertexArrays)
|
|
gl->BindVertexArray (vao);
|
|
else
|
|
_bind_buffer (context);
|
|
|
|
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
|
|
|
if (gl->GenVertexArrays)
|
|
gl->BindVertexArray (0);
|
|
else
|
|
_unbind_buffer (context);
|
|
|
|
context_class->swap_buffers (context);
|
|
}
|
|
|
|
GST_START_TEST (test_share)
|
|
{
|
|
GstGLContext *context;
|
|
GstGLWindow *window;
|
|
GstGLContext *other_context;
|
|
GstGLWindow *other_window;
|
|
GError *error = NULL;
|
|
gint i = 0;
|
|
|
|
context = gst_gl_context_new (display);
|
|
|
|
window = gst_gl_window_new (display);
|
|
gst_gl_context_set_window (context, window);
|
|
|
|
gst_gl_context_create (context, 0, &error);
|
|
|
|
fail_if (error != NULL, "Error creating master context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
other_window = gst_gl_window_new (display);
|
|
|
|
other_context = gst_gl_context_new (display);
|
|
gst_gl_context_set_window (other_context, other_window);
|
|
|
|
gst_gl_context_create (other_context, context, &error);
|
|
|
|
fail_if (error != NULL, "Error creating secondary context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
/* make the window visible */
|
|
gst_gl_window_set_preferred_size (window, 320, 240);
|
|
gst_gl_window_draw (window);
|
|
|
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (init),
|
|
other_context);
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init_blit), context);
|
|
|
|
while (i < 10) {
|
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (draw_tex),
|
|
context);
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
|
|
context);
|
|
i++;
|
|
}
|
|
|
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit),
|
|
other_context);
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit_blit), context);
|
|
|
|
gst_object_unref (window);
|
|
gst_object_unref (other_window);
|
|
gst_object_unref (other_context);
|
|
gst_object_unref (context);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static void
|
|
accum_true (GstGLContext * context, gpointer data)
|
|
{
|
|
gint *i = data;
|
|
*i = 1;
|
|
}
|
|
|
|
static void
|
|
check_wrapped (gpointer data)
|
|
{
|
|
GstGLContext *wrapped_context = data;
|
|
GError *error = NULL;
|
|
gint i = 0;
|
|
gboolean ret;
|
|
|
|
/* check that scheduling on an unactivated wrapped context asserts */
|
|
ASSERT_CRITICAL (gst_gl_context_thread_add (wrapped_context,
|
|
(GstGLContextThreadFunc) accum_true, &i));
|
|
fail_if (i != 0);
|
|
|
|
/* check that scheduling on an activated context succeeds */
|
|
gst_gl_context_activate (wrapped_context, TRUE);
|
|
gst_gl_context_thread_add (wrapped_context,
|
|
(GstGLContextThreadFunc) accum_true, &i);
|
|
fail_if (i != 1);
|
|
|
|
/* check filling out the wrapped context's info */
|
|
fail_if (wrapped_context->gl_vtable->TexImage2D != NULL);
|
|
ret = gst_gl_context_fill_info (wrapped_context, &error);
|
|
fail_if (!ret, "error received %s\n",
|
|
error ? error->message : "Unknown error");
|
|
fail_if (wrapped_context->gl_vtable->TexImage2D == NULL);
|
|
gst_gl_context_activate (wrapped_context, FALSE);
|
|
}
|
|
|
|
GST_START_TEST (test_wrapped_context)
|
|
{
|
|
GstGLContext *context, *other_context, *wrapped_context;
|
|
GstGLWindow *window, *other_window;
|
|
GError *error = NULL;
|
|
gint i = 0;
|
|
guintptr handle, handle2;
|
|
GstGLPlatform platform, platform2;
|
|
GstGLAPI apis, apis2;
|
|
|
|
context = gst_gl_context_new (display);
|
|
|
|
window = gst_gl_window_new (display);
|
|
gst_gl_context_set_window (context, window);
|
|
|
|
gst_gl_context_create (context, 0, &error);
|
|
|
|
fail_if (error != NULL, "Error creating master context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
handle = gst_gl_context_get_gl_context (context);
|
|
platform = gst_gl_context_get_gl_platform (context);
|
|
apis = gst_gl_context_get_gl_api (context);
|
|
|
|
wrapped_context =
|
|
gst_gl_context_new_wrapped (display, handle, platform, apis);
|
|
|
|
handle2 = gst_gl_context_get_gl_context (wrapped_context);
|
|
platform2 = gst_gl_context_get_gl_platform (wrapped_context);
|
|
apis2 = gst_gl_context_get_gl_api (wrapped_context);
|
|
|
|
fail_if (handle != handle2);
|
|
fail_if (platform != platform2);
|
|
fail_if (apis != apis2);
|
|
|
|
other_context = gst_gl_context_new (display);
|
|
other_window = gst_gl_window_new (display);
|
|
gst_gl_context_set_window (other_context, other_window);
|
|
|
|
gst_gl_context_create (other_context, wrapped_context, &error);
|
|
|
|
fail_if (error != NULL, "Error creating secondary context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
/* make the window visible */
|
|
gst_gl_window_set_preferred_size (window, 320, 240);
|
|
gst_gl_window_draw (window);
|
|
|
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (init),
|
|
other_context);
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init_blit), context);
|
|
|
|
while (i < 10) {
|
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (draw_tex),
|
|
context);
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
|
|
context);
|
|
i++;
|
|
}
|
|
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (check_wrapped),
|
|
wrapped_context);
|
|
|
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit),
|
|
other_context);
|
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit_blit), context);
|
|
|
|
gst_object_unref (other_context);
|
|
gst_object_unref (other_window);
|
|
gst_object_unref (window);
|
|
gst_object_unref (context);
|
|
gst_object_unref (wrapped_context);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
struct context_info
|
|
{
|
|
GstGLAPI api;
|
|
guint major;
|
|
guint minor;
|
|
GstGLPlatform platform;
|
|
guintptr handle;
|
|
};
|
|
|
|
static void
|
|
_fill_context_info (GstGLContext * context, struct context_info *info)
|
|
{
|
|
info->handle = gst_gl_context_get_current_gl_context (info->platform);
|
|
info->api =
|
|
gst_gl_context_get_current_gl_api (info->platform, &info->major,
|
|
&info->minor);
|
|
}
|
|
|
|
GST_START_TEST (test_current_context)
|
|
{
|
|
GstGLContext *context;
|
|
GError *error = NULL;
|
|
guintptr handle;
|
|
GstGLPlatform platform;
|
|
GstGLAPI api;
|
|
gint major, minor;
|
|
struct context_info info;
|
|
|
|
context = gst_gl_context_new (display);
|
|
|
|
gst_gl_context_create (context, 0, &error);
|
|
|
|
fail_if (error != NULL, "Error creating master context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
handle = gst_gl_context_get_gl_context (context);
|
|
platform = gst_gl_context_get_gl_platform (context);
|
|
api = gst_gl_context_get_gl_api (context);
|
|
gst_gl_context_get_gl_version (context, &major, &minor);
|
|
|
|
info.platform = platform;
|
|
|
|
gst_gl_context_thread_add (context,
|
|
(GstGLContextThreadFunc) _fill_context_info, &info);
|
|
|
|
fail_if (info.platform != platform);
|
|
fail_if (info.api != api);
|
|
fail_if (info.major != major);
|
|
fail_if (info.minor != minor);
|
|
fail_if (info.handle != handle);
|
|
|
|
gst_object_unref (context);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_context_can_share)
|
|
{
|
|
GstGLContext *c1, *c2, *c3;
|
|
GError *error = NULL;
|
|
|
|
c1 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c1, NULL, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
c2 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c2, c1, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
fail_unless (gst_gl_context_can_share (c1, c2));
|
|
fail_unless (gst_gl_context_can_share (c2, c1));
|
|
|
|
c3 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c3, c2, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
fail_unless (gst_gl_context_can_share (c1, c3));
|
|
fail_unless (gst_gl_context_can_share (c3, c1));
|
|
fail_unless (gst_gl_context_can_share (c2, c3));
|
|
fail_unless (gst_gl_context_can_share (c3, c2));
|
|
|
|
/* destroy the middle context */
|
|
gst_object_unref (c2);
|
|
c2 = NULL;
|
|
|
|
fail_unless (gst_gl_context_can_share (c1, c3));
|
|
fail_unless (gst_gl_context_can_share (c3, c1));
|
|
|
|
gst_object_unref (c1);
|
|
gst_object_unref (c3);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_is_shared)
|
|
{
|
|
GstGLContext *c1, *c2;
|
|
GError *error = NULL;
|
|
|
|
c1 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c1, NULL, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
c2 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c2, c1, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
fail_unless (gst_gl_context_is_shared (c1));
|
|
fail_unless (gst_gl_context_is_shared (c2));
|
|
|
|
gst_object_unref (c2);
|
|
c2 = NULL;
|
|
|
|
fail_unless (!gst_gl_context_is_shared (c1));
|
|
|
|
gst_object_unref (c1);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_display_list)
|
|
{
|
|
GstGLContext *c1, *c2;
|
|
GError *error = NULL;
|
|
|
|
c1 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c1, NULL, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
GST_OBJECT_LOCK (display);
|
|
{
|
|
/* no context added so get should return NULL */
|
|
GstGLContext *tmp =
|
|
gst_gl_display_get_gl_context_for_thread (display, NULL);
|
|
fail_unless (tmp == NULL);
|
|
}
|
|
|
|
fail_unless (gst_gl_display_add_context (display, c1));
|
|
/* re-adding the same context is a no-op */
|
|
fail_unless (gst_gl_display_add_context (display, c1));
|
|
|
|
{
|
|
GThread *thread;
|
|
GstGLContext *tmp;
|
|
|
|
thread = gst_gl_context_get_thread (c1);
|
|
fail_unless (thread != NULL);
|
|
|
|
tmp = gst_gl_display_get_gl_context_for_thread (display, thread);
|
|
fail_unless (tmp == c1);
|
|
g_thread_unref (thread);
|
|
gst_object_unref (tmp);
|
|
|
|
tmp = gst_gl_display_get_gl_context_for_thread (display, NULL);
|
|
fail_unless (tmp == c1);
|
|
gst_object_unref (tmp);
|
|
}
|
|
|
|
c2 = gst_gl_context_new (display);
|
|
gst_gl_context_create (c2, c1, &error);
|
|
fail_if (error != NULL, "Error creating context %s\n",
|
|
error ? error->message : "Unknown Error");
|
|
|
|
fail_unless (gst_gl_display_add_context (display, c2));
|
|
/* re-adding the same context is a no-op */
|
|
fail_unless (gst_gl_display_add_context (display, c2));
|
|
|
|
{
|
|
GThread *thread;
|
|
GstGLContext *tmp;
|
|
|
|
thread = gst_gl_context_get_thread (c2);
|
|
fail_unless (thread != NULL);
|
|
|
|
tmp = gst_gl_display_get_gl_context_for_thread (display, thread);
|
|
fail_unless (tmp == c2);
|
|
g_thread_unref (thread);
|
|
gst_object_unref (tmp);
|
|
|
|
/* undefined which context will be returned for the NULL thread */
|
|
tmp = gst_gl_display_get_gl_context_for_thread (display, NULL);
|
|
fail_unless (tmp != NULL);
|
|
gst_object_unref (tmp);
|
|
}
|
|
|
|
gst_object_unref (c1);
|
|
/* c1 is now dead */
|
|
|
|
{
|
|
GstGLContext *tmp;
|
|
|
|
tmp = gst_gl_display_get_gl_context_for_thread (display, NULL);
|
|
fail_unless (tmp == c2);
|
|
gst_object_unref (tmp);
|
|
}
|
|
GST_OBJECT_UNLOCK (display);
|
|
|
|
gst_object_unref (c2);
|
|
/* c2 is now dead */
|
|
|
|
{
|
|
/* no more contexts alive */
|
|
GstGLContext *tmp =
|
|
gst_gl_display_get_gl_context_for_thread (display, NULL);
|
|
fail_unless (tmp == NULL);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static Suite *
|
|
gst_gl_context_suite (void)
|
|
{
|
|
Suite *s = suite_create ("GstGLContext");
|
|
TCase *tc_chain = tcase_create ("general");
|
|
|
|
suite_add_tcase (s, tc_chain);
|
|
tcase_add_checked_fixture (tc_chain, setup, teardown);
|
|
tcase_add_test (tc_chain, test_share);
|
|
tcase_add_test (tc_chain, test_wrapped_context);
|
|
tcase_add_test (tc_chain, test_current_context);
|
|
tcase_add_test (tc_chain, test_context_can_share);
|
|
tcase_add_test (tc_chain, test_is_shared);
|
|
tcase_add_test (tc_chain, test_display_list);
|
|
|
|
return s;
|
|
}
|
|
|
|
GST_CHECK_MAIN (gst_gl_context);
|