From cc8e54541b8cb9fab64b1f42bd8a2b061131e4e6 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Thu, 6 Dec 2012 18:40:26 +1100 Subject: [PATCH] [624/906] OPENGL_ES2 => HAVE_GLES2 and add HAVE_OPENGL use GstGLAPI to determine which code paths to execute. perform some cleanups --- gst-libs/gst/gl/Makefile.am | 3 +- gst-libs/gst/gl/gstgldisplay.c | 874 +++++++++++++------- gst-libs/gst/gl/gstgldisplay.h | 29 +- gst-libs/gst/gl/gstgldownload.c | 807 +++++++++++------- gst-libs/gst/gl/gstgldownload.h | 13 +- gst-libs/gst/gl/gstglfilter.c | 7 +- gst-libs/gst/gl/gstglfilter.h | 4 +- gst-libs/gst/gl/gstglmemory.c | 37 +- gst-libs/gst/gl/gstglshader.c | 172 ++-- gst-libs/gst/gl/gstglshader.h | 107 ++- gst-libs/gst/gl/gstglshadervariables.c | 27 +- gst-libs/gst/gl/gstglupload.c | 814 +++++++++++------- gst-libs/gst/gl/gstglupload.h | 13 +- gst/gl/Makefile.am | 2 +- gst/gl/effects/gstgleffectbulge.c | 2 +- gst/gl/effects/gstgleffectfisheye.c | 2 +- gst/gl/effects/gstgleffectglow.c | 8 +- gst/gl/effects/gstgleffectidentity.c | 76 +- gst/gl/effects/gstgleffectlumatocurve.c | 2 +- gst/gl/effects/gstgleffectmirror.c | 86 +- gst/gl/effects/gstgleffectrgbtocurve.c | 2 +- gst/gl/effects/gstgleffectsin.c | 2 +- gst/gl/effects/gstgleffectsquare.c | 2 +- gst/gl/effects/gstgleffectsqueeze.c | 88 +- gst/gl/effects/gstgleffectssources.c | 44 +- gst/gl/effects/gstgleffectssources.h | 14 +- gst/gl/effects/gstgleffectstretch.c | 2 +- gst/gl/effects/gstgleffecttunnel.c | 2 +- gst/gl/effects/gstgleffecttwirl.c | 2 +- gst/gl/effects/gstgleffectxray.c | 14 +- gst/gl/gltestsrc.c | 207 ++--- gst/gl/gstgldifferencematte.c | 2 +- gst/gl/gstgleffects.c | 147 ++-- gst/gl/gstgleffects.h | 2 +- gst/gl/gstglfiltercube.c | 116 ++- gst/gl/gstglfiltercube.h | 6 +- gst/gl/gstopengl.c | 24 +- tests/check/pipelines/simple-launch-lines.c | 8 +- 38 files changed, 2283 insertions(+), 1486 deletions(-) diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am index a59b8dd4c45..946d7c110dd 100644 --- a/gst-libs/gst/gl/Makefile.am +++ b/gst-libs/gst/gl/Makefile.am @@ -55,7 +55,8 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \ gstglshadervariables.h \ gstglshader.h \ gstgldownload.h \ - gstglupload.h + gstglupload.h \ + gstglapi.h libgstgl_@GST_API_VERSION@_la_CFLAGS = \ $(GL_CFLAGS) \ diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index afd4a50a6cc..673a3b54de4 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -42,14 +42,11 @@ #define GLEW_VERSION_MINOR 0 #endif -/* - * gst-launch-0.10 --gst-debug=gldisplay:N pipeline - * N=1: errors - * N=2: errors warnings - * N=3: errors warnings infos - * N=4: errors warnings infos - * N=5: errors warnings infos logs - */ +#define USING_OPENGL(display) (display->gl_api & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (display->gl_api & GST_GL_API_OPENGL3) +#define USING_GLES(display) (display->gl_api & GST_GL_API_GLES) +#define USING_GLES2(display) (display->gl_api & GST_GL_API_GLES2) +#define USING_GLES3(display) (display->gl_api & GST_GL_API_GLES3) GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug); #define GST_CAT_DEFAULT gst_gl_display_debug @@ -59,13 +56,17 @@ GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug); G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, G_TYPE_OBJECT, DEBUG_INIT); + +#define GST_GL_DISPLAY_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_DISPLAY, GstGLDisplayPrivate)) + static void gst_gl_display_finalize (GObject * object); /* Called in the gl thread, protected by lock and unlock */ gpointer gst_gl_display_thread_create_context (GstGLDisplay * display); void gst_gl_display_thread_destroy_context (GstGLDisplay * display); void gst_gl_display_thread_run_generic (GstGLDisplay * display); -#ifdef OPENGL_ES2 +#if HAVE_GLES2 void gst_gl_display_thread_init_redisplay (GstGLDisplay * display); #endif void gst_gl_display_thread_gen_fbo (GstGLDisplay * display); @@ -86,12 +87,46 @@ void gst_gl_display_del_texture_thread (GstGLDisplay * display, void gst_gl_display_gen_texture_window_cb (GstGLDisplay * display); -//------------------------------------------------------------ -//---------------------- For klass GstGLDisplay --------------- -//------------------------------------------------------------ +#if HAVE_OPENGL +void _gen_fbo_opengl (GstGLDisplay * display); +void _use_fbo_opengl (GstGLDisplay * display); +void _use_fbo_v2_opengl (GstGLDisplay * display); +void _del_fbo_opengl (GstGLDisplay * display); +void _gen_shader_opengl (GstGLDisplay * display); +void _del_shader_opengl (GstGLDisplay * display); +#endif +#if HAVE_GLES2 +void _gen_fbo_gles2 (GstGLDisplay * display); +void _use_fbo_gles2 (GstGLDisplay * display); +void _use_fbo_v2_gles2 (GstGLDisplay * display); +void _del_fbo_gles2 (GstGLDisplay * display); +void _gen_shader_gles2 (GstGLDisplay * display); +void _del_shader_gles2 (GstGLDisplay * display); +#endif + +typedef struct _GstGLVtable +{ + GstGLWindowCB gen_fbo; + GstGLWindowCB use_fbo; + GstGLWindowCB use_fbo_v2; + GstGLWindowCB del_fbo; + GstGLWindowCB gen_shader; + GstGLWindowCB del_shader; +} GstGLVtable; + +struct _GstGLDisplayPrivate +{ + GstGLVtable vtable; +}; + +/*------------------------------------------------------------ + --------------------- For klass GstGLDisplay --------------- + ----------------------------------------------------------*/ static void gst_gl_display_class_init (GstGLDisplayClass * klass) { + g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate)); + G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize; } @@ -99,52 +134,54 @@ gst_gl_display_class_init (GstGLDisplayClass * klass) static void gst_gl_display_init (GstGLDisplay * display) { - //thread safe + display->priv = GST_GL_DISPLAY_GET_PRIVATE (display); + + /* thread safe */ display->mutex = g_mutex_new (); - //gl context + /* gl context */ display->gl_thread = NULL; display->gl_window = NULL; display->isAlive = TRUE; - //conditions + /* conditions */ display->cond_create_context = g_cond_new (); display->cond_destroy_context = g_cond_new (); - //action redisplay + /* action redisplay */ display->redisplay_texture = 0; display->redisplay_texture_width = 0; display->redisplay_texture_height = 0; display->keep_aspect_ratio = FALSE; -#ifdef OPENGL_ES2 +#if HAVE_GLES2 display->redisplay_shader = NULL; display->redisplay_attr_position_loc = 0; display->redisplay_attr_texture_loc = 0; #endif - //action gen and del texture + /* action gen and del texture */ display->gen_texture = 0; display->gen_texture_width = 0; display->gen_texture_height = 0; display->gen_texture_video_format = GST_VIDEO_FORMAT_UNKNOWN; - //client callbacks + /* client callbacks */ display->clientReshapeCallback = NULL; display->clientDrawCallback = NULL; display->client_data = NULL; display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_GLSL; - //foreign gl context + /* foreign gl context */ display->external_gl_context = 0; - //filter gen fbo + /* filter gen fbo */ display->gen_fbo_width = 0; display->gen_fbo_height = 0; display->generated_fbo = 0; display->generated_depth_buffer = 0; - //filter use fbo + /* filter use fbo */ display->use_fbo = 0; display->use_depth_buffer = 0; display->use_fbo_texture = 0; @@ -162,11 +199,11 @@ gst_gl_display_init (GstGLDisplay * display) display->input_texture_height = 0; display->input_texture = 0; - //filter del fbo + /* filter del fbo */ display->del_fbo = 0; display->del_depth_buffer = 0; - //action gen and del shader + /* action gen and del shader */ display->gen_shader_fragment_source = NULL; display->gen_shader_vertex_source = NULL; display->gen_shader = NULL; @@ -175,17 +212,19 @@ gst_gl_display_init (GstGLDisplay * display) display->uploads = NULL; display->downloads = NULL; -#ifdef OPENGL_ES2 - display->redisplay_vertex_shader_str = +#if HAVE_GLES2 +/* *INDENT-OFF* */ + display->redisplay_vertex_shader_str_gles2 = "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 v_texCoord; \n" "void main() \n" "{ \n" " gl_Position = a_position; \n" - " v_texCoord = a_texCoord; \n" "} \n"; + " v_texCoord = a_texCoord; \n" + "} \n"; - display->redisplay_fragment_shader_str = + display->redisplay_fragment_shader_str_gles2 = "precision mediump float; \n" "varying vec2 v_texCoord; \n" "uniform sampler2D s_texture; \n" @@ -193,6 +232,7 @@ gst_gl_display_init (GstGLDisplay * display) "{ \n" " gl_FragColor = texture2D( s_texture, v_texCoord );\n" "} \n"; +/* *INDENT_ON* */ #endif display->error_message = NULL; @@ -295,14 +335,124 @@ gst_gl_display_set_error (GstGLDisplay * display, const char *format, ...) display->isAlive = FALSE; } +#if HAVE_GLES2 +static gboolean +_create_context_gles2 (GstGLDisplay * display, gint * gl_major, gint * gl_minor) +{ + GLenum gl_err = GL_NO_ERROR; + + if (glGetString (GL_VERSION)) + GST_INFO ("GL_VERSION: %s", glGetString (GL_VERSION)); + + if (glGetString (GL_SHADING_LANGUAGE_VERSION)) + GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s", + glGetString (GL_SHADING_LANGUAGE_VERSION)); + else + GST_INFO ("Your driver does not support GLSL (OpenGL Shading Language)"); + + if (glGetString (GL_VENDOR)) + GST_INFO ("GL_VENDOR: %s", glGetString (GL_VENDOR)); + + if (glGetString (GL_RENDERER)) + GST_INFO ("GL_RENDERER: %s", glGetString (GL_RENDERER)); + + gl_err = glGetError (); + if (gl_err != GL_NO_ERROR) { + gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err); + } + + if (!GL_ES_VERSION_2_0) + gst_gl_display_set_error (display, "OpenGL|ES >= 2.0 is required"); + + display->priv->vtable.gen_fbo = (GstGLWindowCB) _gen_fbo_gles2; + display->priv->vtable.use_fbo = (GstGLWindowCB) _use_fbo_gles2; + display->priv->vtable.use_fbo_v2 = (GstGLWindowCB) _use_fbo_v2_gles2; + display->priv->vtable.del_fbo = (GstGLWindowCB) _del_fbo_gles2; + display->priv->vtable.gen_shader = (GstGLWindowCB) _gen_shader_gles2; + display->priv->vtable.del_shader = (GstGLWindowCB) _del_shader_gles2; + + *gl_major = 2; + *gl_minor = 0; + + return TRUE; +} +#endif + +#if HAVE_OPENGL +gboolean +_create_context_opengl (GstGLDisplay * display, gint * gl_major, gint * gl_minor) +{ + GLenum err = GLEW_OK; + GLenum gl_err = GL_NO_ERROR; + GString *opengl_version = NULL; + + if (glewInit () != GLEW_OK) { + gst_gl_display_set_error (display, "Failed to init GLEW: %s", + glewGetErrorString (err)); + return TRUE; + } + + /* OpenGL > 1.2.0 and Glew > 1.4.0 */ + if (glGetString (GL_VERSION)) + GST_INFO ("GL_VERSION: %s", glGetString (GL_VERSION)); + + GST_INFO ("GLEW_VERSION: %s", glewGetString (GLEW_VERSION)); + + if (glGetString (GL_SHADING_LANGUAGE_VERSION)) + GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s", + glGetString (GL_SHADING_LANGUAGE_VERSION)); + else + GST_INFO ("Your driver does not support GLSL (OpenGL Shading Language)"); + + if (glGetString (GL_VENDOR)) + GST_INFO ("GL_VENDOR: %s", glGetString (GL_VENDOR)); + + if (glGetString (GL_RENDERER)) + GST_INFO ("GL_RENDERER: %s", glGetString (GL_RENDERER)); + + gl_err = glGetError (); + if (gl_err != GL_NO_ERROR) { + gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err); + } + if (glGetString (GL_VERSION)) { + opengl_version = + g_string_truncate (g_string_new ((gchar *) glGetString (GL_VERSION)), 3); + + sscanf (opengl_version->str, "%d.%d", gl_major, gl_minor); + + g_string_free (opengl_version, TRUE); + + if ((*gl_major < 1) || + (GLEW_VERSION_MAJOR < 1) || + (*gl_major < 2 && *gl_major >= 1 + && *gl_minor < 2) || (GLEW_VERSION_MAJOR < 2 + && GLEW_VERSION_MAJOR >= 1 && GLEW_VERSION_MINOR < 4)) { + /* turn off the pipeline, the old drivers are not yet supported */ + gst_gl_display_set_error (display, + "OpenGL >= 1.2.0 and Glew >= 1.4.0 is required"); + } + } + + display->priv->vtable.gen_fbo = (GstGLWindowCB) _gen_fbo_opengl; + display->priv->vtable.use_fbo = (GstGLWindowCB) _use_fbo_opengl; + display->priv->vtable.use_fbo_v2 = (GstGLWindowCB) _use_fbo_v2_opengl; + display->priv->vtable.del_fbo = (GstGLWindowCB) _del_fbo_opengl; + display->priv->vtable.gen_shader = (GstGLWindowCB) _gen_shader_opengl; + display->priv->vtable.del_shader = (GstGLWindowCB) _del_shader_opengl; + + return TRUE; +} +#endif + gpointer gst_gl_display_thread_create_context (GstGLDisplay * display) { - GLenum err = GLEW_OK; + gint gl_major = 0, gl_minor = 0; + gboolean ret = FALSE; gst_gl_display_lock (display); display->gl_window = - gst_gl_window_new (GST_GL_RENDERER_API_ANY, display->external_gl_context); + gst_gl_window_new (GST_GL_API_ANY, display->external_gl_context); if (!display->gl_window) { gst_gl_display_set_error (display, "Failed to create gl window"); @@ -313,76 +463,24 @@ gst_gl_display_thread_create_context (GstGLDisplay * display) GST_INFO ("gl window created"); -#ifndef OPENGL_ES2 - err = glewInit (); + display->gl_api = gst_gl_window_get_gl_api (display->gl_window); + + g_assert (display->gl_api != GST_GL_API_NONE && display->gl_api != GST_GL_API_ANY); + + /* gl api specific code */ +#if HAVE_OPENGL + if (!ret && USING_OPENGL(display)) + ret = _create_context_opengl (display, &gl_major, &gl_minor); #endif - if (err != GLEW_OK) { -#ifndef OPENGL_ES2 - gst_gl_display_set_error (display, "Failed to init GLEW: %s", - glewGetErrorString (err)); -#endif - } else { -#ifndef OPENGL_ES2 - //OpenGL > 1.2.0 and Glew > 1.4.0 - GString *opengl_version = NULL; - gint opengl_version_major = 0; - gint opengl_version_minor = 0; +#if HAVE_GLES2 + if (!ret && USING_GLES2(display)) + ret = _create_context_gles2 (display, &gl_major, &gl_minor); #endif - GLenum gl_err = GL_NO_ERROR; - if (glGetString (GL_VERSION)) - GST_INFO ("GL_VERSION: %s", glGetString (GL_VERSION)); + if (!ret || !gl_major) + gst_gl_display_set_error (display, "failed to create context"); -#ifndef OPENGL_ES2 - GST_INFO ("GLEW_VERSION: %s", glewGetString (GLEW_VERSION)); -#endif - if (glGetString (GL_SHADING_LANGUAGE_VERSION)) - GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s", - glGetString (GL_SHADING_LANGUAGE_VERSION)); - else - GST_INFO ("Your driver does not support GLSL (OpenGL Shading Language)"); - - if (glGetString (GL_VENDOR)) - GST_INFO ("GL_VENDOR: %s", glGetString (GL_VENDOR)); - - if (glGetString (GL_RENDERER)) - GST_INFO ("GL_RENDERER: %s", glGetString (GL_RENDERER)); - - - gl_err = glGetError (); - if (gl_err != GL_NO_ERROR) { - gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err); - } -#ifndef OPENGL_ES2 - if (glGetString (GL_VERSION) && gl_err == GL_NO_ERROR) { - - opengl_version = - g_string_truncate (g_string_new ((gchar *) glGetString (GL_VERSION)), - 3); - - sscanf (opengl_version->str, "%d.%d", &opengl_version_major, - &opengl_version_minor); - - g_string_free (opengl_version, TRUE); - - if ((opengl_version_major < 1) || - (GLEW_VERSION_MAJOR < 1) || - (opengl_version_major < 2 && opengl_version_major >= 1 - && opengl_version_minor < 2) || (GLEW_VERSION_MAJOR < 2 - && GLEW_VERSION_MAJOR >= 1 && GLEW_VERSION_MINOR < 4)) { - //turn off the pipeline, the old drivers are not yet supported - gst_gl_display_set_error (display, - "Required OpenGL >= 1.2.0 and Glew >= 1.4.0"); - } - } -#else - if (!GL_ES_VERSION_2_0) { - gst_gl_display_set_error (display, "Required OpenGL ES > 2.0"); - } -#endif - } - - //setup callbacks + /* setup callbacks */ gst_gl_window_set_resize_callback (display->gl_window, GST_GL_WINDOW_RESIZE_CB (gst_gl_display_on_resize), display); gst_gl_window_set_draw_callback (display->gl_window, @@ -418,7 +516,7 @@ gst_gl_display_thread_create_context (GstGLDisplay * display) void gst_gl_display_thread_destroy_context (GstGLDisplay * display) { -#ifdef OPENGL_ES2 +#if HAVE_GLES2 if (display->redisplay_shader) { g_object_unref (G_OBJECT (display->redisplay_shader)); display->redisplay_shader = NULL; @@ -438,18 +536,18 @@ gst_gl_display_thread_run_generic (GstGLDisplay * display) display->generic_callback (display, display->data); } -#ifdef OPENGL_ES2 +#if HAVE_GLES2 /* Called in the gl thread */ void gst_gl_display_thread_init_redisplay (GstGLDisplay * display) { GError *error = NULL; - display->redisplay_shader = gst_gl_shader_new (); + display->redisplay_shader = gst_gl_shader_new (display); gst_gl_shader_set_vertex_source (display->redisplay_shader, - display->redisplay_vertex_shader_str); + display->redisplay_vertex_shader_str_gles2); gst_gl_shader_set_fragment_source (display->redisplay_shader, - display->redisplay_fragment_shader_str); + display->redisplay_fragment_shader_str_gles2); gst_gl_shader_compile (display->redisplay_shader, &error); if (error) { @@ -468,42 +566,37 @@ gst_gl_display_thread_init_redisplay (GstGLDisplay * display) } #endif -/* Called in the gl thread */ +#if HAVE_OPENGL void -gst_gl_display_thread_gen_fbo (GstGLDisplay * display) +_gen_fbo_opengl (GstGLDisplay * display) { - //a texture must be attached to the FBO + /* a texture must be attached to the FBO */ GLuint fake_texture = 0; GST_TRACE ("creating FBO dimensions:%ux%u", display->gen_fbo_width, display->gen_fbo_height); - //-- generate frame buffer object + /* -- generate frame buffer object */ if (!GLEW_EXT_framebuffer_object) { - //turn off the pipeline because Frame buffer object is a not present - gst_gl_display_set_error (display, + gst_gl_display_set_error (display, "Context, EXT_framebuffer_object not supported"); return; } - //setup FBO + /* setup FBO */ glGenFramebuffersEXT (1, &display->generated_fbo); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->generated_fbo); - //setup the render buffer for depth + /* setup the render buffer for depth */ glGenRenderbuffersEXT (1, &display->generated_depth_buffer); glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, display->generated_depth_buffer); -#ifndef OPENGL_ES2 + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, display->gen_fbo_width, display->gen_fbo_height); glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, display->gen_fbo_width, display->gen_fbo_height); -#else - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, - display->gen_fbo_width, display->gen_fbo_height); -#endif - //setup a texture to render to + /* setup a texture to render to */ glGenTextures (1, &fake_texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fake_texture); glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, @@ -516,38 +609,94 @@ gst_gl_display_thread_gen_fbo (GstGLDisplay * display) glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - //attach the texture to the FBO to renderer to + /* attach the texture to the FBO to renderer to */ glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, fake_texture, 0); - //attach the depth render buffer to the FBO + /* attach the depth render buffer to the FBO */ glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, display->generated_depth_buffer); -#ifndef OPENGL_ES2 - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, display->generated_depth_buffer); -#endif + if (USING_OPENGL(display)) + glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, display->generated_depth_buffer); if (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) gst_gl_display_set_error (display, "GL framebuffer status incomplete"); - //unbind the FBO + /* unbind the FBO */ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); glDeleteTextures (1, &fake_texture); } - - -/* Called in the gl thread */ -void -gst_gl_display_thread_use_fbo (GstGLDisplay * display) -{ -#ifdef OPENGL_ES2 - GLint viewport_dim[4]; #endif +#if HAVE_GLES2 +void +_gen_fbo_gles2 (GstGLDisplay * display) +{ + /* a texture must be attached to the FBO */ + GLuint fake_texture = 0; + + GST_TRACE ("creating FBO dimensions:%ux%u", display->gen_fbo_width, + display->gen_fbo_height); + + /* -- generate frame buffer object */ + + if (!GLEW_EXT_framebuffer_object) { + gst_gl_display_set_error (display, + "Context, EXT_framebuffer_object not supported"); + return; + } + /* setup FBO */ + glGenFramebuffersEXT (1, &display->generated_fbo); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->generated_fbo); + + /* setup the render buffer for depth */ + glGenRenderbuffersEXT (1, &display->generated_depth_buffer); + glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, display->generated_depth_buffer); + + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + display->gen_fbo_width, display->gen_fbo_height); + + /* setup a texture to render to */ + glGenTextures (1, &fake_texture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fake_texture); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, + display->gen_fbo_width, display->gen_fbo_height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, NULL); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + + /* attach the texture to the FBO to renderer to */ + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_RECTANGLE_ARB, fake_texture, 0); + + /* attach the depth render buffer to the FBO */ + glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, display->generated_depth_buffer); + + if (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) != + GL_FRAMEBUFFER_COMPLETE_EXT) + gst_gl_display_set_error (display, "GL framebuffer status incomplete"); + + /* unbind the FBO */ + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); + + glDeleteTextures (1, &fake_texture); +} +#endif + +/* Called in the gl thread */ +#if HAVE_OPENGL +void +_use_fbo_opengl (GstGLDisplay * display) +{ GST_TRACE ("Binding v1 FBO %u dimensions:%ux%u with texture:%u " "dimensions:%ux%u", display->use_fbo, display->use_fbo_width, display->use_fbo_height, display->use_fbo_texture, @@ -555,17 +704,16 @@ gst_gl_display_thread_use_fbo (GstGLDisplay * display) glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->use_fbo); - //setup a texture to render to + /* setup a texture to render to */ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture); - //attach the texture to the FBO to renderer to + /* attach the texture to the FBO to renderer to */ glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture, 0); if (GLEW_ARB_fragment_shader) gst_gl_shader_use (NULL); -#ifndef OPENGL_ES2 glPushAttrib (GL_VIEWPORT_BIT); glMatrixMode (GL_PROJECTION); glPushMatrix (); @@ -589,44 +737,75 @@ gst_gl_display_thread_use_fbo (GstGLDisplay * display) glMatrixMode (GL_MODELVIEW); glPushMatrix (); glLoadIdentity (); -#else // OPENGL_ES2 - glGetIntegerv (GL_VIEWPORT, viewport_dim); -#endif + glViewport (0, 0, display->use_fbo_width, display->use_fbo_height); -#ifndef OPENGL_ES2 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); -#endif glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //the opengl scene + /* the opengl scene */ display->use_fbo_scene_cb (display->input_texture_width, display->input_texture_height, display->input_texture, display->use_fbo_stuff); -#ifndef OPENGL_ES2 glDrawBuffer (GL_NONE); glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); glPopMatrix (); glPopAttrib (); -#else - glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], - viewport_dim[3]); -#endif glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); } +#endif +#if HAVE_GLES2 +void +_use_fbo_gles2 (GstGLDisplay * display) +{ + GLint viewport_dim[4]; + + GST_TRACE ("Binding v1 FBO %u dimensions:%ux%u with texture:%u " + "dimensions:%ux%u", display->use_fbo, display->use_fbo_width, + display->use_fbo_height, display->use_fbo_texture, + display->input_texture_width, display->input_texture_height); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->use_fbo); + + /* setup a texture to render to */ + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture); + + /* attach the texture to the FBO to renderer to */ + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture, 0); + + glGetIntegerv (GL_VIEWPORT, viewport_dim); + + glViewport (0, 0, display->use_fbo_width, display->use_fbo_height); + + glClearColor (0.0, 0.0, 0.0, 0.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* the opengl scene */ + display->use_fbo_scene_cb (display->input_texture_width, + display->input_texture_height, display->input_texture, + display->use_fbo_stuff); + + glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], + viewport_dim[3]); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); +} +#endif /* Called in a gl thread * Need full shader support */ +#if HAVE_OPENGL void -gst_gl_display_thread_use_fbo_v2 (GstGLDisplay * display) +_use_fbo_v2_opengl (GstGLDisplay * display) { GLint viewport_dim[4]; @@ -636,10 +815,10 @@ gst_gl_display_thread_use_fbo_v2 (GstGLDisplay * display) glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->use_fbo); - //setup a texture to render to + /* setup a texture to render to */ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture); - //attach the texture to the FBO to renderer to + /* attach the texture to the FBO to renderer to */ glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture, 0); @@ -647,30 +826,63 @@ gst_gl_display_thread_use_fbo_v2 (GstGLDisplay * display) glViewport (0, 0, display->use_fbo_width, display->use_fbo_height); -#ifndef OPENGL_ES2 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); + + glClearColor (0.0, 0.0, 0.0, 0.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* the opengl scene */ + display->use_fbo_scene_cb_v2 (display->use_fbo_stuff); + + glDrawBuffer (GL_NONE); + + glViewport (viewport_dim[0], viewport_dim[1], + viewport_dim[2], viewport_dim[3]); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); +} #endif +#if HAVE_GLES2 +void +_use_fbo_v2_gles2 (GstGLDisplay * display) +{ + GLint viewport_dim[4]; + + GST_TRACE ("Binding v2 FBO %u dimensions:%ux%u with texture:%u ", + display->use_fbo, display->use_fbo_width, + display->use_fbo_height, display->use_fbo_texture); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->use_fbo); + + /* setup a texture to render to */ + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture); + + /* attach the texture to the FBO to renderer to */ + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_RECTANGLE_ARB, display->use_fbo_texture, 0); + + glGetIntegerv (GL_VIEWPORT, viewport_dim); + + glViewport (0, 0, display->use_fbo_width, display->use_fbo_height); + glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //the opengl scene display->use_fbo_scene_cb_v2 (display->use_fbo_stuff); -#ifndef OPENGL_ES2 - glDrawBuffer (GL_NONE); -#endif - glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], viewport_dim[3]); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); } - +#endif /* Called in the gl thread */ +#if HAVE_OPENGL void -gst_gl_display_thread_del_fbo (GstGLDisplay * display) +_del_fbo_opengl (GstGLDisplay * display) { GST_TRACE ("Deleting FBO %u", display->del_fbo); @@ -683,11 +895,28 @@ gst_gl_display_thread_del_fbo (GstGLDisplay * display) display->del_depth_buffer = 0; } } +#endif +#if HAVE_GLES2 +void +_del_fbo_gles2 (GstGLDisplay * display) +{ + GST_TRACE ("Deleting FBO %u", display->del_fbo); + + if (display->del_fbo) { + glDeleteFramebuffersEXT (1, &display->del_fbo); + display->del_fbo = 0; + } + if (display->del_depth_buffer) { + glDeleteRenderbuffersEXT (1, &display->del_depth_buffer); + display->del_depth_buffer = 0; + } +} +#endif /* Called in the gl thread */ void -gst_gl_display_thread_gen_shader (GstGLDisplay * display) +_gen_shader_opengl (GstGLDisplay * display) { GST_TRACE ("Generating shader %" GST_PTR_FORMAT, display->gen_shader); @@ -696,7 +925,7 @@ gst_gl_display_thread_gen_shader (GstGLDisplay * display) display->gen_shader_fragment_source) { GError *error = NULL; - display->gen_shader = gst_gl_shader_new (); + display->gen_shader = gst_gl_shader_new (display); if (display->gen_shader_vertex_source) gst_gl_shader_set_vertex_source (display->gen_shader, @@ -723,10 +952,49 @@ gst_gl_display_thread_gen_shader (GstGLDisplay * display) } } +#if HAVE_GLES2 +void +_gen_shader_gles2 (GstGLDisplay * display) +{ + GST_TRACE ("Generating shader %" GST_PTR_FORMAT, display->gen_shader); + + if (GLEW_ARB_fragment_shader) { + if (display->gen_shader_vertex_source || + display->gen_shader_fragment_source) { + GError *error = NULL; + + display->gen_shader = gst_gl_shader_new (display); + + if (display->gen_shader_vertex_source) + gst_gl_shader_set_vertex_source (display->gen_shader, + display->gen_shader_vertex_source); + + if (display->gen_shader_fragment_source) + gst_gl_shader_set_fragment_source (display->gen_shader, + display->gen_shader_fragment_source); + + gst_gl_shader_compile (display->gen_shader, &error); + if (error) { + gst_gl_display_set_error (display, "%s", error->message); + g_error_free (error); + error = NULL; + gst_gl_shader_use (NULL); + g_object_unref (G_OBJECT (display->gen_shader)); + display->gen_shader = NULL; + } + } + } else { + gst_gl_display_set_error (display, + "One of the filter required ARB_fragment_shader"); + display->gen_shader = NULL; + } +} +#endif /* Called in the gl thread */ +#if HAVE_OPENGL void -gst_gl_display_thread_del_shader (GstGLDisplay * display) +_del_shader_opengl (GstGLDisplay * display) { GST_TRACE ("Deleting shader %" GST_PTR_FORMAT, display->del_shader); @@ -735,7 +1003,20 @@ gst_gl_display_thread_del_shader (GstGLDisplay * display) display->del_shader = NULL; } } +#endif +#if HAVE_GLES2 +void +_del_shader_gles2 (GstGLDisplay * display) +{ + GST_TRACE ("Deleting shader %" GST_PTR_FORMAT, display->del_shader); + + if (display->del_shader) { + g_object_unref (G_OBJECT (display->del_shader)); + display->del_shader = NULL; + } +} +#endif //------------------------------------------------------------ //------------------ BEGIN GL THREAD ACTIONS ----------------- @@ -776,11 +1057,13 @@ gst_gl_display_on_resize (GstGLDisplay * display, gint width, gint height) } else { glViewport (0, 0, width, height); } -#ifndef OPENGL_ES2 - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - gluOrtho2D (0, width, 0, height); - glMatrixMode (GL_MODELVIEW); +#if HAVE_OPENGL + if (USING_OPENGL(display)) { + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + gluOrtho2D (0, width, 0, height); + glMatrixMode (GL_MODELVIEW); + } #endif } } @@ -789,24 +1072,25 @@ gst_gl_display_on_resize (GstGLDisplay * display, gint width, gint height) void gst_gl_display_on_draw (GstGLDisplay * display) { - //check if tecture is ready for being drawn + /* check if texture is ready for being drawn */ if (!display->redisplay_texture) return; - //opengl scene + /* opengl scene */ GST_TRACE ("on draw"); - //make sure that the environnement is clean + /* make sure that the environnement is clean */ if (display->colorspace_conversion == GST_GL_DISPLAY_CONVERSION_GLSL) glUseProgramObjectARB (0); -#ifndef OPENGL_ES2 - glDisable (GL_TEXTURE_RECTANGLE_ARB); +#if HAVE_OPENGL + if (USING_OPENGL(display)) + glDisable (GL_TEXTURE_RECTANGLE_ARB); #endif glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); - //check if a client draw callback is registered + /* check if a client draw callback is registered */ if (display->clientDrawCallback) { gboolean doRedisplay = display->clientDrawCallback (display->redisplay_texture, @@ -817,79 +1101,80 @@ gst_gl_display_on_draw (GstGLDisplay * display) gst_gl_window_draw_unlocked (display->gl_window, display->redisplay_texture_width, display->redisplay_texture_height); } - //default opengl scene + /* default opengl scene */ else { +#if HAVE_OPENGL + if (USING_OPENGL(display)) { + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -#ifndef OPENGL_ES2 - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->redisplay_texture); + glEnable (GL_TEXTURE_RECTANGLE_ARB); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->redisplay_texture); - glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBegin (GL_QUADS); + /* gst images are top-down while opengl plane is bottom-up */ + glTexCoord2i (display->redisplay_texture_width, 0); + glVertex2f (1.0f, 1.0f); + glTexCoord2i (0, 0); + glVertex2f (-1.0f, 1.0f); + glTexCoord2i (0, display->redisplay_texture_height); + glVertex2f (-1.0f, -1.0f); + glTexCoord2i (display->redisplay_texture_width, + display->redisplay_texture_height); + glVertex2f (1.0f, -1.0f); + /*glTexCoord2i (display->redisplay_texture_width, 0); + glVertex2i (1, -1); + glTexCoord2i (0, 0); + glVertex2f (-1.0f, -1.0f); + glTexCoord2i (0, display->redisplay_texture_height); + glVertex2f (-1.0f, 1.0f); + glTexCoord2i (display->redisplay_texture_width, + display->redisplay_texture_height); + glVertex2f (1.0f, 1.0f); */ + glEnd (); - glBegin (GL_QUADS); - /* gst images are top-down while opengl plane is bottom-up */ - glTexCoord2i (display->redisplay_texture_width, 0); - glVertex2f (1.0f, 1.0f); - glTexCoord2i (0, 0); - glVertex2f (-1.0f, 1.0f); - glTexCoord2i (0, display->redisplay_texture_height); - glVertex2f (-1.0f, -1.0f); - glTexCoord2i (display->redisplay_texture_width, - display->redisplay_texture_height); - glVertex2f (1.0f, -1.0f); - /*glTexCoord2i (display->redisplay_texture_width, 0); - glVertex2i (1, -1); - glTexCoord2i (0, 0); - glVertex2f (-1.0f, -1.0f); - glTexCoord2i (0, display->redisplay_texture_height); - glVertex2f (-1.0f, 1.0f); - glTexCoord2i (display->redisplay_texture_width, - display->redisplay_texture_height); - glVertex2f (1.0f, 1.0f); */ - glEnd (); - - glDisable (GL_TEXTURE_RECTANGLE_ARB); - -#else //OPENGL_ES2 - - const GLfloat vVertices[] = { 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 - }; - - GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; - - glClear (GL_COLOR_BUFFER_BIT); - - gst_gl_shader_use (display->redisplay_shader); - - //Load the vertex position - glVertexAttribPointer (display->redisplay_attr_position_loc, 3, GL_FLOAT, - GL_FALSE, 5 * sizeof (GLfloat), vVertices); - - //Load the texture coordinate - glVertexAttribPointer (display->redisplay_attr_texture_loc, 2, GL_FLOAT, - GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - - glEnableVertexAttribArray (display->redisplay_attr_position_loc); - glEnableVertexAttribArray (display->redisplay_attr_texture_loc); - - glActiveTexture (GL_TEXTURE0); - glBindTexture (GL_TEXTURE_2D, display->redisplay_texture); - gst_gl_shader_set_uniform_1i (display->redisplay_shader, "s_texture", 0); - - glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + } #endif +#if HAVE_GLES2 + if (USING_GLES2(display)) { + const GLfloat vVertices[] = { 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 + }; - } //end default opengl scene + GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; + + glClear (GL_COLOR_BUFFER_BIT); + + gst_gl_shader_use (display->redisplay_shader); + + /* Load the vertex position */ + glVertexAttribPointer (display->redisplay_attr_position_loc, 3, GL_FLOAT, + GL_FALSE, 5 * sizeof (GLfloat), vVertices); + + /* Load the texture coordinate */ + glVertexAttribPointer (display->redisplay_attr_texture_loc, 2, GL_FLOAT, + GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + + glEnableVertexAttribArray (display->redisplay_attr_position_loc); + glEnableVertexAttribArray (display->redisplay_attr_texture_loc); + + glActiveTexture (GL_TEXTURE0); + glBindTexture (GL_TEXTURE_2D, display->redisplay_texture); + gst_gl_shader_set_uniform_1i (display->redisplay_shader, "s_texture", 0); + + glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + } +#endif + } /* end default opengl scene */ } @@ -941,7 +1226,8 @@ gst_gl_display_gen_texture_thread (GstGLDisplay * display, GLuint * pTexture, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; -/* case GST_GL_DISPLAY_CONVERSION_MESA: +#if 0 + case GST_GL_DISPLAY_CONVERSION_MESA: if (display->upload_width != display->upload_data_width || display->upload_height != display->upload_data_height) glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, @@ -949,7 +1235,8 @@ gst_gl_display_gen_texture_thread (GstGLDisplay * display, GLuint * pTexture, else glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); - break;*/ + break; +#endif default: gst_gl_display_set_error (display, "Unknow colorspace conversion %d", display->colorspace_conversion); @@ -962,8 +1249,8 @@ gst_gl_display_gen_texture_thread (GstGLDisplay * display, GLuint * pTexture, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; default: -// gst_gl_display_set_error (display, "Unsupported upload video format %d", -// display->upload_video_format); + gst_gl_display_set_error (display, "Unsupported upload video format %d", + v_format); break; } @@ -984,14 +1271,14 @@ gst_gl_display_del_texture_thread (GstGLDisplay * display, GLuint * pTexture) } -//------------------------------------------------------------ -//--------------------- END PRIVATE ------------------------- -//------------------------------------------------------------ +/*------------------------------------------------------------ + --------------------- END PRIVATE ------------------------- + ----------------------------------------------------------*/ -//------------------------------------------------------------ -//---------------------- BEGIN PUBLIC ------------------------ -//------------------------------------------------------------ +/*------------------------------------------------------------ + --------------------- BEGIN PUBLIC ------------------------- + ----------------------------------------------------------*/ void gst_gl_display_lock (GstGLDisplay * display) @@ -999,7 +1286,6 @@ gst_gl_display_lock (GstGLDisplay * display) g_mutex_lock (display->mutex); } - void gst_gl_display_unlock (GstGLDisplay * display) { @@ -1030,7 +1316,7 @@ gst_gl_display_check_framebuffer_status (void) case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: GST_ERROR ("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); break; -#ifndef OPENGL_ES2 +#if HAVE_OPENGL case GL_FRAMEBUFFER_UNDEFINED: GST_ERROR ("GL_FRAMEBUFFER_UNDEFINED"); break; @@ -1044,7 +1330,7 @@ gst_gl_display_check_framebuffer_status (void) GstGLDisplay * gst_gl_display_new (void) { - return g_object_new (GST_TYPE_GL_DISPLAY, NULL); + return g_object_new (GST_GL_TYPE_DISPLAY, NULL); } @@ -1083,16 +1369,17 @@ gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture, gint gl_width, gint gl_height, gint window_width, gint window_height, gboolean keep_aspect_ratio) { - gboolean isAlive = TRUE; + gboolean isAlive; gst_gl_display_lock (display); - isAlive = display->isAlive; - if (isAlive) { + if (display->isAlive) { -#ifdef OPENGL_ES2 - if (!display->redisplay_shader) { - gst_gl_window_send_message (display->gl_window, +#if HAVE_GLES2 + if (USING_GLES2(display)) { + if (!display->redisplay_shader) { + gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_init_redisplay), display); + } } #endif @@ -1104,8 +1391,8 @@ gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture, display->keep_aspect_ratio = keep_aspect_ratio; if (display->gl_window) gst_gl_window_draw (display->gl_window, window_width, window_height); - isAlive = display->isAlive; } + isAlive = display->isAlive; gst_gl_display_unlock (display); return isAlive; @@ -1167,11 +1454,11 @@ gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height, display->gen_fbo_width = width; display->gen_fbo_height = height; gst_gl_window_send_message (display->gl_window, - GST_GL_WINDOW_CB (gst_gl_display_thread_gen_fbo), display); + GST_GL_WINDOW_CB (display->priv->vtable.gen_fbo), display); *fbo = display->generated_fbo; *depthbuffer = display->generated_depth_buffer; - isAlive = display->isAlive; } + isAlive = display->isAlive; gst_gl_display_unlock (display); return isAlive; @@ -1194,11 +1481,10 @@ gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width, gdouble proj_param2, gdouble proj_param3, gdouble proj_param4, GstGLDisplayProjection projection, gpointer * stuff) { - gboolean isAlive = TRUE; + gboolean isAlive; gst_gl_display_lock (display); - isAlive = display->isAlive; - if (isAlive) { + if (display->isAlive) { display->use_fbo = fbo; display->use_depth_buffer = depth_buffer; display->use_fbo_texture = texture_fbo; @@ -1214,10 +1500,9 @@ gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width, display->input_texture_width = input_texture_width; display->input_texture_height = input_texture_height; display->input_texture = input_texture; - gst_gl_window_send_message (display->gl_window, - GST_GL_WINDOW_CB (gst_gl_display_thread_use_fbo), display); - isAlive = display->isAlive; + gst_gl_window_send_message (display->gl_window, display->priv->vtable.use_fbo, display); } + isAlive = display->isAlive; gst_gl_display_unlock (display); return isAlive; @@ -1228,11 +1513,10 @@ gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width, gint texture_fbo_height, GLuint fbo, GLuint depth_buffer, GLuint texture_fbo, GLCB_V2 cb, gpointer * stuff) { - gboolean isAlive = TRUE; + gboolean isAlive; gst_gl_display_lock (display); - isAlive = display->isAlive; - if (isAlive) { + if (display->isAlive) { display->use_fbo = fbo; display->use_depth_buffer = depth_buffer; display->use_fbo_texture = texture_fbo; @@ -1240,10 +1524,9 @@ gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width, display->use_fbo_height = texture_fbo_height; display->use_fbo_scene_cb_v2 = cb; display->use_fbo_stuff = stuff; - gst_gl_window_send_message (display->gl_window, - GST_GL_WINDOW_CB (gst_gl_display_thread_use_fbo_v2), display); - isAlive = display->isAlive; + gst_gl_window_send_message (display->gl_window, display->priv->vtable.use_fbo_v2, display); } + isAlive = display->isAlive; gst_gl_display_unlock (display); return isAlive; @@ -1254,10 +1537,11 @@ void gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer) { gst_gl_display_lock (display); - display->del_fbo = fbo; - display->del_depth_buffer = depth_buffer; - gst_gl_window_send_message (display->gl_window, - GST_GL_WINDOW_CB (gst_gl_display_thread_del_fbo), display); + if (display->isAlive) { + display->del_fbo = fbo; + display->del_depth_buffer = depth_buffer; + gst_gl_window_send_message (display->gl_window, display->priv->vtable.del_fbo, display); + } gst_gl_display_unlock (display); } @@ -1268,19 +1552,20 @@ gst_gl_display_gen_shader (GstGLDisplay * display, const gchar * shader_vertex_source, const gchar * shader_fragment_source, GstGLShader ** shader) { - gboolean isAlive = FALSE; + gboolean isAlive; gst_gl_display_lock (display); - display->gen_shader_vertex_source = shader_vertex_source; - display->gen_shader_fragment_source = shader_fragment_source; - gst_gl_window_send_message (display->gl_window, - GST_GL_WINDOW_CB (gst_gl_display_thread_gen_shader), display); + if (display->isAlive) { + display->gen_shader_vertex_source = shader_vertex_source; + display->gen_shader_fragment_source = shader_fragment_source; + gst_gl_window_send_message (display->gl_window, display->priv->vtable.gen_shader, display); + if (shader) + *shader = display->gen_shader; + display->gen_shader = NULL; + display->gen_shader_vertex_source = NULL; + display->gen_shader_fragment_source = NULL; + } isAlive = display->isAlive; - if (shader) - *shader = display->gen_shader; - display->gen_shader = NULL; - display->gen_shader_vertex_source = NULL; - display->gen_shader_fragment_source = NULL; gst_gl_display_unlock (display); return isAlive; @@ -1292,9 +1577,10 @@ void gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader) { gst_gl_display_lock (display); - display->del_shader = shader; - gst_gl_window_send_message (display->gl_window, - GST_GL_WINDOW_CB (gst_gl_display_thread_del_shader), display); + if (display->isAlive) { + display->del_shader = shader; + gst_gl_window_send_message (display->gl_window, display->priv->vtable.del_shader, display); + } gst_gl_display_unlock (display); } @@ -1356,6 +1642,24 @@ gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate) gst_gl_display_unlock (display); } +GstGLAPI +gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display) +{ + return display->gl_api; +} + +GstGLAPI +gst_gl_display_get_gl_api (GstGLDisplay * display) +{ + GstGLAPI api; + + gst_gl_display_lock (display); + api = gst_gl_display_get_gl_api_unlocked (display); + gst_gl_display_unlock (display); + + return api; +} + //------------------------------------------------------------ //------------------------ END PUBLIC ------------------------ //------------------------------------------------------------ diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 54b4d5b2da5..313880f85d1 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -25,8 +25,11 @@ #include +typedef struct _GstGLUpload GstGLUpload; +typedef struct _GstGLDownload GstGLDownload; +typedef struct _GstGLShader GstGLShader; + #include "gstglwindow.h" -#include "gstglrenderer.h" #include "gstglshader.h" #include "gstglupload.h" #include "gstgldownload.h" @@ -34,18 +37,19 @@ G_BEGIN_DECLS GType gst_gl_display_get_type (void); -#define GST_TYPE_GL_DISPLAY (gst_gl_display_get_type()) -#define GST_GL_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY,GstGLDisplay)) +#define GST_GL_TYPE_DISPLAY (gst_gl_display_get_type()) +#define GST_GL_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_GL_TYPE_DISPLAY,GstGLDisplay)) #define GST_GL_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_DISPLAY,GstGLDisplayClass)) + (G_TYPE_CHECK_CLASS_CAST((klass),GST_GL_TYPE_DISPLAY,GstGLDisplayClass)) #define GST_IS_GL_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY)) + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_GL_TYPE_DISPLAY)) #define GST_IS_GL_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_DISPLAY)) + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_GL_TYPE_DISPLAY)) #define GST_GL_DISPLAY_CAST(obj) ((GstGLDisplay*)(obj)) typedef struct _GstGLDisplay GstGLDisplay; typedef struct _GstGLDisplayClass GstGLDisplayClass; +typedef struct _GstGLDisplayPrivate GstGLDisplayPrivate; /** * GstGLDisplayConversion: @@ -139,6 +143,9 @@ struct _GstGLDisplay GstGLWindow *gl_window; gboolean isAlive; + /* gl API we are using */ + GstGLAPI gl_api; + /* conditions */ GCond *cond_create_context; GCond *cond_destroy_context; @@ -152,10 +159,10 @@ struct _GstGLDisplay GLuint redisplay_texture_width; GLuint redisplay_texture_height; gboolean keep_aspect_ratio; -#ifdef OPENGL_ES2 +#if HAVE_GLES2 GstGLShader *redisplay_shader; - gchar *redisplay_vertex_shader_str; - gchar *redisplay_fragment_shader_str; + gchar *redisplay_vertex_shader_str_gles2; + gchar *redisplay_fragment_shader_str_gles2; GLint redisplay_attr_position_loc; GLint redisplay_attr_texture_loc; #endif @@ -214,6 +221,8 @@ struct _GstGLDisplay GstGLShader *del_shader; gchar *error_message; + + GstGLDisplayPrivate *priv; }; @@ -277,6 +286,8 @@ void gst_gl_display_check_framebuffer_status (void); void gst_gl_display_lock (GstGLDisplay * display); void gst_gl_display_unlock (GstGLDisplay * display); +GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display); +GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display); G_END_DECLS diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c index 74454d19e8c..87dbb392751 100644 --- a/gst-libs/gst/gl/gstgldownload.c +++ b/gst-libs/gst/gl/gstgldownload.c @@ -43,11 +43,13 @@ * calling thread. */ +#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3) +#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES) +#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2) +#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3) + static void _do_download (GstGLDisplay * display, GstGLDownload * download); -static void _do_download_draw_rgb (GstGLDisplay * display, - GstGLDownload * download); -static void _do_download_draw_yuv (GstGLDisplay * display, - GstGLDownload * download); static void _init_download (GstGLDisplay * display, GstGLDownload * download); static void _init_download_shader (GstGLDisplay * display, GstGLDownload * download); @@ -56,18 +58,29 @@ static gboolean gst_gl_download_perform_with_data_unlocked (GstGLDownload * static gboolean gst_gl_download_perform_with_data_unlocked_thread (GstGLDownload * download, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); +#if HAVE_OPENGL +static void _do_download_draw_rgb_opengl (GstGLDisplay * display, + GstGLDownload * download); +static void _do_download_draw_yuv_opengl (GstGLDisplay * display, + GstGLDownload * download); +#endif +#if HAVE_GLES2 +static void _do_download_draw_rgb_gles2 (GstGLDisplay * display, + GstGLDownload * download); +static void _do_download_draw_yuv_gles2 (GstGLDisplay * display, + GstGLDownload * download); +#endif + +/* *INDENT-OFF* */ + /* YUY2:y2,u,y1,v UYVY:v,y1,u,y2 */ -static gchar *text_shader_download_YUY2_UYVY = -#ifndef OPENGL_ES2 +#if HAVE_OPENGL +static gchar *text_shader_YUY2_UYVY_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" -#else - "precision mediump float;\n" - "varying vec2 v_texCoord;\n" "uniform sampler2D tex;\n" -#endif - "void main(void) {\n" " float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n" -#ifndef OPENGL_ES2 + "void main(void) {\n" + " float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n" " fx = gl_TexCoord[0].x;\n" " fy = gl_TexCoord[0].y;\n" " r=texture2DRect(tex,vec2(fx*2.0,fy)).r;\n" @@ -76,28 +89,18 @@ static gchar *text_shader_download_YUY2_UYVY = " r2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).r;\n" " g2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).g;\n" " b2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).b;\n" -#else - " fx = v_texCoord.x;\n" - " fy = v_texCoord.y;\n" - " r=texture2D(tex,vec2(fx*2.0,fy)).r;\n" - " g=texture2D(tex,vec2(fx*2.0,fy)).g;\n" - " b=texture2D(tex,vec2(fx*2.0,fy)).b;\n" - " r2=texture2D(tex,vec2(fx*2.0+1.0,fy)).r;\n" - " g2=texture2D(tex,vec2(fx*2.0+1.0,fy)).g;\n" - " b2=texture2D(tex,vec2(fx*2.0+1.0,fy)).b;\n" -#endif " y1=0.299011*r + 0.586987*g + 0.114001*b;\n" " y2=0.299011*r2 + 0.586987*g2 + 0.114001*b2;\n" " u=-0.148246*r -0.29102*g + 0.439266*b;\n" " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" " y1=0.858885*y1 + 0.0625;\n" " y2=0.858885*y2 + 0.0625;\n" - " u=u + 0.5;\n" " v=v + 0.5;\n" " gl_FragColor=vec4(%s);\n" "}\n"; + " u=u + 0.5;\n" + " v=v + 0.5;\n" + " gl_FragColor=vec4(%s);\n" + "}\n"; -/* no OpenGL ES 2.0 support because for now it's not possible - * to attach multiple textures to a frame buffer object - */ -static gchar *text_shader_download_I420_YV12 = +static gchar *text_shader_I420_YV12_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" "uniform float w, h;\n" @@ -119,48 +122,91 @@ static gchar *text_shader_download_I420_YV12 = " v=v + 0.5;\n" " gl_FragData[0] = vec4(y, 0.0, 0.0, 1.0);\n" " gl_FragData[1] = vec4(u, 0.0, 0.0, 1.0);\n" - " gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n" "}\n"; + " gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n" + "}\n"; -static gchar *text_shader_download_AYUV = -#ifndef OPENGL_ES2 +static gchar *text_shader_AYUV_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" -#else - "precision mediump float;\n" - "varying vec2 v_texCoord;\n" "uniform sampler2D tex;\n" -#endif - "void main(void) {\n" " float r,g,b,y,u,v;\n" -#ifndef OPENGL_ES2 + "void main(void) {\n" + " float r,g,b,y,u,v;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" " r=texture2DRect(tex,nxy).r;\n" - " g=texture2DRect(tex,nxy).g;\n" " b=texture2DRect(tex,nxy).b;\n" -#else - " vec2 nxy=v_texCoord.xy;\n" - " r=texture2D(tex,nxy).r;\n" - " g=texture2D(tex,nxy).g;\n" " b=texture2D(tex,nxy).b;\n" -#endif + " g=texture2DRect(tex,nxy).g;\n" + " b=texture2DRect(tex,nxy).b;\n" " y=0.299011*r + 0.586987*g + 0.114001*b;\n" " u=-0.148246*r -0.29102*g + 0.439266*b;\n" " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" - " y=0.858885*y + 0.0625;\n" " u=u + 0.5;\n" " v=v + 0.5;\n" -#ifndef OPENGL_ES2 + " y=0.858885*y + 0.0625;\n" + " u=u + 0.5;\n" + " v=v + 0.5;\n" " gl_FragColor=vec4(y,u,v,1.0);\n" -#else - " gl_FragColor=vec4(1.0,y,u,v);\n" -#endif "}\n"; -#ifdef OPENGL_ES2 -static gchar *text_vertex_shader_download = +#define text_vertex_shader_opengl NULL +#endif /* HAVE_OPENGL */ + +#if HAVE_GLES2 +static gchar *text_shader_YUY2_UYVY_gles2 = + "precision mediump float;\n" + "varying vec2 v_texCoord;\n" + "uniform sampler2D tex;\n" + "void main(void) {\n" + " float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n" + " fx = v_texCoord.x;\n" + " fy = v_texCoord.y;\n" + " r=texture2D(tex,vec2(fx*2.0,fy)).r;\n" + " g=texture2D(tex,vec2(fx*2.0,fy)).g;\n" + " b=texture2D(tex,vec2(fx*2.0,fy)).b;\n" + " r2=texture2D(tex,vec2(fx*2.0+1.0,fy)).r;\n" + " g2=texture2D(tex,vec2(fx*2.0+1.0,fy)).g;\n" + " b2=texture2D(tex,vec2(fx*2.0+1.0,fy)).b;\n" + " y1=0.299011*r + 0.586987*g + 0.114001*b;\n" + " y2=0.299011*r2 + 0.586987*g2 + 0.114001*b2;\n" + " u=-0.148246*r -0.29102*g + 0.439266*b;\n" + " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" + " y1=0.858885*y1 + 0.0625;\n" + " y2=0.858885*y2 + 0.0625;\n" + " u=u + 0.5;\n" + " v=v + 0.5;\n" + " gl_FragColor=vec4(%s);\n" + "}\n"; + +/* no OpenGL ES 2.0 support because for now it's not possible + * to attach multiple textures to a frame buffer object + */ +#define text_shader_I420_YV12_gles2 NULL + +static gchar *text_shader_AYUV_gles2 = + "precision mediump float;\n" + "varying vec2 v_texCoord;\n" + "uniform sampler2D tex;\n" + "void main(void) {\n" + " float r,g,b,y,u,v;\n" + " vec2 nxy=v_texCoord.xy;\n" + " r=texture2D(tex,nxy).r;\n" + " g=texture2D(tex,nxy).g;\n" + " b=texture2D(tex,nxy).b;\n" + " y=0.299011*r + 0.586987*g + 0.114001*b;\n" + " u=-0.148246*r -0.29102*g + 0.439266*b;\n" + " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" + " y=0.858885*y + 0.0625;\n" + " u=u + 0.5;\n" + " v=v + 0.5;\n" + " gl_FragColor=vec4(1.0,y,u,v);\n" + "}\n"; + +static gchar *text_vertex_shader_gles2 = "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 v_texCoord; \n" "void main() \n" "{ \n" " gl_Position = a_position; \n" - " v_texCoord = a_texCoord; \n" "} \n"; + " v_texCoord = a_texCoord; \n" + "} \n"; -static gchar *text_fragment_shader_download_RGB = +static gchar *text_shader_RGB_gles2 = "precision mediump float; \n" "varying vec2 v_texCoord; \n" "uniform sampler2D s_texture; \n" @@ -168,7 +214,20 @@ static gchar *text_fragment_shader_download_RGB = "{ \n" " gl_FragColor = texture2D( s_texture, v_texCoord );\n" "} \n"; -#endif +#endif /* HAVE_GLES2 */ + +/* *INDENT-ON* */ + +struct _GstGLDownloadPrivate +{ + const gchar *YUY2_UYVY; + const gchar *I420_YV12; + const gchar *AYUV; + const gchar *vert_shader; + + void (*do_rgb) (GstGLDisplay * display, GstGLDownload * download); + void (*do_yuv) (GstGLDisplay * display, GstGLDownload * download); +}; GST_DEBUG_CATEGORY_STATIC (gst_gl_download_debug); #define GST_CAT_DEFAULT gst_gl_download_debug @@ -186,12 +245,17 @@ static void gst_gl_download_finalize (GObject * object); static void gst_gl_download_class_init (GstGLDownloadClass * klass) { + g_type_class_add_private (klass, sizeof (GstGLDownloadPrivate)); + G_OBJECT_CLASS (klass)->finalize = gst_gl_download_finalize; } static void gst_gl_download_init (GstGLDownload * download) { + + download->priv = GST_GL_DOWNLOAD_GET_PRIVATE (download); + download->display = NULL; g_mutex_init (&download->lock); @@ -201,10 +265,8 @@ gst_gl_download_init (GstGLDownload * download) download->in_texture = 0; download->shader = NULL; -#ifdef OPENGL_ES2 download->shader_attr_position_loc = 0; download->shader_attr_texture_loc = 0; -#endif gst_video_info_init (&download->info); } @@ -219,10 +281,33 @@ GstGLDownload * gst_gl_download_new (GstGLDisplay * display) { GstGLDownload *download; + GstGLDownloadPrivate *priv; download = g_object_new (GST_TYPE_GL_DOWNLOAD, NULL); download->display = g_object_ref (display); + priv = download->priv; + +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + priv->YUY2_UYVY = text_shader_YUY2_UYVY_opengl; + priv->I420_YV12 = text_shader_I420_YV12_opengl; + priv->AYUV = text_shader_AYUV_opengl; + priv->vert_shader = text_vertex_shader_opengl; + priv->do_rgb = _do_download_draw_rgb_opengl; + priv->do_yuv = _do_download_draw_yuv_opengl; + } +#endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + priv->YUY2_UYVY = text_shader_YUY2_UYVY_gles2; + priv->I420_YV12 = text_shader_I420_YV12_gles2; + priv->AYUV = text_shader_AYUV_gles2; + priv->vert_shader = text_vertex_shader_gles2; + priv->do_rgb = _do_download_draw_rgb_gles2; + priv->do_yuv = _do_download_draw_yuv_gles2; + } +#endif return download; } @@ -574,7 +659,7 @@ GstGLDownload * gst_gl_display_find_download_unlocked (GstGLDisplay * display, GstVideoFormat v_format, guint out_width, guint out_height) { - GstGLDownload *ret; + GstGLDownload *ret = NULL; GSList *walk; walk = display->downloads; @@ -641,6 +726,25 @@ _init_download (GstGLDisplay * display, GstGLDownload * download) GST_TRACE ("initializing texture download for format %d", v_format); + if (USING_OPENGL (display)) { + switch (v_format) { + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + goto no_convert; + break; + default: + break; + } + } + switch (v_format) { case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_BGRx: @@ -652,10 +756,6 @@ _init_download (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: - /* color space conversion is not needed */ -#ifndef OPENGL_ES2 - break; -#endif case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_UYVY: case GST_VIDEO_FORMAT_I420: @@ -681,14 +781,19 @@ _init_download (GstGLDisplay * display, GstGLDownload * download) /* setup the render buffer for depth */ glGenRenderbuffersEXT (1, &download->depth_buffer); glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, download->depth_buffer); -#ifndef OPENGL_ES2 - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - out_width, out_height); - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, - out_width, out_height); -#else - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, - out_width, out_height); +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + out_width, out_height); + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, + out_width, out_height); + } +#endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + out_width, out_height); + } #endif /* setup a first texture to render to */ @@ -754,10 +859,12 @@ _init_download (GstGLDisplay * display, GstGLDownload * download) glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, download->depth_buffer); -#ifndef OPENGL_ES2 - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, - download->depth_buffer); +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, + download->depth_buffer); + } #endif gst_gl_display_check_framebuffer_status (); @@ -778,9 +885,38 @@ _init_download (GstGLDisplay * display, GstGLDownload * download) g_assert_not_reached (); } +no_convert: _init_download_shader (display, download); } +static gboolean +_create_shader (GstGLDisplay * display, const gchar * vertex_src, + const gchar * fragment_src, GstGLShader ** out_shader) +{ + GstGLShader *shader; + GError *error; + + g_return_val_if_fail (vertex_src != NULL || fragment_src != NULL, FALSE); + + shader = gst_gl_shader_new (display); + + if (vertex_src) + gst_gl_shader_set_vertex_source (shader, vertex_src); + if (fragment_src) + gst_gl_shader_set_fragment_source (shader, fragment_src); + + if (!gst_gl_shader_compile (shader, &error)) { + gst_gl_display_set_error (display, "%s", error->message); + g_error_free (error); + gst_gl_shader_use (NULL); + g_object_unref (G_OBJECT (shader)); + return FALSE; + } + + *out_shader = shader; + return TRUE; +} + static void _init_download_shader (GstGLDisplay * display, GstGLDownload * download) { @@ -800,32 +936,19 @@ _init_download_shader (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: /* color space conversion is not needed */ -#ifdef OPENGL_ES2 +#if HAVE_GLES2 { - /* glGetTexImage2D not available in OpenGL ES 2.0 */ - GError *error = NULL; - download->shader = gst_gl_shader_new (); - - gst_gl_shader_set_vertex_source (download->shader, - text_vertex_shader_download); - gst_gl_shader_set_fragment_source (download->shader, - text_fragment_shader_download_RGB); - - gst_gl_shader_compile (download->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; - } else { - download->shader_attr_position_loc = - gst_gl_shader_get_attribute_location (download->shader, - "a_position"); - download->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location (download->shader, - "a_texCoord"); + if (USING_GLES2 (display)) { + /* glGetTexImage2D not available in OpenGL ES 2.0 */ + if (_create_shader (display, text_vertex_shader_gles2, + text_shader_RGB_gles2, &download->shader)) { + download->shader_attr_position_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_position"); + download->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_texCoord"); + } } } #endif @@ -837,9 +960,6 @@ _init_download_shader (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_AYUV: /* color space conversion is needed */ { -#ifdef OPENGL_ES2 - GError *error = NULL; -#endif /* check if fragment shader is available, then load them * GLSL is a requirement for download */ @@ -854,132 +974,65 @@ _init_download_shader (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_YUY2: { gchar text_shader_download_YUY2[2048]; + sprintf (text_shader_download_YUY2, - text_shader_download_YUY2_UYVY, "y2,u,y1,v"); + download->priv->YUY2_UYVY, "y2,u,y1,v"); - download->shader = gst_gl_shader_new (); -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (download->shader, - text_shader_download_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for downloading YUY2"); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; + if (_create_shader (display, download->priv->vert_shader, + text_shader_download_YUY2, &download->shader)) { + if (USING_GLES2 (display)) { + download->shader_attr_position_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_position"); + download->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_texCoord"); + } } -#else - gst_gl_shader_set_vertex_source (download->shader, - text_vertex_shader_download); - gst_gl_shader_set_fragment_source (download->shader, - text_shader_download_YUY2); - - gst_gl_shader_compile (download->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; - } else { - download->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (download->shader, "a_position"); - download->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (download->shader, "a_texCoord"); - } -#endif } break; case GST_VIDEO_FORMAT_UYVY: { gchar text_shader_download_UYVY[2048]; + sprintf (text_shader_download_UYVY, - text_shader_download_YUY2_UYVY, "v,y1,u,y2"); + download->priv->YUY2_UYVY, "v,y1,u,y2"); - download->shader = gst_gl_shader_new (); - -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (download->shader, - text_shader_download_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for downloading UYVY"); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; + if (_create_shader (display, download->priv->vert_shader, + text_shader_download_UYVY, &download->shader)) { + if (USING_GLES2 (display)) { + download->shader_attr_position_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_position"); + download->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_texCoord"); + } } -#else - gst_gl_shader_set_vertex_source (download->shader, - text_vertex_shader_download); - gst_gl_shader_set_fragment_source (download->shader, - text_shader_download_UYVY); - - gst_gl_shader_compile (download->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; - } else { - download->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (download->shader, "a_position"); - download->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (download->shader, "a_texCoord"); - } -#endif - } break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - download->shader = gst_gl_shader_new (); - if (!gst_gl_shader_compile_and_check (download->shader, - text_shader_download_I420_YV12, - GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for downloading I420 or YV12"); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; - } + { + _create_shader (display, download->priv->vert_shader, + download->priv->I420_YV12, &download->shader); break; + } case GST_VIDEO_FORMAT_AYUV: - download->shader = gst_gl_shader_new (); - -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (download->shader, - text_shader_download_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for downloading AYUV"); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; + { + if (_create_shader (display, download->priv->vert_shader, + download->priv->AYUV, &download->shader)) { + if (USING_GLES2 (display)) { + download->shader_attr_position_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_position"); + download->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location (download->shader, + "a_texCoord"); + } } -#else - gst_gl_shader_set_vertex_source (download->shader, - text_vertex_shader_download); - gst_gl_shader_set_fragment_source (download->shader, - text_shader_download_AYUV); - - gst_gl_shader_compile (download->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (download->shader)); - download->shader = NULL; - } else { - download->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (download->shader, "a_position"); - download->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (download->shader, "a_texCoord"); - } -#endif break; + } default: gst_gl_display_set_error (display, "Unsupported download video format %d", v_format); @@ -1022,7 +1075,7 @@ _do_download (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: /* color space conversion is not needed */ - _do_download_draw_rgb (display, download); + download->priv->do_rgb (display, download); break; case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_UYVY: @@ -1030,7 +1083,7 @@ _do_download (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_AYUV: /* color space conversion is needed */ - _do_download_draw_yuv (display, download); + download->priv->do_yuv (display, download); break; default: gst_gl_display_set_error (display, "Unsupported download video format %d", @@ -1040,19 +1093,77 @@ _do_download (GstGLDisplay * display, GstGLDownload * download) } } -/* called by _do_download (in the gl thread) */ +#if HAVE_OPENGL static void -_do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) +_do_download_draw_rgb_opengl (GstGLDisplay * display, GstGLDownload * download) { GstVideoFormat v_format; -#ifndef OPENGL_ES2 if (download->display->colorspace_conversion == GST_GL_DISPLAY_CONVERSION_GLSL) glUseProgramObjectARB (0); glEnable (GL_TEXTURE_RECTANGLE_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); + + v_format = GST_VIDEO_INFO_FORMAT (&download->info); + + switch (v_format) { + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_RGBx: + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, + GL_UNSIGNED_BYTE, download->data[0]); + break; + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_ARGB: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8, download->data[0]); #else + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); +#endif /* G_BYTE_ORDER */ + break; + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_BGRA: + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, + GL_UNSIGNED_BYTE, download->data[0]); + break; + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_ABGR: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, + GL_UNSIGNED_INT_8_8_8_8, download->data[0]); +#else + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, + GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); +#endif /* G_BYTE_ORDER */ + break; + case GST_VIDEO_FORMAT_RGB: + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, + GL_UNSIGNED_BYTE, download->data[0]); + break; + case GST_VIDEO_FORMAT_BGR: + glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGR, + GL_UNSIGNED_BYTE, download->data[0]); + break; + default: + gst_gl_display_set_error (display, + "Download video format inconsistency %d", v_format); + g_assert_not_reached (); + break; + } + + glReadBuffer (GL_NONE); + glDisable (GL_TEXTURE_RECTANGLE_ARB); +} +#endif + + +#if HAVE_GLES2 +static void +_do_download_draw_rgb_gles2 (GstGLDisplay * display, GstGLDownload * download) +{ + GstVideoFormat v_format; guint out_width, out_height; const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f, @@ -1094,32 +1205,17 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); glUseProgramObjectARB (0); -#endif v_format = GST_VIDEO_INFO_FORMAT (&download->info); switch (v_format) { case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_RGBx: -#ifndef OPENGL_ES2 - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - GL_UNSIGNED_BYTE, download->data[0]); -#else glReadPixels (0, 0, out_width, out_height, GL_RGBA, GL_UNSIGNED_BYTE, download->data[0]); -#endif break; case GST_VIDEO_FORMAT_xRGB: case GST_VIDEO_FORMAT_ARGB: -#ifndef OPENGL_ES2 -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8, download->data[0]); -#else - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); -#endif /* G_BYTE_ORDER */ -#else /* OPENGL_ES2 */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN glReadPixels (0, 0, out_width, out_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, download->data[0]); @@ -1127,41 +1223,16 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) glReadPixels (0, 0, out_width, out_eight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); #endif /* G_BYTE_ORDER */ -#endif /* !OPENGL_ES2 */ + break; + case GST_VIDEO_FORMAT_RGB: + glReadPixels (0, 0, out_width, out_height, GL_RGB, GL_UNSIGNED_BYTE, + download->data[0]); break; case GST_VIDEO_FORMAT_BGRx: case GST_VIDEO_FORMAT_BGRA: -#ifndef OPENGL_ES2 - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, - GL_UNSIGNED_BYTE, download->data[0]); -#endif - break; case GST_VIDEO_FORMAT_xBGR: case GST_VIDEO_FORMAT_ABGR: -#ifndef OPENGL_ES2 -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - GL_UNSIGNED_INT_8_8_8_8, download->data[0]); -#else - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); -#endif /* G_BYTE_ORDER */ -#endif /* !OPENGL_ES2 */ - break; - case GST_VIDEO_FORMAT_RGB: -#ifndef OPENGL_ES2 - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, - GL_UNSIGNED_BYTE, download->data[0]); -#else - glReadPixels (0, 0, out_width, out_height, GL_RGB, GL_UNSIGNED_BYTE, - download->data[0]); -#endif - break; case GST_VIDEO_FORMAT_BGR: -#ifndef OPENGL_ES2 - glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGR, - GL_UNSIGNED_BYTE, download->data[0]); -#endif break; default: gst_gl_display_set_error (display, @@ -1169,42 +1240,21 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) g_assert_not_reached (); break; } - -#ifndef OPENGL_ES2 - glReadBuffer (GL_NONE); - glDisable (GL_TEXTURE_RECTANGLE_ARB); -#endif } +#endif - -/* called by _do_download (in the gl thread) */ +#if HAVE_OPENGL static void -_do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) +_do_download_draw_yuv_opengl (GstGLDisplay * display, GstGLDownload * download) { GstVideoFormat v_format; guint out_width, out_height; -#ifndef OPENGL_ES2 GLenum multipleRT[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT }; -#else - GLint viewport_dim[4]; - - const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f, - 1.0f, 0.0f, - -1.0f, -1.0f, 0.0f, - 0.0f, .0f, - -1.0f, 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, 0.0f, - 1.0f, 1.0f - }; - - GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; -#endif out_width = GST_VIDEO_INFO_WIDTH (&download->info); out_height = GST_VIDEO_INFO_HEIGHT (&download->info); @@ -1215,7 +1265,6 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); -#ifndef OPENGL_ES2 glPushAttrib (GL_VIEWPORT_BIT); glMatrixMode (GL_PROJECTION); @@ -1226,9 +1275,6 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glMatrixMode (GL_MODELVIEW); glPushMatrix (); glLoadIdentity (); -#else /* OPENGL_ES2 */ - glGetIntegerv (GL_VIEWPORT, viewport_dim); -#endif glViewport (0, 0, out_width, out_height); @@ -1237,27 +1283,15 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_UYVY: case GST_VIDEO_FORMAT_AYUV: { -#ifndef OPENGL_ES2 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); -#endif glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_gl_shader_use (download->shader); -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); -#else - glVertexAttribPointer (download->shader_attr_position_loc, 3, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); - glVertexAttribPointer (download->shader_attr_texture_loc, 2, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - - glEnableVertexAttribArray (download->shader_attr_position_loc); - glEnableVertexAttribArray (download->shader_attr_texture_loc); -#endif glActiveTextureARB (GL_TEXTURE0_ARB); gst_gl_shader_set_uniform_1i (download->shader, "tex", 0); @@ -1268,19 +1302,15 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: { -#ifndef OPENGL_ES2 glDrawBuffers (3, multipleRT); -#endif glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_gl_shader_use (download->shader); -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); -#endif glActiveTextureARB (GL_TEXTURE0_ARB); gst_gl_shader_set_uniform_1i (download->shader, "tex", 0); @@ -1297,7 +1327,6 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) } -#ifndef OPENGL_ES2 glBegin (GL_QUADS); glTexCoord2i (0, 0); glVertex2f (-1.0f, -1.0f); @@ -1310,9 +1339,6 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glEnd (); glDrawBuffer (GL_NONE); -#else /* OPENGL_ES2 */ - glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); -#endif /* don't check if GLSL is available * because download yuv is not available @@ -1320,24 +1346,17 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) */ glUseProgramObjectARB (0); -#ifndef OPENGL_ES2 glDisable (GL_TEXTURE_RECTANGLE_ARB); glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); glPopMatrix (); glPopAttrib (); -#else - glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], - viewport_dim[3]); -#endif gst_gl_display_check_framebuffer_status (); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); -#ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); -#endif switch (v_format) { case GST_VIDEO_FORMAT_AYUV: @@ -1364,17 +1383,13 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glReadPixels (0, 0, out_width, out_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[0]); -#ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); -#endif glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[1]); -#ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT2_EXT); -#endif glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, @@ -1386,17 +1401,13 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glReadPixels (0, 0, out_width, out_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[0]); -#ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); -#endif glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[2]); -#ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT2_EXT); -#endif glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, @@ -1409,11 +1420,167 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) "Download video format inconsistensy %d", v_format); g_assert_not_reached (); } -#ifndef OPENGL_ES2 glReadBuffer (GL_NONE); -#endif gst_gl_display_check_framebuffer_status (); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); } +#endif + +#if HAVE_GLES2 +static void +_do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download) +{ + GstVideoFormat v_format; + guint out_width, out_height; + + GLint viewport_dim[4]; + + const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f, + 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, + 0.0f, .0f, + -1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f + }; + + GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; + + out_width = GST_VIDEO_INFO_WIDTH (&download->info); + out_height = GST_VIDEO_INFO_HEIGHT (&download->info); + v_format = GST_VIDEO_INFO_FORMAT (&download->info); + + GST_TRACE ("doing YUV download of texture:%u (%ux%u) using fbo:%u", + download->in_texture, out_width, out_height, download->fbo); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); + + glGetIntegerv (GL_VIEWPORT, viewport_dim); + + glViewport (0, 0, out_width, out_height); + + switch (v_format) { + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: + case GST_VIDEO_FORMAT_AYUV: + { + glClearColor (0.0, 0.0, 0.0, 0.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + gst_gl_shader_use (download->shader); + + glVertexAttribPointer (download->shader_attr_position_loc, 3, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); + glVertexAttribPointer (download->shader_attr_texture_loc, 2, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + + glEnableVertexAttribArray (download->shader_attr_position_loc); + glEnableVertexAttribArray (download->shader_attr_texture_loc); + + glActiveTextureARB (GL_TEXTURE0_ARB); + gst_gl_shader_set_uniform_1i (download->shader, "tex", 0); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); + } + break; + + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + { + glClearColor (0.0, 0.0, 0.0, 0.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + gst_gl_shader_use (download->shader); + + glActiveTextureARB (GL_TEXTURE0_ARB); + gst_gl_shader_set_uniform_1i (download->shader, "tex", 0); + gst_gl_shader_set_uniform_1f (download->shader, "w", (gfloat) out_width); + gst_gl_shader_set_uniform_1f (download->shader, "h", (gfloat) out_height); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); + } + break; + + default: + break; + gst_gl_display_set_error (display, + "Download video format inconsistensy %d", v_format); + + } + + glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + + /* don't check if GLSL is available + * because download yuv is not available + * without GLSL (whereas rgb is) + */ + glUseProgramObjectARB (0); + + glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], + viewport_dim[3]); + + gst_gl_display_check_framebuffer_status (); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); + + switch (v_format) { + case GST_VIDEO_FORMAT_AYUV: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + glReadPixels (0, 0, out_width, out_height, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8, download->data[0]); +#else + glReadPixels (0, 0, out_width, out_height, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); +#endif + break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, out_height, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); +#else + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, out_height, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8, download->data[0]); +#endif + break; + case GST_VIDEO_FORMAT_I420: + { + glReadPixels (0, 0, out_width, out_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, + download->data[0]); + + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + download->data[1]); + + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + download->data[2]); + } + break; + case GST_VIDEO_FORMAT_YV12: + { + glReadPixels (0, 0, out_width, out_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, + download->data[0]); + + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + download->data[2]); + + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + download->data[1]); + } + break; + default: + break; + gst_gl_display_set_error (display, + "Download video format inconsistensy %d", v_format); + g_assert_not_reached (); + } + + gst_gl_display_check_framebuffer_status (); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); +} +#endif diff --git a/gst-libs/gst/gl/gstgldownload.h b/gst-libs/gst/gl/gstgldownload.h index ed94728399a..a06677361ef 100644 --- a/gst-libs/gst/gl/gstgldownload.h +++ b/gst-libs/gst/gl/gstgldownload.h @@ -24,8 +24,8 @@ #include #include -#include "gstglshader.h" #include "gstgldisplay.h" +#include "gstglshader.h" G_BEGIN_DECLS @@ -43,6 +43,7 @@ GType gst_gl_download_get_type (void); typedef struct _GstGLDownload GstGLDownload; typedef struct _GstGLDownloadClass GstGLDownloadClass; +typedef struct _GstGLDownloadPrivate GstGLDownloadPrivate; /** * GstGLDownload @@ -74,10 +75,10 @@ struct _GstGLDownload GLuint in_texture; GLuint out_texture[GST_VIDEO_MAX_PLANES]; GstGLShader *shader; -#ifdef OPENGL_ES2 GLint shader_attr_position_loc; GLint shader_attr_texture_loc; -#endif + + GstGLDownloadPrivate *priv; gpointer _reserved[GST_PADDING]; }; @@ -97,12 +98,12 @@ struct _GstGLDownloadClass * * The currently supported formats that can be downloaded */ -#ifndef OPENGL_ES2 +#if !HAVE_GLES2 # define GST_GL_DOWNLOAD_FORMATS "{ RGB, RGBx, RGBA, BGR, BGRx, BGRA, xRGB, " \ "xBGR, ARGB, ABGR, I420, YV12, YUY2, UYVY, AYUV }" -#else /* OPENGL_ES2 */ +#else /* HAVE_GLES2 */ # define GST_GL_DOWNLOAD_FORMATS "{ RGB, RGBx, RGBA, I420, YV12, YUY2, UYVY, AYUV }" -#endif /* !OPENGL_ES2 */ +#endif /* !HAVE_GLES2 */ /** * GST_GL_DOWNLOAD_VIDEO_CAPS: diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index 4c80b90b90c..9a91a996799 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -1075,7 +1075,7 @@ gst_gl_filter_render_to_target (GstGLFilter * filter, gboolean resize, in_width, 0, in_height, GST_GL_DISPLAY_PROJECTION_ORTHO2D, data); } -#ifndef OPENGL_ES2 +#if HAVE_OPENGL static void _draw_with_shader_cb (gint width, gint height, guint texture, gpointer stuff) { @@ -1116,6 +1116,9 @@ void gst_gl_filter_render_to_target_with_shader (GstGLFilter * filter, gboolean resize, GLuint input, GLuint target, GstGLShader * shader) { + g_return_if_fail (gst_gl_display_get_gl_api (filter->display) & + GST_GL_API_OPENGL); + filter->default_shader = shader; gst_gl_filter_render_to_target (filter, resize, input, target, _draw_with_shader_cb, filter); @@ -1153,4 +1156,4 @@ gst_gl_filter_draw_texture (GstGLFilter * filter, GLuint texture, glEnd (); } -#endif +#endif /* HAVE_OPENGL */ diff --git a/gst-libs/gst/gl/gstglfilter.h b/gst-libs/gst/gl/gstglfilter.h index 6d6d9b95dd5..405960393d6 100644 --- a/gst-libs/gst/gl/gstglfilter.h +++ b/gst-libs/gst/gl/gstglfilter.h @@ -124,12 +124,12 @@ gboolean gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, void gst_gl_filter_render_to_target (GstGLFilter *filter, gboolean resize, GLuint input, GLuint target, GLCB func, gpointer data); -#ifndef OPENGL_ES2 +#if HAVE_OPENGL void gst_gl_filter_render_to_target_with_shader (GstGLFilter * filter, gboolean resize, GLuint input, GLuint target, GstGLShader *shader); void gst_gl_filter_draw_texture (GstGLFilter *filter, GLuint texture, guint width, guint height); -#endif /* !OPENGL_ES2 */ +#endif /* HAVE_OPENGL */ G_END_DECLS diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c index 611929bec2e..25db723bec5 100644 --- a/gst-libs/gst/gl/gstglmemory.c +++ b/gst-libs/gst/gl/gstglmemory.c @@ -40,6 +40,12 @@ * Data is uploaded or downloaded from the GPU as is necessary. */ +#define USING_OPENGL(display) (display->gl_api & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (display->gl_api & GST_GL_API_OPENGL3) +#define USING_GLES(display) (display->gl_api & GST_GL_API_GLES) +#define USING_GLES2(display) (display->gl_api & GST_GL_API_GLES2) +#define USING_GLES3(display) (display->gl_api & GST_GL_API_GLES3) + GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY); #define GST_CAT_DEFUALT GST_CAT_GL_MEMORY @@ -220,22 +226,29 @@ _gl_mem_copy_thread (GstGLDisplay * display, gpointer data) glGenRenderbuffersEXT (1, &rboId); glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, rboId); -#ifndef OPENGL_ES2 - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, - height); - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, - width, height); -#else - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, - width, height); +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, + height); + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, + width, height); + } +#endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + width, height); + } #endif /* attach the renderbuffer to depth attachment point */ glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); -#ifndef OPENGL_ES2 - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); + } #endif glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, @@ -264,7 +277,7 @@ _gl_mem_copy_thread (GstGLDisplay * display, gpointer data) GST_CAT_ERROR (GST_CAT_GL_MEMORY, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); break; -#ifndef OPENGL_ES2 +#if HAVE_OPENGL case GL_FRAMEBUFFER_UNDEFINED: GST_CAT_ERROR (GST_CAT_GL_MEMORY, "GL_FRAMEBUFFER_UNDEFINED"); break; diff --git a/gst-libs/gst/gl/gstglshader.c b/gst-libs/gst/gl/gstglshader.c index 89087fe922f..ddbaa3b852e 100644 --- a/gst-libs/gst/gl/gstglshader.c +++ b/gst-libs/gst/gl/gstglshader.c @@ -27,6 +27,12 @@ #define GST_GL_SHADER_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_SHADER, GstGLShaderPrivate)) +#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3) +#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES) +#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2) +#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3) + enum { PROP_0, @@ -251,9 +257,13 @@ gst_gl_shader_init (GstGLShader * self) } GstGLShader * -gst_gl_shader_new (void) +gst_gl_shader_new (GstGLDisplay * display) { - return g_object_new (GST_GL_TYPE_SHADER, NULL); + GstGLShader *shader = g_object_new (GST_GL_TYPE_SHADER, NULL); + + shader->display = display; + + return shader; } gboolean @@ -270,7 +280,7 @@ gst_gl_shader_compile (GstGLShader * shader, GError ** error) GstGLShaderPrivate *priv; gchar info_buffer[2048]; - GLsizei len = 0; + gint len = 0; GLint status = GL_FALSE; g_return_val_if_fail (GST_GL_IS_SHADER (shader), FALSE); @@ -293,12 +303,15 @@ gst_gl_shader_compile (GstGLShader * shader, GError ** error) glGetObjectParameterivARB (priv->vertex_handle, GL_OBJECT_COMPILE_STATUS_ARB, &status); -#ifndef OPENGL_ES2 - glGetInfoLogARB (priv->vertex_handle, - sizeof (info_buffer) - 1, &len, info_buffer); -#else - glGetShaderInfoLog (priv->vertex_handle, - sizeof (info_buffer) - 1, &len, info_buffer); +#if HAVE_OPENGL + if (USING_OPENGL (shader->display)) + glGetInfoLogARB (priv->vertex_handle, + sizeof (info_buffer) - 1, &len, info_buffer); +#endif +#if HAVE_GLES2 + if (USING_GLES2 (shader->display)) + glGetShaderInfoLog (priv->vertex_handle, + sizeof (info_buffer) - 1, &len, info_buffer); #endif info_buffer[len] = '\0'; @@ -329,12 +342,15 @@ gst_gl_shader_compile (GstGLShader * shader, GError ** error) glGetObjectParameterivARB (priv->fragment_handle, GL_OBJECT_COMPILE_STATUS_ARB, &status); -#ifndef OPENGL_ES2 - glGetInfoLogARB (priv->fragment_handle, - sizeof (info_buffer) - 1, &len, info_buffer); -#else - glGetShaderInfoLog (priv->fragment_handle, - sizeof (info_buffer) - 1, &len, info_buffer); +#if HAVE_OPENGL + if (USING_OPENGL (shader->display)) + glGetInfoLogARB (priv->fragment_handle, + sizeof (info_buffer) - 1, &len, info_buffer); +#endif +#if HAVE_GLES2 + if (USING_GLES2 (shader->display)) + glGetShaderInfoLog (priv->fragment_handle, + sizeof (info_buffer) - 1, &len, info_buffer); #endif info_buffer[len] = '\0'; if (status != GL_TRUE) { @@ -356,10 +372,13 @@ gst_gl_shader_compile (GstGLShader * shader, GError ** error) /* if nothing failed link shaders */ glLinkProgramARB (priv->program_handle); -#ifndef OPENGL_ES2 - glGetObjectParameterivARB (priv->program_handle, GL_LINK_STATUS, &status); -#else - glGetProgramiv (priv->program_handle, GL_LINK_STATUS, &status); +#if HAVE_OPENGL + if (USING_OPENGL (shader->display)) + glGetObjectParameterivARB (priv->program_handle, GL_LINK_STATUS, &status); +#endif +#if HAVE_GLES2 + if (USING_GLES2 (shader->display)) + glGetProgramiv (priv->program_handle, GL_LINK_STATUS, &status); #endif glGetInfoLogARB (priv->program_handle, @@ -400,10 +419,13 @@ gst_gl_shader_release (GstGLShader * shader) if (priv->vertex_handle) { /* not needed but nvidia doesn't care to respect the spec */ GST_TRACE ("finalizing vertex shader %u", priv->vertex_handle); -#ifndef OPENGL_ES2 - glDeleteObjectARB (priv->vertex_handle); -#else - glDeleteShader (priv->vertex_handle); +#if HAVE_OPENGL + if (USING_OPENGL (shader->display)) + glDeleteObjectARB (priv->vertex_handle); +#endif +#if HAVE_GLES2 + if (USING_GLES2 (shader->display)) + glDeleteShader (priv->vertex_handle); #endif /* err = glGetError (); */ @@ -415,10 +437,14 @@ gst_gl_shader_release (GstGLShader * shader) if (priv->fragment_handle) { GST_TRACE ("finalizing fragment shader %u", priv->fragment_handle); -#ifndef OPENGL_ES2 - glDeleteObjectARB (priv->fragment_handle); -#else - glDeleteShader (priv->fragment_handle); + +#if HAVE_OPENGL + if (USING_OPENGL (shader->display)) + glDeleteObjectARB (priv->fragment_handle); +#endif +#if HAVE_GLES2 + if (USING_GLES2 (shader->display)) + glDeleteShader (priv->fragment_handle); #endif /* err = glGetError (); */ @@ -748,7 +774,7 @@ gst_gl_shader_set_uniform_4iv (GstGLShader * shader, const gchar * name, void gst_gl_shader_set_uniform_matrix_2fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat * value) + gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -762,11 +788,42 @@ gst_gl_shader_set_uniform_matrix_2fv (GstGLShader * shader, const gchar * name, glUniformMatrix2fvARB (location, count, transpose, value); } -#ifndef OPENGL_ES2 +void +gst_gl_shader_set_uniform_matrix_3fv (GstGLShader * shader, const gchar * name, + gint count, gboolean transpose, const gfloat * value) +{ + GstGLShaderPrivate *priv; + GLint location = -1; + + priv = shader->priv; + + g_return_if_fail (priv->program_handle != 0); + + location = glGetUniformLocationARB (priv->program_handle, name); + + glUniformMatrix3fvARB (location, count, transpose, value); +} + +void +gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name, + gint count, gboolean transpose, const gfloat * value) +{ + GstGLShaderPrivate *priv; + GLint location = -1; + + priv = shader->priv; + + g_return_if_fail (priv->program_handle != 0); + + location = glGetUniformLocationARB (priv->program_handle, name); + + glUniformMatrix4fvARB (location, count, transpose, value); +} + +#if HAVE_OPENGL void gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader * shader, - const gchar * name, GLsizei count, GLboolean transpose, - const GLfloat * value) + const gchar * name, gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -782,8 +839,7 @@ gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader * shader, void gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader * shader, - const gchar * name, GLsizei count, GLboolean transpose, - const GLfloat * value) + const gchar * name, gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -796,29 +852,10 @@ gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader * shader, glUniformMatrix2x4fv (location, count, transpose, value); } -#endif -void -gst_gl_shader_set_uniform_matrix_3fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat * value) -{ - GstGLShaderPrivate *priv; - GLint location = -1; - - priv = shader->priv; - - g_return_if_fail (priv->program_handle != 0); - - location = glGetUniformLocationARB (priv->program_handle, name); - - glUniformMatrix3fvARB (location, count, transpose, value); -} - -#ifndef OPENGL_ES2 void gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader * shader, - const gchar * name, GLsizei count, GLboolean transpose, - const GLfloat * value) + const gchar * name, gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -834,8 +871,7 @@ gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader * shader, void gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader * shader, - const gchar * name, GLsizei count, GLboolean transpose, - const GLfloat * value) + const gchar * name, gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -848,29 +884,10 @@ gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader * shader, glUniformMatrix3x4fv (location, count, transpose, value); } -#endif -void -gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat * value) -{ - GstGLShaderPrivate *priv; - GLint location = -1; - - priv = shader->priv; - - g_return_if_fail (priv->program_handle != 0); - - location = glGetUniformLocationARB (priv->program_handle, name); - - glUniformMatrix4fvARB (location, count, transpose, value); -} - -#ifndef OPENGL_ES2 void gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader * shader, - const gchar * name, GLsizei count, GLboolean transpose, - const GLfloat * value) + const gchar * name, gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -886,8 +903,7 @@ gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader * shader, void gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader * shader, - const gchar * name, GLsizei count, GLboolean transpose, - const GLfloat * value) + const gchar * name, gint count, gboolean transpose, const gfloat * value) { GstGLShaderPrivate *priv; GLint location = -1; @@ -900,7 +916,7 @@ gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader * shader, glUniformMatrix4x3fv (location, count, transpose, value); } -#endif +#endif /* HAVE_OPENGL */ GLint gst_gl_shader_get_attribute_location (GstGLShader * shader, const gchar * name) diff --git a/gst-libs/gst/gl/gstglshader.h b/gst-libs/gst/gl/gstglshader.h index c193d489ec7..27ba5830f20 100644 --- a/gst-libs/gst/gl/gstglshader.h +++ b/gst-libs/gst/gl/gstglshader.h @@ -21,18 +21,17 @@ #ifndef __GST_GL_SHADER_H__ #define __GST_GL_SHADER_H__ -/* OpenGL 2.0 for Embedded Systems */ -#ifdef OPENGL_ES2 -#include -#include "gstgles2.h" -/* OpenGL for usual systems */ -#else -#include +#ifdef HAVE_CONFIG_H +#include "config.h" #endif + +#include "gstgldisplay.h" #include G_BEGIN_DECLS +typedef struct _GstGLDisplay GstGLDisplay; + #define GST_GL_TYPE_SHADER (gst_gl_shader_get_type()) #define GST_GL_SHADER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_SHADER, GstGLShader)) #define GST_GL_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_SHADER, GstGLShaderClass)) @@ -60,6 +59,9 @@ typedef struct _GstGLShaderClass GstGLShaderClass; struct _GstGLShader { /*< private >*/ GObject parent; + + GstGLDisplay *display; + GstGLShaderPrivate *priv; }; @@ -73,68 +75,51 @@ struct _GstGLShaderClass { GQuark gst_gl_shader_error_quark (void); GType gst_gl_shader_get_type (void); -GstGLShader * gst_gl_shader_new (void); +GstGLShader * gst_gl_shader_new (GstGLDisplay *display); -void gst_gl_shader_set_vertex_source (GstGLShader *shader, - const gchar *src); -void gst_gl_shader_set_fragment_source (GstGLShader *shader, - const gchar *src); -const gchar * gst_gl_shader_get_vertex_source (GstGLShader *shader); +void gst_gl_shader_set_vertex_source (GstGLShader *shader, const gchar *src); +void gst_gl_shader_set_fragment_source (GstGLShader *shader, const gchar *src); +const gchar * gst_gl_shader_get_vertex_source (GstGLShader *shader); const gchar * gst_gl_shader_get_fragment_source (GstGLShader *shader); -void gst_gl_shader_set_active (GstGLShader *shader, - gboolean active); - -gboolean gst_gl_shader_is_compiled (GstGLShader *shader); - -gboolean gst_gl_shader_compile (GstGLShader *shader, GError **error); +void gst_gl_shader_set_active (GstGLShader *shader, gboolean active); +gboolean gst_gl_shader_is_compiled (GstGLShader *shader); +gboolean gst_gl_shader_compile (GstGLShader *shader, GError **error); gboolean gst_gl_shader_compile_and_check (GstGLShader *shader, const gchar *source, GstGLShaderSourceType type); + void gst_gl_shader_release (GstGLShader *shader); -void gst_gl_shader_use (GstGLShader *shader); +void gst_gl_shader_use (GstGLShader *shader); -void gst_gl_shader_set_uniform_1i (GstGLShader *shader, const gchar *name, gint value); -void gst_gl_shader_set_uniform_1iv (GstGLShader *shader, const gchar *name, guint count, gint * value); -void gst_gl_shader_set_uniform_1f (GstGLShader *shader, const gchar *name, gfloat value); -void gst_gl_shader_set_uniform_1fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value); -void gst_gl_shader_set_uniform_2i (GstGLShader *shader, const gchar *name, gint v0, gint v1); -void gst_gl_shader_set_uniform_2iv (GstGLShader *shader, const gchar *name, guint count, gint * value); -void gst_gl_shader_set_uniform_2f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1); -void gst_gl_shader_set_uniform_2fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value); -void gst_gl_shader_set_uniform_3i (GstGLShader *shader, const gchar *name, gint v0, gint v1, gint v2); -void gst_gl_shader_set_uniform_3iv (GstGLShader *shader, const gchar *name, guint count, gint * value); -void gst_gl_shader_set_uniform_3f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1, gfloat v2); -void gst_gl_shader_set_uniform_3fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value); -void gst_gl_shader_set_uniform_4i (GstGLShader *shader, const gchar *name, gint v0, gint v1, gint v2, gint v3); -void gst_gl_shader_set_uniform_4iv (GstGLShader *shader, const gchar *name, guint count, gint * value); -void gst_gl_shader_set_uniform_4f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1, gfloat v2, gfloat v3); -void gst_gl_shader_set_uniform_4fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value); -void gst_gl_shader_set_uniform_matrix_2fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -#ifndef OPENGL_ES2 -void gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -void gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -#endif -void gst_gl_shader_set_uniform_matrix_3fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -#ifndef OPENGL_ES2 -void gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -void gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -#endif -void gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -#ifndef OPENGL_ES2 -void gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); -void gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader * shader, const gchar * name, - GLsizei count, GLboolean transpose, const GLfloat* value); +void gst_gl_shader_set_uniform_1i (GstGLShader *shader, const gchar *name, gint value); +void gst_gl_shader_set_uniform_1iv (GstGLShader *shader, const gchar *name, guint count, gint *value); +void gst_gl_shader_set_uniform_1f (GstGLShader *shader, const gchar *name, gfloat value); +void gst_gl_shader_set_uniform_1fv (GstGLShader *shader, const gchar *name, guint count, gfloat *value); +void gst_gl_shader_set_uniform_2i (GstGLShader *shader, const gchar *name, gint v0, gint v1); +void gst_gl_shader_set_uniform_2iv (GstGLShader *shader, const gchar *name, guint count, gint *value); +void gst_gl_shader_set_uniform_2f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1); +void gst_gl_shader_set_uniform_2fv (GstGLShader *shader, const gchar *name, guint count, gfloat *value); +void gst_gl_shader_set_uniform_3i (GstGLShader *shader, const gchar *name, gint v0, gint v1, gint v2); +void gst_gl_shader_set_uniform_3iv (GstGLShader *shader, const gchar *name, guint count, gint * value); +void gst_gl_shader_set_uniform_3f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1, gfloat v2); +void gst_gl_shader_set_uniform_3fv (GstGLShader *shader, const gchar *name, guint count, gfloat *value); +void gst_gl_shader_set_uniform_4i (GstGLShader *shader, const gchar *name, gint v0, gint v1, gint v2, gint v3); +void gst_gl_shader_set_uniform_4iv (GstGLShader *shader, const gchar *name, guint count, gint *value); +void gst_gl_shader_set_uniform_4f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1, gfloat v2, gfloat v3); +void gst_gl_shader_set_uniform_4fv (GstGLShader *shader, const gchar *name, guint count, gfloat *value); +void gst_gl_shader_set_uniform_matrix_2fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_3fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_4fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +#if HAVE_OPENGL +void gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); +void gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader *shader, const gchar *name, gint count, gboolean transpose, const gfloat* value); #endif -GLint gst_gl_shader_get_attribute_location (GstGLShader *shader, const gchar *name); -void gst_gl_shader_bind_attribute_location (GstGLShader * shader, GLuint index, const gchar * name); +gint gst_gl_shader_get_attribute_location (GstGLShader *shader, const gchar *name); +void gst_gl_shader_bind_attribute_location (GstGLShader * shader, guint index, const gchar * name); G_END_DECLS diff --git a/gst-libs/gst/gl/gstglshadervariables.c b/gst-libs/gst/gl/gstglshadervariables.c index f97ef09a0ee..11251051247 100644 --- a/gst-libs/gst/gl/gstglshadervariables.c +++ b/gst-libs/gst/gl/gstglshadervariables.c @@ -554,7 +554,19 @@ gst_gl_shadervariable_set (GstGLShader * shader, (float *) ret->value); break; -#ifndef OPENGL_ES2 + case _mat3: + case _mat3x3: + gst_gl_shader_set_uniform_matrix_3fv (shader, ret->name, ret->count, 0, + (float *) ret->value); + break; + + case _mat4: + case _mat4x4: + gst_gl_shader_set_uniform_matrix_4fv (shader, ret->name, ret->count, 0, + (float *) ret->value); + break; + +#if HAVE_OPENGL case _mat2x3: gst_gl_shader_set_uniform_matrix_2x3fv (shader, ret->name, ret->count, 0, (float *) ret->value); @@ -574,13 +586,7 @@ gst_gl_shadervariable_set (GstGLShader * shader, gst_gl_shader_set_uniform_matrix_4x2fv (shader, ret->name, ret->count, 0, (float *) ret->value); break; -#endif - case _mat3: - case _mat3x3: - gst_gl_shader_set_uniform_matrix_3fv (shader, ret->name, ret->count, 0, - (float *) ret->value); - break; -#ifndef OPENGL_ES2 + case _mat3x4: gst_gl_shader_set_uniform_matrix_3x4fv (shader, ret->name, ret->count, 0, (float *) ret->value); @@ -591,11 +597,6 @@ gst_gl_shadervariable_set (GstGLShader * shader, (float *) ret->value); break; #endif - case _mat4: - case _mat4x4: - gst_gl_shader_set_uniform_matrix_4fv (shader, ret->name, ret->count, 0, - (float *) ret->value); - break; default: return -1; diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index b72bcf88f52..d1ed9398e38 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -43,8 +43,13 @@ * calling thread. */ +#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3) +#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES) +#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2) +#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3) + static void _do_upload (GstGLDisplay * display, GstGLUpload * upload); -static void _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload); static void _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload); static void _do_upload_make (GstGLDisplay * display, GstGLUpload * upload); static void _init_upload (GstGLDisplay * display, GstGLUpload * upload); @@ -54,100 +59,164 @@ static gboolean gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, static gboolean gst_gl_upload_perform_with_data_unlocked_thread (GstGLUpload * upload, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); +#if HAVE_OPENGL +static void _do_upload_draw_opengl (GstGLDisplay * display, + GstGLUpload * upload); +#endif +#if HAVE_GLES2 +static void _do_upload_draw_gles2 (GstGLDisplay * display, + GstGLUpload * upload); +#endif + +/* *INDENT-OFF* */ + +#if HAVE_OPENGL /* YUY2:r,g,a UYVY:a,b,r */ -static gchar *text_shader_YUY2_UYVY = -#ifndef OPENGL_ES2 +static gchar *text_shader_YUY2_UYVY_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect Ytex, UVtex;\n" -#else - "precision mediump float;\n" - "varying vec2 v_texCoord;\n" "uniform sampler2D Ytex, UVtex;\n" -#endif - "void main(void) {\n" " float fx, fy, y, u, v, r, g, b;\n" -#ifndef OPENGL_ES2 + "void main(void) {\n" + " float fx, fy, y, u, v, r, g, b;\n" " fx = gl_TexCoord[0].x;\n" " fy = gl_TexCoord[0].y;\n" " y = texture2DRect(Ytex,vec2(fx,fy)).%c;\n" " u = texture2DRect(UVtex,vec2(fx*0.5,fy)).%c;\n" " v = texture2DRect(UVtex,vec2(fx*0.5,fy)).%c;\n" -#else - " fx = v_texCoord.x;\n" - " fy = v_texCoord.y;\n" - " y = texture2D(Ytex,vec2(fx,fy)).%c;\n" - " u = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" - " v = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" -#endif " y=1.164*(y-0.0627);\n" " u=u-0.5;\n" " v=v-0.5;\n" " r = y+1.5958*v;\n" " g = y-0.39173*u-0.81290*v;\n" - " b = y+2.017*u;\n" " gl_FragColor = vec4(r, g, b, 1.0);\n" "}\n"; + " b = y+2.017*u;\n" + " gl_FragColor = vec4(r, g, b, 1.0);\n" + "}\n"; /* ATI: "*0.5", "" normal: "", "*0.5" */ -static gchar *text_shader_I420_YV12 = -#ifndef OPENGL_ES2 +static gchar *text_shader_I420_YV12_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect Ytex,Utex,Vtex;\n" -#else - "precision mediump float;\n" - "varying vec2 v_texCoord;\n" "uniform sampler2D Ytex,Utex,Vtex;\n" -#endif - "void main(void) {\n" " float r,g,b,y,u,v;\n" -#ifndef OPENGL_ES2 + "void main(void) {\n" + " float r,g,b,y,u,v;\n" " vec2 nxy = gl_TexCoord[0].xy;\n" " y=texture2DRect(Ytex,nxy%s).r;\n" - " u=texture2DRect(Utex,nxy%s).r;\n" " v=texture2DRect(Vtex,nxy*0.5).r;\n" -#else - " vec2 nxy = v_texCoord.xy;\n" - " y=texture2D(Ytex,nxy).r;\n" - " u=texture2D(Utex,nxy).r;\n" " v=texture2D(Vtex,nxy).r;\n" -#endif + " u=texture2DRect(Utex,nxy%s).r;\n" + " v=texture2DRect(Vtex,nxy*0.5).r;\n" " y=1.1643*(y-0.0625);\n" " u=u-0.5;\n" " v=v-0.5;\n" " r=y+1.5958*v;\n" " g=y-0.39173*u-0.81290*v;\n" - " b=y+2.017*u;\n" " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n"; + " b=y+2.017*u;\n" + " gl_FragColor=vec4(r,g,b,1.0);\n" + "}\n"; -static gchar *text_shader_AYUV = -#ifndef OPENGL_ES2 +static gchar *text_shader_AYUV_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" -#else - "precision mediump float;\n" - "varying vec2 v_texCoord;\n" "uniform sampler2D tex;\n" -#endif - "void main(void) {\n" " float r,g,b,y,u,v;\n" -#ifndef OPENGL_ES2 + "void main(void) {\n" + " float r,g,b,y,u,v;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" " y=texture2DRect(tex,nxy).r;\n" - " u=texture2DRect(tex,nxy).g;\n" " v=texture2DRect(tex,nxy).b;\n" -#else - " vec2 nxy = v_texCoord.xy;\n" - " y=texture2D(tex,nxy).g;\n" - " u=texture2D(tex,nxy).b;\n" " v=texture2D(tex,nxy).a;\n" -#endif + " u=texture2DRect(tex,nxy).g;\n" + " v=texture2DRect(tex,nxy).b;\n" " y=1.1643*(y-0.0625);\n" " u=u-0.5;\n" " v=v-0.5;\n" " r=y+1.5958*v;\n" " g=y-0.39173*u-0.81290*v;\n" - " b=y+2.017*u;\n" " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n"; + " b=y+2.017*u;\n" + " gl_FragColor=vec4(r,g,b,1.0);\n" + "}\n"; -#ifdef OPENGL_ES2 -static gchar *text_vertex_shader = +#define text_vertex_shader_opengl NULL +#endif + +#ifdef HAVE_GLES2 +/* YUY2:r,g,a + UYVY:a,b,r */ +static gchar *text_shader_YUY2_UYVY_gles2 = + "precision mediump float;\n" + "varying vec2 v_texCoord;\n" + "uniform sampler2D Ytex, UVtex;\n" + "void main(void) {\n" + " float fx, fy, y, u, v, r, g, b;\n" + " fx = v_texCoord.x;\n" + " fy = v_texCoord.y;\n" + " y = texture2D(Ytex,vec2(fx,fy)).%c;\n" + " u = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" + " v = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" + " y=1.164*(y-0.0627);\n" + " u=u-0.5;\n" + " v=v-0.5;\n" + " r = y+1.5958*v;\n" + " g = y-0.39173*u-0.81290*v;\n" + " b = y+2.017*u;\n" + " gl_FragColor = vec4(r, g, b, 1.0);\n" + "}\n"; + +static gchar *text_shader_I420_YV12_gles2 = + "precision mediump float;\n" + "varying vec2 v_texCoord;\n" + "uniform sampler2D Ytex,Utex,Vtex;\n" + "void main(void) {\n" + " float r,g,b,y,u,v;\n" + " vec2 nxy = v_texCoord.xy;\n" + " y=texture2D(Ytex,nxy).r;\n" + " u=texture2D(Utex,nxy).r;\n" + " v=texture2D(Vtex,nxy).r;\n" + " y=1.1643*(y-0.0625);\n" + " u=u-0.5;\n" + " v=v-0.5;\n" + " r=y+1.5958*v;\n" + " g=y-0.39173*u-0.81290*v;\n" + " b=y+2.017*u;\n" + " gl_FragColor=vec4(r,g,b,1.0);\n" + "}\n"; + +static gchar *text_shader_AYUV_gles2 = + "precision mediump float;\n" + "varying vec2 v_texCoord;\n" + "uniform sampler2D tex;\n" + "void main(void) {\n" + " float r,g,b,y,u,v;\n" + " vec2 nxy = v_texCoord.xy;\n" + " y=texture2D(tex,nxy).g;\n" + " u=texture2D(tex,nxy).b;\n" + " v=texture2D(tex,nxy).a;\n" + " y=1.1643*(y-0.0625);\n" + " u=u-0.5;\n" + " v=v-0.5;\n" + " r=y+1.5958*v;\n" + " g=y-0.39173*u-0.81290*v;\n" + " b=y+2.017*u;\n" + " gl_FragColor=vec4(r,g,b,1.0);\n" + "}\n"; + +static gchar *text_vertex_shader_gles2 = "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 v_texCoord; \n" "void main() \n" "{ \n" " gl_Position = a_position; \n" - " v_texCoord = a_texCoord; \n" "} \n"; + " v_texCoord = a_texCoord; \n" + "} \n"; #endif +/* *INDENT-ON* */ + +struct _GstGLUploadPrivate +{ + const gchar *YUY2_UYVY; + const gchar *I420_YV12; + const gchar *AYUV; + const gchar *vert_shader; + + void (*draw) (GstGLDisplay * display, GstGLUpload * download); +}; + GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug); #define GST_CAT_DEFAULT gst_gl_upload_debug @@ -163,12 +232,16 @@ static void gst_gl_upload_finalize (GObject * object); static void gst_gl_upload_class_init (GstGLUploadClass * klass) { + g_type_class_add_private (klass, sizeof (GstGLUploadPrivate)); + G_OBJECT_CLASS (klass)->finalize = gst_gl_upload_finalize; } static void gst_gl_upload_init (GstGLUpload * upload) { + upload->priv = GST_GL_UPLOAD_GET_PRIVATE (upload); + upload->display = NULL; g_mutex_init (&upload->lock); @@ -178,10 +251,8 @@ gst_gl_upload_init (GstGLUpload * upload) upload->out_texture = 0; upload->shader = NULL; -#ifdef OPENGL_ES2 upload->shader_attr_position_loc = 0; upload->shader_attr_texture_loc = 0; -#endif gst_video_info_init (&upload->info); } @@ -196,13 +267,34 @@ GstGLUpload * gst_gl_upload_new (GstGLDisplay * display) { GstGLUpload *upload; + GstGLUploadPrivate *priv; upload = g_object_new (GST_TYPE_GL_UPLOAD, NULL); upload->display = g_object_ref (display); + priv = upload->priv; g_mutex_init (&upload->lock); +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + priv->YUY2_UYVY = text_shader_YUY2_UYVY_opengl; + priv->I420_YV12 = text_shader_I420_YV12_opengl; + priv->AYUV = text_shader_AYUV_opengl; + priv->vert_shader = text_vertex_shader_opengl; + priv->draw = _do_upload_draw_opengl; + } +#endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + priv->YUY2_UYVY = text_shader_YUY2_UYVY_gles2; + priv->I420_YV12 = text_shader_I420_YV12_gles2; + priv->AYUV = text_shader_AYUV_gles2; + priv->vert_shader = text_vertex_shader_gles2; + priv->draw = _do_upload_draw_gles2; + } +#endif + return upload; } @@ -547,7 +639,7 @@ gst_gl_display_find_upload_unlocked (GstGLDisplay * display, GstVideoFormat v_format, guint in_width, guint in_height, guint out_width, guint out_height) { - GstGLUpload *ret; + GstGLUpload *ret = NULL; GSList *walk; walk = display->uploads; @@ -606,6 +698,34 @@ gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, return ret; } +static gboolean +_create_shader (GstGLDisplay * display, const gchar * vertex_src, + const gchar * fragment_src, GstGLShader ** out_shader) +{ + GstGLShader *shader; + GError *error; + + g_return_val_if_fail (vertex_src != NULL || fragment_src != NULL, FALSE); + + shader = gst_gl_shader_new (display); + + if (vertex_src) + gst_gl_shader_set_vertex_source (shader, vertex_src); + if (fragment_src) + gst_gl_shader_set_fragment_source (shader, fragment_src); + + if (!gst_gl_shader_compile (shader, &error)) { + gst_gl_display_set_error (display, "%s", error->message); + g_error_free (error); + gst_gl_shader_use (NULL); + g_object_unref (G_OBJECT (shader)); + return FALSE; + } + + *out_shader = shader; + return TRUE; +} + /* Called in the gl thread */ void _init_upload (GstGLDisplay * display, GstGLUpload * upload) @@ -647,10 +767,6 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload) /* shouldn't we require ARB_shading_language_100? --Filippo */ if (GLEW_ARB_fragment_shader) { -#ifdef OPENGL_ES2 - GError *error = NULL; -#endif - GST_INFO ("Context, ARB_fragment_shader supported: yes"); display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_GLSL; @@ -661,173 +777,100 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload) case GST_VIDEO_FORMAT_YUY2: { gchar text_shader_YUY2[2048]; - sprintf (text_shader_YUY2, text_shader_YUY2_UYVY, 'r', 'g', 'a'); + sprintf (text_shader_YUY2, upload->priv->YUY2_UYVY, 'r', 'g', 'a'); - upload->shader = gst_gl_shader_new (); -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (upload->shader, - text_shader_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for uploading YUY2"); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; + if (_create_shader (display, upload->priv->vert_shader, + text_shader_YUY2, &upload->shader)) { + if (USING_GLES2 (display)) { + upload->shader_attr_position_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_position"); + upload->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_texCoord"); + } } -#else - gst_gl_shader_set_vertex_source (upload->shader, - text_vertex_shader); - gst_gl_shader_set_fragment_source (upload->shader, - text_shader_YUY2); - - gst_gl_shader_compile (upload->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; - } else { - upload->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_position"); - upload->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_texCoord"); - } -#endif } break; case GST_VIDEO_FORMAT_UYVY: { gchar text_shader_UYVY[2048]; - sprintf (text_shader_UYVY, -#ifndef OPENGL_ES2 - text_shader_YUY2_UYVY, 'a', 'b', 'r'); -#else - text_shader_YUY2_UYVY, 'a', 'r', 'b'); -#endif - - upload->shader = gst_gl_shader_new (); - -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (upload->shader, - text_shader_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for uploading UYVY"); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; - } -#else - gst_gl_shader_set_vertex_source (upload->shader, - text_vertex_shader); - gst_gl_shader_set_fragment_source (upload->shader, - text_shader_UYVY); - - gst_gl_shader_compile (upload->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; - } else { - upload->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_position"); - upload->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_texCoord"); +#if HAVE_OPENGL + if (USING_GLES2 (display)) { + sprintf (text_shader_UYVY, upload->priv->YUY2_UYVY, + 'a', 'b', 'r'); } #endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + sprintf (text_shader_UYVY, upload->priv->YUY2_UYVY, + 'a', 'r', 'b'); + } +#endif + + if (_create_shader (display, upload->priv->vert_shader, + text_shader_UYVY, &upload->shader)) { + if (USING_GLES2 (display)) { + upload->shader_attr_position_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_position"); + upload->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_texCoord"); + } + } } break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: { -#ifndef OPENGL_ES2 - gchar text_shader[2048]; - if ((g_ascii_strncasecmp ("ATI", (gchar *) glGetString (GL_VENDOR), - 3) == 0) - && (g_ascii_strncasecmp ("ATI Mobility Radeon HD", - (gchar *) glGetString (GL_RENDERER), 22) != 0) - && (g_ascii_strncasecmp ("ATI Radeon HD", - (gchar *) glGetString (GL_RENDERER), 13) != 0)) - sprintf (text_shader, text_shader_I420_YV12, "*0.5", ""); - else - sprintf (text_shader, text_shader_I420_YV12, "", "*0.5"); -#endif - - upload->shader = gst_gl_shader_new (); - -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check - (upload->shader, text_shader, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for uploading I420 or YV12"); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; - } -#else - gst_gl_shader_set_vertex_source (upload->shader, - text_vertex_shader); - gst_gl_shader_set_fragment_source (upload->shader, - text_shader_I420_YV12); - - gst_gl_shader_compile (upload->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; - } else { - upload->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_position"); - upload->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_texCoord"); + gchar text_shader_I420_YV12[2048]; +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + if ((g_ascii_strncasecmp ("ATI", + (gchar *) glGetString (GL_VENDOR), 3) == 0) + && (g_ascii_strncasecmp ("ATI Mobility Radeon HD", + (gchar *) glGetString (GL_RENDERER), 22) != 0) + && (g_ascii_strncasecmp ("ATI Radeon HD", + (gchar *) glGetString (GL_RENDERER), 13) != 0)) + sprintf (text_shader_I420_YV12, upload->priv->I420_YV12, "*0.5", + ""); + else + sprintf (text_shader_I420_YV12, upload->priv->I420_YV12, "", + "*0.5"); } #endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) + g_strlcpy (text_shader_I420_YV12, upload->priv->I420_YV12, 2048); +#endif + + if (_create_shader (display, upload->priv->vert_shader, + text_shader_I420_YV12, &upload->shader)) { + if (USING_GLES2 (display)) { + upload->shader_attr_position_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_position"); + upload->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_texCoord"); + } + } } break; case GST_VIDEO_FORMAT_AYUV: { - upload->shader = gst_gl_shader_new (); - -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (upload->shader, - text_shader_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (display, - "Failed to initialize shader for uploading AYUV"); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; + if (_create_shader (display, upload->priv->vert_shader, + upload->priv->AYUV, &upload->shader)) { + if (USING_GLES2 (display)) { + upload->shader_attr_position_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_position"); + upload->shader_attr_texture_loc = + gst_gl_shader_get_attribute_location + (upload->shader, "a_texCoord"); + } } -#else - gst_gl_shader_set_vertex_source (upload->shader, - text_vertex_shader); - gst_gl_shader_set_fragment_source (upload->shader, - text_shader_AYUV); - - gst_gl_shader_compile (upload->shader, &error); - if (error) { - gst_gl_display_set_error (display, "%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - g_object_unref (G_OBJECT (upload->shader)); - upload->shader = NULL; - } else { - upload->shader_attr_position_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_position"); - upload->shader_attr_texture_loc = - gst_gl_shader_get_attribute_location - (upload->shader, "a_texCoord"); - } -#endif } break; default: @@ -916,14 +959,19 @@ _init_upload_fbo (GstGLDisplay * display, GstGLUpload * upload) /* setup the render buffer for depth */ glGenRenderbuffersEXT (1, &upload->depth_buffer); glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, upload->depth_buffer); -#ifndef OPENGL_ES2 - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - out_width, out_height); - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, - out_width, out_height); -#else - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, - out_width, out_height); +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + out_width, out_height); + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, + out_width, out_height); + } +#endif +#if HAVE_GLES2 + if (USING_GLES2 (display)) { + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + out_width, out_height); + } #endif /* a fake texture is attached to the upload FBO (cannot init without it) */ @@ -946,9 +994,11 @@ _init_upload_fbo (GstGLDisplay * display, GstGLUpload * upload) glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, upload->depth_buffer); -#ifndef OPENGL_ES2 - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, upload->depth_buffer); +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, upload->depth_buffer); + } #endif gst_gl_display_check_framebuffer_status (); @@ -995,7 +1045,7 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload) case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: if (in_width != out_width || in_height != out_height) - _do_upload_draw (display, upload); + upload->priv->draw (display, upload); /* color space conversion is not needed */ break; case GST_VIDEO_FORMAT_YUY2: @@ -1007,7 +1057,7 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload) switch (display->colorspace_conversion) { case GST_GL_DISPLAY_CONVERSION_GLSL: /* color space conversion is needed */ - _do_upload_draw (display, upload); + upload->priv->draw (display, upload); break; case GST_GL_DISPLAY_CONVERSION_MATRIX: /* color space conversion is needed */ @@ -1015,7 +1065,7 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload) break; case GST_GL_DISPLAY_CONVERSION_MESA: if (in_width != out_width || in_height != out_height) - _do_upload_draw (display, upload); + upload->priv->draw (display, upload); /* color space conversion is not needed */ break; default: @@ -1329,31 +1379,14 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); } - +#if HAVE_OPENGL /* called by _do_upload (in the gl thread) */ -void -_do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) +static void +_do_upload_draw_opengl (GstGLDisplay * display, GstGLUpload * upload) { GstVideoFormat v_format; guint out_width, out_height; - -#ifndef OPENGL_ES2 guint in_width, in_height; -#else - GLint viewport_dim[4]; - - const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f, - 1.0f, 0.0f, - -1.0f, -1.0f, 0.0f, - 0.0f, .0f, - -1.0f, 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, 0.0f, - 1.0f, 1.0f - }; - - GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; -#endif out_width = GST_VIDEO_INFO_WIDTH (&upload->info); out_height = GST_VIDEO_INFO_HEIGHT (&upload->info); @@ -1362,12 +1395,10 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, upload->fbo); /* setup a texture to render to */ -#ifndef OPENGL_ES2 in_width = upload->in_width; in_height = upload->in_height; glEnable (GL_TEXTURE_RECTANGLE_ARB); -#endif glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); /* attach the texture to the FBO to renderer to */ @@ -1377,7 +1408,6 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) if (GLEW_ARB_fragment_shader) gst_gl_shader_use (NULL); -#ifndef OPENGL_ES2 glPushAttrib (GL_VIEWPORT_BIT); glMatrixMode (GL_PROJECTION); @@ -1388,15 +1418,10 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) glMatrixMode (GL_MODELVIEW); glPushMatrix (); glLoadIdentity (); -#else /* OPENGL_ES2 */ - glGetIntegerv (GL_VIEWPORT, viewport_dim); -#endif glViewport (0, 0, out_width, out_height); -#ifndef OPENGL_ES2 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); -#endif glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1413,22 +1438,10 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: { -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); -#else - glVertexAttribPointer (upload->shader_attr_position_loc, 3, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); - glVertexAttribPointer (upload->shader_attr_texture_loc, 2, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - glEnableVertexAttribArray (upload->shader_attr_position_loc); - glEnableVertexAttribArray (upload->shader_attr_texture_loc); -#endif - -#ifndef OPENGL_ES2 glEnable (GL_TEXTURE_RECTANGLE_ARB); -#endif glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -1438,9 +1451,7 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#ifndef OPENGL_ES2 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -#endif } break; @@ -1453,18 +1464,8 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) { gst_gl_shader_use (upload->shader); -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); -#else - glVertexAttribPointer (upload->shader_attr_position_loc, 3, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); - glVertexAttribPointer (upload->shader_attr_texture_loc, 2, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - - glEnableVertexAttribArray (upload->shader_attr_position_loc); - glEnableVertexAttribArray (upload->shader_attr_texture_loc); -#endif glActiveTextureARB (GL_TEXTURE1_ARB); gst_gl_shader_set_uniform_1i (upload->shader, "UVtex", 1); @@ -1494,11 +1495,9 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) case GST_GL_DISPLAY_CONVERSION_MESA: { -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); glEnable (GL_TEXTURE_RECTANGLE_ARB); -#endif glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -1508,9 +1507,7 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#ifndef OPENGL_ES2 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -#endif } break; default: @@ -1527,18 +1524,8 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) { gst_gl_shader_use (upload->shader); -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); -#else - glVertexAttribPointer (upload->shader_attr_position_loc, 3, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); - glVertexAttribPointer (upload->shader_attr_texture_loc, 2, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - - glEnableVertexAttribArray (upload->shader_attr_position_loc); - glEnableVertexAttribArray (upload->shader_attr_texture_loc); -#endif glActiveTextureARB (GL_TEXTURE1_ARB); gst_gl_shader_set_uniform_1i (upload->shader, "Utex", 1); @@ -1582,18 +1569,8 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) { gst_gl_shader_use (upload->shader); -#ifndef OPENGL_ES2 glMatrixMode (GL_PROJECTION); glLoadIdentity (); -#else - glVertexAttribPointer (upload->shader_attr_position_loc, 3, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); - glVertexAttribPointer (upload->shader_attr_texture_loc, 2, - GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - - glEnableVertexAttribArray (upload->shader_attr_position_loc); - glEnableVertexAttribArray (upload->shader_attr_texture_loc); -#endif glActiveTextureARB (GL_TEXTURE0_ARB); gst_gl_shader_set_uniform_1i (upload->shader, "tex", 0); @@ -1617,7 +1594,6 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) } /* end switch display->currentVideo_format */ -#ifndef OPENGL_ES2 glBegin (GL_QUADS); glTexCoord2i (in_width, 0); glVertex2f (1.0f, -1.0f); @@ -1630,15 +1606,11 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) glEnd (); glDrawBuffer (GL_NONE); -#else /* OPENGL_ES2 */ - glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); -#endif /* we are done with the shader */ if (display->colorspace_conversion == GST_GL_DISPLAY_CONVERSION_GLSL) glUseProgramObjectARB (0); -#ifndef OPENGL_ES2 glDisable (GL_TEXTURE_RECTANGLE_ARB); glMatrixMode (GL_PROJECTION); @@ -1646,12 +1618,250 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) glMatrixMode (GL_MODELVIEW); glPopMatrix (); glPopAttrib (); -#else - glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], - viewport_dim[3]); -#endif gst_gl_display_check_framebuffer_status (); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); } +#endif + +#if HAVE_GLES2 +static void +_do_upload_draw_gles2 (GstGLDisplay * display, GstGLUpload * upload) +{ + GstVideoFormat v_format; + guint out_width, out_height; + + GLint viewport_dim[4]; + + const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f, + 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, + 0.0f, .0f, + -1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f + }; + + GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; + + out_width = GST_VIDEO_INFO_WIDTH (&upload->info); + out_height = GST_VIDEO_INFO_HEIGHT (&upload->info); + v_format = GST_VIDEO_INFO_FORMAT (&upload->info); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, upload->fbo); + + /* setup a texture to render to */ + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); + + /* attach the texture to the FBO to renderer to */ + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_RECTANGLE_ARB, upload->out_texture, 0); + + if (GLEW_ARB_fragment_shader) + gst_gl_shader_use (NULL); + + glGetIntegerv (GL_VIEWPORT, viewport_dim); + + glViewport (0, 0, out_width, out_height); + + glClearColor (0.0, 0.0, 0.0, 0.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + switch (v_format) { + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + { + glVertexAttribPointer (upload->shader_attr_position_loc, 3, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); + glVertexAttribPointer (upload->shader_attr_texture_loc, 2, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + + glEnableVertexAttribArray (upload->shader_attr_position_loc); + glEnableVertexAttribArray (upload->shader_attr_texture_loc); + + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + } + break; + + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: + { + switch (display->colorspace_conversion) { + case GST_GL_DISPLAY_CONVERSION_GLSL: + case GST_GL_DISPLAY_CONVERSION_MATRIX: + { + gst_gl_shader_use (upload->shader); + + glVertexAttribPointer (upload->shader_attr_position_loc, 3, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); + glVertexAttribPointer (upload->shader_attr_texture_loc, 2, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + + glEnableVertexAttribArray (upload->shader_attr_position_loc); + glEnableVertexAttribArray (upload->shader_attr_texture_loc); + + glActiveTextureARB (GL_TEXTURE1_ARB); + gst_gl_shader_set_uniform_1i (upload->shader, "UVtex", 1); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + + glActiveTextureARB (GL_TEXTURE0_ARB); + gst_gl_shader_set_uniform_1i (upload->shader, "Ytex", 0); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + } + break; + case GST_GL_DISPLAY_CONVERSION_MESA: + { + + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + } + break; + default: + gst_gl_display_set_error (display, "Unknow colorspace conversion %d", + display->colorspace_conversion); + g_assert_not_reached (); + break; + } + } + break; + + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + { + gst_gl_shader_use (upload->shader); + + glVertexAttribPointer (upload->shader_attr_position_loc, 3, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); + glVertexAttribPointer (upload->shader_attr_texture_loc, 2, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + + glEnableVertexAttribArray (upload->shader_attr_position_loc); + glEnableVertexAttribArray (upload->shader_attr_texture_loc); + + glActiveTextureARB (GL_TEXTURE1_ARB); + gst_gl_shader_set_uniform_1i (upload->shader, "Utex", 1); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + + glActiveTextureARB (GL_TEXTURE2_ARB); + gst_gl_shader_set_uniform_1i (upload->shader, "Vtex", 2); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + + glActiveTextureARB (GL_TEXTURE0_ARB); + gst_gl_shader_set_uniform_1i (upload->shader, "Ytex", 0); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + } + break; + + case GST_VIDEO_FORMAT_AYUV: + { + gst_gl_shader_use (upload->shader); + + glVertexAttribPointer (upload->shader_attr_position_loc, 3, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); + glVertexAttribPointer (upload->shader_attr_texture_loc, 2, + GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + + glEnableVertexAttribArray (upload->shader_attr_position_loc); + glEnableVertexAttribArray (upload->shader_attr_texture_loc); + + glActiveTextureARB (GL_TEXTURE0_ARB); + gst_gl_shader_set_uniform_1i (upload->shader, "tex", 0); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + } + break; + + default: + gst_gl_display_set_error (display, "Unsupported upload video format %d", + v_format); + g_assert_not_reached (); + break; + + } /* end switch display->currentVideo_format */ + + glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + + /* we are done with the shader */ + if (display->colorspace_conversion == GST_GL_DISPLAY_CONVERSION_GLSL) + glUseProgramObjectARB (0); + + glViewport (viewport_dim[0], viewport_dim[1], viewport_dim[2], + viewport_dim[3]); + + gst_gl_display_check_framebuffer_status (); + + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); +} +#endif diff --git a/gst-libs/gst/gl/gstglupload.h b/gst-libs/gst/gl/gstglupload.h index 9ab9ce7e96e..cc3d10c8c56 100644 --- a/gst-libs/gst/gl/gstglupload.h +++ b/gst-libs/gst/gl/gstglupload.h @@ -43,6 +43,7 @@ GType gst_gl_upload_get_type (void); typedef struct _GstGLUpload GstGLUpload; typedef struct _GstGLUploadClass GstGLUploadClass; +typedef struct _GstGLUploadPrivate GstGLUploadPrivate; /** * GstGLUpload @@ -76,12 +77,12 @@ struct _GstGLUpload guint in_width; guint in_height; GstGLShader *shader; -#ifdef OPENGL_ES2 GLint shader_attr_position_loc; GLint shader_attr_texture_loc; -#endif /* */ + GstGLUploadPrivate *priv; + gpointer _reserved[GST_PADDING]; }; @@ -100,12 +101,12 @@ struct _GstGLUploadClass * * The currently supported formats that can be uploaded */ -#ifndef OPENGL_ES2 -# define GST_GL_UPLOAD_FORMATS "{ RGB, RGBx, RGBA, BGR, BGRx, BGRA, xRGB, " \ +#if !HAVE_GLES2 +#define GST_GL_UPLOAD_FORMATS "{ RGB, RGBx, RGBA, BGR, BGRx, BGRA, xRGB, " \ "xBGR, ARGB, ABGR, I420, YV12, YUY2, UYVY, AYUV }" -#else /* OPENGL_ES2 */ +#else /* HAVE_GLES2 */ # define GST_GL_UPLOAD_FORMATS "{ RGB, RGBx, RGBA, I420, YV12, YUY2, UYVY, AYUV }" -#endif +#endif /* !HAVE_GLES2 */ /** * GST_GL_UPLOAD_VIDEO_CAPS: diff --git a/gst/gl/Makefile.am b/gst/gl/Makefile.am index 63c5bdc46c4..3575fdc8f3c 100644 --- a/gst/gl/Makefile.am +++ b/gst/gl/Makefile.am @@ -5,7 +5,7 @@ AM_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) AM_LIBS = $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) # full opengl required -if USE_GL +if USE_OPENGL OPENGL_SOURCES = \ gstglfiltershader.c \ gstglfiltershader.h \ diff --git a/gst/gl/effects/gstgleffectbulge.c b/gst/gl/effects/gstgleffectbulge.c index 6816e1ed7a2..f951844dd97 100644 --- a/gst/gl/effects/gstgleffectbulge.c +++ b/gst/gl/effects/gstgleffectbulge.c @@ -31,7 +31,7 @@ gst_gl_effects_bulge_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "bulge0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "bulge0", shader); } diff --git a/gst/gl/effects/gstgleffectfisheye.c b/gst/gl/effects/gstgleffectfisheye.c index 9b835291790..bc141384ab9 100644 --- a/gst/gl/effects/gstgleffectfisheye.c +++ b/gst/gl/effects/gstgleffectfisheye.c @@ -31,7 +31,7 @@ gst_gl_effects_fisheye_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "fisheye0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "fisheye0", shader); } diff --git a/gst/gl/effects/gstgleffectglow.c b/gst/gl/effects/gstgleffectglow.c index dc47841dc32..28e36d7a13a 100644 --- a/gst/gl/effects/gstgleffectglow.c +++ b/gst/gl/effects/gstgleffectglow.c @@ -34,7 +34,7 @@ gst_gl_effects_glow_step_one (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "glow0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "glow0", shader); } @@ -71,7 +71,7 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "glow1"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "glow1", shader); } @@ -115,7 +115,7 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "glow2"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "glow2", shader); } @@ -154,7 +154,7 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "glow3"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "glow3", shader); } diff --git a/gst/gl/effects/gstgleffectidentity.c b/gst/gl/effects/gstgleffectidentity.c index b0435ab759d..1ed38c0d220 100644 --- a/gst/gl/effects/gstgleffectidentity.c +++ b/gst/gl/effects/gstgleffectidentity.c @@ -20,51 +20,61 @@ #include +#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3) +#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES) +#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2) +#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3) + static void gst_gl_effects_identity_callback (gint width, gint height, guint texture, gpointer data) { GstGLEffects *effects = GST_GL_EFFECTS (data); + GstGLFilter *filter = GST_GL_FILTER (effects); -#ifndef OPENGL_ES2 - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); -#else - GstGLShader *shader = - g_hash_table_lookup (effects->shaderstable, "identity0"); +#if HAVE_OPENGL + if (USING_OPENGL (filter->display)) { + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + } +#endif +#if HAVE_GLES2 + if (USING_GLES2 (filter->display)) { + GstGLShader *shader = + g_hash_table_lookup (effects->shaderstable, "identity0"); - if (!shader) { - shader = gst_gl_shader_new (); - g_hash_table_insert (effects->shaderstable, "identity0", shader); + if (!shader) { + shader = gst_gl_shader_new (filter->display); + g_hash_table_insert (effects->shaderstable, "identity0", shader); + if (shader) { + GError *error = NULL; + gst_gl_shader_set_vertex_source (shader, vertex_shader_source); + gst_gl_shader_set_fragment_source (shader, identity_fragment_source); - if (shader) { - GError *error = NULL; - gst_gl_shader_set_vertex_source (shader, vertex_shader_source); - gst_gl_shader_set_fragment_source (shader, identity_fragment_source); - - gst_gl_shader_compile (shader, &error); - if (error) { - GST_ERROR ("%s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - } else { - effects->draw_attr_position_loc = - gst_gl_shader_get_attribute_location (shader, "a_position"); - effects->draw_attr_texture_loc = - gst_gl_shader_get_attribute_location (shader, "a_texCoord"); + gst_gl_shader_compile (shader, &error); + if (error) { + GST_ERROR ("%s", error->message); + g_error_free (error); + error = NULL; + gst_gl_shader_use (NULL); + } else { + effects->draw_attr_position_loc = + gst_gl_shader_get_attribute_location (shader, "a_position"); + effects->draw_attr_texture_loc = + gst_gl_shader_get_attribute_location (shader, "a_texCoord"); + } } } + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE0); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + + gst_gl_shader_set_uniform_1i (shader, "tex", 0); } - - gst_gl_shader_use (shader); - - glActiveTexture (GL_TEXTURE0); - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - - gst_gl_shader_set_uniform_1i (shader, "tex", 0); #endif gst_gl_effects_draw_texture (effects, texture, width, height); diff --git a/gst/gl/effects/gstgleffectlumatocurve.c b/gst/gl/effects/gstgleffectlumatocurve.c index c0dfb1e56e3..9656f670d27 100644 --- a/gst/gl/effects/gstgleffectlumatocurve.c +++ b/gst/gl/effects/gstgleffectlumatocurve.c @@ -31,7 +31,7 @@ gst_gl_effects_luma_to_curve (GstGLEffects * effects, shader = g_hash_table_lookup (effects->shaderstable, "lumamap0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "lumamap0", shader); } diff --git a/gst/gl/effects/gstgleffectmirror.c b/gst/gl/effects/gstgleffectmirror.c index 7acea2ad274..0f02ee5a8e8 100644 --- a/gst/gl/effects/gstgleffectmirror.c +++ b/gst/gl/effects/gstgleffectmirror.c @@ -20,57 +20,69 @@ #include +#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3) +#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES) +#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2) +#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3) + static void gst_gl_effects_mirror_callback (gint width, gint height, guint texture, gpointer data) { GstGLEffects *effects = GST_GL_EFFECTS (data); - + GstGLFilter *filter = GST_GL_FILTER (effects); GstGLShader *shader; shader = g_hash_table_lookup (effects->shaderstable, "mirror0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (filter->display); g_hash_table_insert (effects->shaderstable, "mirror0", shader); -#ifdef OPENGL_ES2 - if (shader) { - GError *error = NULL; - gst_gl_shader_set_vertex_source (shader, vertex_shader_source); - gst_gl_shader_set_fragment_source (shader, mirror_fragment_source); +#if HAVE_GLES2 + if (USING_GLES2 (filter->display)) { + if (shader) { + GError *error = NULL; + gst_gl_shader_set_vertex_source (shader, vertex_shader_source); + gst_gl_shader_set_fragment_source (shader, + mirror_fragment_source_gles2); - gst_gl_shader_compile (shader, &error); - if (error) { - gst_gl_display_set_error (GST_GL_FILTER (effects)->display, - "Failed to initialize mirror shader, %s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, - GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), (NULL)); - } else { - effects->draw_attr_position_loc = - gst_gl_shader_get_attribute_location (shader, "a_position"); - effects->draw_attr_texture_loc = - gst_gl_shader_get_attribute_location (shader, "a_texCoord"); + gst_gl_shader_compile (shader, &error); + if (error) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize mirror shader, %s", error->message); + g_error_free (error); + error = NULL; + gst_gl_shader_use (NULL); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), + (NULL)); + } else { + effects->draw_attr_position_loc = + gst_gl_shader_get_attribute_location (shader, "a_position"); + effects->draw_attr_texture_loc = + gst_gl_shader_get_attribute_location (shader, "a_texCoord"); + } } } #endif - } -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (shader, - mirror_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (GST_GL_FILTER (effects)->display, - "Failed to initialize mirror shader"); - GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, - GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), (NULL)); - return; - } +#if HAVE_OPENGL + if (USING_OPENGL (filter->display)) { + if (!gst_gl_shader_compile_and_check (shader, + mirror_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize mirror shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), (NULL)); + return; + } - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + } #endif + } gst_gl_shader_use (shader); @@ -80,9 +92,11 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture, gst_gl_shader_set_uniform_1i (shader, "tex", 0); -#ifndef OPENGL_ES2 - gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f); - gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f); +#if HAVE_OPENGL + if (USING_OPENGL (filter->display)) { + gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f); + gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f); + } #endif gst_gl_effects_draw_texture (effects, texture, width, height); diff --git a/gst/gl/effects/gstgleffectrgbtocurve.c b/gst/gl/effects/gstgleffectrgbtocurve.c index b249a8061a7..ca2b16011ca 100644 --- a/gst/gl/effects/gstgleffectrgbtocurve.c +++ b/gst/gl/effects/gstgleffectrgbtocurve.c @@ -31,7 +31,7 @@ gst_gl_effects_rgb_to_curve (GstGLEffects * effects, shader = g_hash_table_lookup (effects->shaderstable, "rgbmap0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "rgbmap0", shader); } diff --git a/gst/gl/effects/gstgleffectsin.c b/gst/gl/effects/gstgleffectsin.c index 6a357e0e8f2..80a1ace1b0a 100644 --- a/gst/gl/effects/gstgleffectsin.c +++ b/gst/gl/effects/gstgleffectsin.c @@ -31,7 +31,7 @@ gst_gl_effects_sin_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "sin0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "sin0", shader); } diff --git a/gst/gl/effects/gstgleffectsquare.c b/gst/gl/effects/gstgleffectsquare.c index 90de7269875..88033e49239 100644 --- a/gst/gl/effects/gstgleffectsquare.c +++ b/gst/gl/effects/gstgleffectsquare.c @@ -31,7 +31,7 @@ gst_gl_effects_square_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "square0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "square0", shader); } diff --git a/gst/gl/effects/gstgleffectsqueeze.c b/gst/gl/effects/gstgleffectsqueeze.c index ff04ef35cd8..640e2f05847 100644 --- a/gst/gl/effects/gstgleffectsqueeze.c +++ b/gst/gl/effects/gstgleffectsqueeze.c @@ -20,57 +20,69 @@ #include +#define USING_OPENGL(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL) +#define USING_OPENGL3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_OPENGL3) +#define USING_GLES(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES) +#define USING_GLES2(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES2) +#define USING_GLES3(display) (gst_gl_display_get_gl_api_unlocked (display) & GST_GL_API_GLES3) + static void gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointer data) { GstGLEffects *effects = GST_GL_EFFECTS (data); - + GstGLFilter *filter = GST_GL_FILTER (effects); GstGLShader *shader; shader = g_hash_table_lookup (effects->shaderstable, "squeeze0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (filter->display); g_hash_table_insert (effects->shaderstable, "squeeze0", shader); -#ifdef OPENGL_ES2 - if (shader) { - GError *error = NULL; - gst_gl_shader_set_vertex_source (shader, vertex_shader_source); - gst_gl_shader_set_fragment_source (shader, squeeze_fragment_source); +#if HAVE_GLES2 + if (USING_GLES2 (filter->display)) { + if (shader) { + GError *error = NULL; + gst_gl_shader_set_vertex_source (shader, vertex_shader_source); + gst_gl_shader_set_fragment_source (shader, + squeeze_fragment_source_gles2); - gst_gl_shader_compile (shader, &error); - if (error) { - GstGLFilter *filter = GST_GL_FILTER (effects); - gst_gl_display_set_error (filter->display, - "Failed to initialize squeeze shader, %s", error->message); - g_error_free (error); - error = NULL; - gst_gl_shader_use (NULL); - GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, - GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), (NULL)); - } else { - effects->draw_attr_position_loc = - gst_gl_shader_get_attribute_location (shader, "a_position"); - effects->draw_attr_texture_loc = - gst_gl_shader_get_attribute_location (shader, "a_texCoord"); + gst_gl_shader_compile (shader, &error); + if (error) { + GstGLFilter *filter = GST_GL_FILTER (effects); + gst_gl_display_set_error (filter->display, + "Failed to initialize squeeze shader, %s", error->message); + g_error_free (error); + error = NULL; + gst_gl_shader_use (NULL); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), + (NULL)); + } else { + effects->draw_attr_position_loc = + gst_gl_shader_get_attribute_location (shader, "a_position"); + effects->draw_attr_texture_loc = + gst_gl_shader_get_attribute_location (shader, "a_texCoord"); + } } } #endif - } -#ifndef OPENGL_ES2 - if (!gst_gl_shader_compile_and_check (shader, - squeeze_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { - gst_gl_display_set_error (GST_GL_FILTER (effects)->display, - "Failed to initialize squeeze shader"); - GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, - GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), (NULL)); - return; - } - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); +#if HAVE_OPENGL + if (USING_OPENGL (filter->display)) { + if (!gst_gl_shader_compile_and_check (shader, + squeeze_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize squeeze shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display), (NULL)); + return; + } + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + } #endif + } gst_gl_shader_use (shader); @@ -80,9 +92,11 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gst_gl_shader_set_uniform_1i (shader, "tex", 0); -#ifndef OPENGL_ES2 - gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f); - gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f); +#if HAVE_GLES2 + if (USING_GLES2 (filter->display)) { + gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f); + gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f); + } #endif gst_gl_effects_draw_texture (effects, texture, width, height); diff --git a/gst/gl/effects/gstgleffectssources.c b/gst/gl/effects/gstgleffectssources.c index e8d6af6a345..1bf5b40eca2 100644 --- a/gst/gl/effects/gstgleffectssources.c +++ b/gst/gl/effects/gstgleffectssources.c @@ -80,18 +80,12 @@ const gchar *identity_fragment_source = "}"; /* Mirror effect */ -const gchar *mirror_fragment_source = -#ifndef OPENGL_ES2 +#if HAVE_OPENGL +const gchar *mirror_fragment_source_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;" "uniform float width, height;" -#else - "precision mediump float;" - "varying vec2 v_texCoord;" - "uniform sampler2D tex;" -#endif "void main () {" -#ifndef OPENGL_ES2 " vec2 tex_size = vec2 (width, height);" " vec2 texturecoord = gl_TexCoord[0].xy;" " vec2 normcoord;" @@ -100,29 +94,29 @@ const gchar *mirror_fragment_source = " texturecoord = (normcoord + 1.0) * tex_size;" " vec4 color = texture2DRect (tex, texturecoord);" " gl_FragColor = color * gl_Color;" -#else + "}"; +#endif +#if HAVE_GLES2 +const gchar *mirror_fragment_source_gles2 = + "precision mediump float;" + "varying vec2 v_texCoord;" + "uniform sampler2D tex;" + "void main () {" " vec2 texturecoord = v_texCoord.xy;" " float normcoord = texturecoord.x - 0.5;" " normcoord *= sign (normcoord);" " texturecoord.x = (normcoord + 0.5);" " gl_FragColor = texture2D (tex, texturecoord);" -#endif "}"; - +#endif /* Squeeze effect */ -const gchar *squeeze_fragment_source = -#ifndef OPENGL_ES2 +#if HAVE_OPENGL +const gchar *squeeze_fragment_source_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;" "uniform float width, height;" -#else - "precision mediump float;" - "varying vec2 v_texCoord;" - "uniform sampler2D tex;" -#endif "void main () {" -#ifndef OPENGL_ES2 " vec2 tex_size = vec2 (width, height);" " vec2 texturecoord = gl_TexCoord[0].xy;" " vec2 normcoord;" @@ -133,7 +127,14 @@ const gchar *squeeze_fragment_source = " texturecoord = (normcoord + 1.0) * tex_size;" " vec4 color = texture2DRect (tex, texturecoord); " " gl_FragColor = color * gl_Color;" -#else + "}"; +#endif +#if HAVE_GLES2 +const gchar *squeeze_fragment_source_gles2 = + "precision mediump float;" + "varying vec2 v_texCoord;" + "uniform sampler2D tex;" + "void main () {" " vec2 texturecoord = v_texCoord.xy;" " vec2 normcoord = texturecoord - 0.5;" " float r = length (normcoord);" @@ -141,9 +142,8 @@ const gchar *squeeze_fragment_source = " normcoord = normcoord / r;" " texturecoord = (normcoord + 0.5);" " gl_FragColor = texture2D (tex, texturecoord);" -#endif "}"; - +#endif /* Stretch Effect */ const gchar *stretch_fragment_source = diff --git a/gst/gl/effects/gstgleffectssources.h b/gst/gl/effects/gstgleffectssources.h index 9320d59288f..d3b3e555e40 100644 --- a/gst/gl/effects/gstgleffectssources.h +++ b/gst/gl/effects/gstgleffectssources.h @@ -21,10 +21,20 @@ #ifndef __GST_GL_EFFECTS_SOURCES_H__ #define __GST_GL_EFFECTS_SOURCES_H__ +#if HAVE_CONFIG_H +#include "config.h" +#endif + extern const gchar *vertex_shader_source; extern const gchar *identity_fragment_source; -extern const gchar *mirror_fragment_source; -extern const gchar *squeeze_fragment_source; +#if HAVE_OPENGL +extern const gchar *mirror_fragment_source_opengl; +extern const gchar *squeeze_fragment_source_opengl; +#endif +#if HAVE_GLES2 +extern const gchar *mirror_fragment_source_gles2; +extern const gchar *squeeze_fragment_source_gles2; +#endif extern const gchar *stretch_fragment_source; extern const gchar *tunnel_fragment_source; extern const gchar *fisheye_fragment_source; diff --git a/gst/gl/effects/gstgleffectstretch.c b/gst/gl/effects/gstgleffectstretch.c index 749ad67c769..9f628c4ec91 100644 --- a/gst/gl/effects/gstgleffectstretch.c +++ b/gst/gl/effects/gstgleffectstretch.c @@ -31,7 +31,7 @@ gst_gl_effects_stretch_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "stretch0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "stretch0", shader); } diff --git a/gst/gl/effects/gstgleffecttunnel.c b/gst/gl/effects/gstgleffecttunnel.c index 870a0e99e5a..233950aefff 100644 --- a/gst/gl/effects/gstgleffecttunnel.c +++ b/gst/gl/effects/gstgleffecttunnel.c @@ -31,7 +31,7 @@ gst_gl_effects_tunnel_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "tunnel0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "tunnel0", shader); } diff --git a/gst/gl/effects/gstgleffecttwirl.c b/gst/gl/effects/gstgleffecttwirl.c index 338d0d84704..de9f0b37bb1 100644 --- a/gst/gl/effects/gstgleffecttwirl.c +++ b/gst/gl/effects/gstgleffecttwirl.c @@ -31,7 +31,7 @@ gst_gl_effects_twirl_callback (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "twirl0"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "twirl0", shader); } diff --git a/gst/gl/effects/gstgleffectxray.c b/gst/gl/effects/gstgleffectxray.c index 3990960d146..091ddf63816 100644 --- a/gst/gl/effects/gstgleffectxray.c +++ b/gst/gl/effects/gstgleffectxray.c @@ -45,7 +45,7 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray1"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray1", shader); } @@ -89,7 +89,7 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray2"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray2", shader); } @@ -129,7 +129,7 @@ gst_gl_effects_xray_desaturate (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray_desat"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray_desat", shader); } @@ -166,7 +166,7 @@ gst_gl_effects_xray_sobel_hconv (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_hconv"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray_sob_hconv", shader); } @@ -203,7 +203,7 @@ gst_gl_effects_xray_sobel_vconv (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_vconv"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray_sob_vconv", shader); } @@ -240,7 +240,7 @@ gst_gl_effects_xray_sobel_length (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_len"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray_sob_len", shader); } @@ -280,7 +280,7 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture, shader = g_hash_table_lookup (effects->shaderstable, "xray4"); if (!shader) { - shader = gst_gl_shader_new (); + shader = gst_gl_shader_new (GST_GL_FILTER (effects)->display); g_hash_table_insert (effects->shaderstable, "xray4", shader); } diff --git a/gst/gl/gltestsrc.c b/gst/gl/gltestsrc.c index 4ca6c8c8354..4a8c5f15fd3 100644 --- a/gst/gl/gltestsrc.c +++ b/gst/gl/gltestsrc.c @@ -25,8 +25,6 @@ #include "gltestsrc.h" - - #include #include #include @@ -85,135 +83,148 @@ gst_gl_test_src_unicolor (GstGLTestSrc * v, GstBuffer * buffer, int w, void gst_gl_test_src_smpte (GstGLTestSrc * v, GstBuffer * buffer, int w, int h) { +#if HAVE_OPENGL int i; - glClearColor (0.0, 0.0, 0.0, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (gst_gl_display_get_gl_api_unlocked (v->display) & GST_GL_API_OPENGL) { - glDisable (GL_CULL_FACE); - glDisable (GL_TEXTURE_RECTANGLE_ARB); + glClearColor (0.0, 0.0, 0.0, 1.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); + glDisable (GL_CULL_FACE); + glDisable (GL_TEXTURE_RECTANGLE_ARB); - for (i = 0; i < 7; i++) { - glColor4f (vts_colors[i].R * (1 / 255.0f), vts_colors[i].G * (1 / 255.0f), - vts_colors[i].B * (1 / 255.0f), 1.0f); - glBegin (GL_QUADS); - glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0 * (2.0f / 3.0f), 0); - glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), - -1.0f + 2.0f * (2.0f / 3.0f), 0); - glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), -1.0f, 0); - glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f, 0); - glEnd (); - } + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); - for (i = 0; i < 7; i++) { - int k; - - if (i & 1) { - k = 7; - } else { - k = 6 - i; + for (i = 0; i < 7; i++) { + glColor4f (vts_colors[i].R * (1 / 255.0f), vts_colors[i].G * (1 / 255.0f), + vts_colors[i].B * (1 / 255.0f), 1.0f); + glBegin (GL_QUADS); + glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0 * (2.0f / 3.0f), 0); + glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), + -1.0f + 2.0f * (2.0f / 3.0f), 0); + glVertex3f (-1.0f + (i + 1.0f) * (2.0f / 7.0f), -1.0f, 0); + glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f, 0); + glEnd (); } - glColor4f (vts_colors[k].R * (1 / 255.0f), vts_colors[k].G * (1 / 255.0f), - vts_colors[k].B * (1 / 255.0f), 1.0f); - glBegin (GL_QUADS); - glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); - glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), - 0); - glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), - 0); - glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), 0); - glEnd (); - } + for (i = 0; i < 7; i++) { + int k; - for (i = 0; i < 3; i++) { - int k; + if (i & 1) { + k = 7; + } else { + k = 6 - i; + } - if (i == 0) { - k = 8; - } else if (i == 1) { - k = 0; - } else { - k = 9; + glColor4f (vts_colors[k].R * (1 / 255.0f), vts_colors[k].G * (1 / 255.0f), + vts_colors[k].B * (1 / 255.0f), 1.0f); + glBegin (GL_QUADS); + glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); + glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (3.0f / 4.0f), + 0); + glVertex3f (-1.0f + (i + 1) * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), + 0); + glVertex3f (-1.0f + i * (2.0f / 7.0f), -1.0f + 2.0f * (2.0f / 3.0f), 0); + glEnd (); } - glColor4f (vts_colors[k].R * (1 / 255.0f), vts_colors[k].G * (1 / 255.0f), - vts_colors[k].B * (1 / 255.0f), 1.0f); - glBegin (GL_QUADS); - glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0); - glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0); - glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), - 0); - glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); - glEnd (); - } + for (i = 0; i < 3; i++) { + int k; - for (i = 0; i < 3; i++) { - int k; + if (i == 0) { + k = 8; + } else if (i == 1) { + k = 0; + } else { + k = 9; + } - if (i == 0) { - k = COLOR_SUPER_BLACK; - } else if (i == 1) { - k = COLOR_BLACK; - } else { - k = COLOR_DARK_GREY; + glColor4f (vts_colors[k].R * (1 / 255.0f), vts_colors[k].G * (1 / 255.0f), + vts_colors[k].B * (1 / 255.0f), 1.0f); + glBegin (GL_QUADS); + glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0); + glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * 1, 0); + glVertex3f (-1.0f + (i + 1) * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), + 0); + glVertex3f (-1.0f + i * (2.0f / 6.0f), -1.0f + 2.0f * (3.0f / 4.0f), 0); + glEnd (); } - glColor4f (vts_colors[k].R * (1 / 255.0f), vts_colors[k].G * (1 / 255.0f), - vts_colors[k].B * (1 / 255.0f), 1.0f); + for (i = 0; i < 3; i++) { + int k; + + if (i == 0) { + k = COLOR_SUPER_BLACK; + } else if (i == 1) { + k = COLOR_BLACK; + } else { + k = COLOR_DARK_GREY; + } + + glColor4f (vts_colors[k].R * (1 / 255.0f), vts_colors[k].G * (1 / 255.0f), + vts_colors[k].B * (1 / 255.0f), 1.0f); + glBegin (GL_QUADS); + glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), -1.0 + 2.0f * 1, + 0); + glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)), + -1.0f + 2.0f * 1, 0); + glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)), + -1.0f + 2.0f * (3.0f / 4.0f), 0); + glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), + -1.0f + 2.0f * (3.0f / 4.0f), 0); + glEnd (); + } + + glColor4f (1.0, 1.0, 1.0, 1.0); glBegin (GL_QUADS); - glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), -1.0 + 2.0f * 1, 0); - glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)), - -1.0f + 2.0f * 1, 0); - glVertex3f (-1.0f + 2.0f * (0.5f + (i + 1) * (1.0f / 12.0f)), - -1.0f + 2.0f * (3.0f / 4.0f), 0); - glVertex3f (-1.0f + 2.0f * (0.5f + i * (1.0f / 12.0f)), - -1.0f + 2.0f * (3.0f / 4.0f), 0); + glVertex3f (-1.0 + 2.0 * (0.75), -1.0 + 2.0 * 1, 0); + glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0); + glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (3.0 / 4.0), 0); + glVertex3f (-1.0 + 2.0 * (0.75), -1.0 + 2.0 * (3.0 / 4.0), 0); glEnd (); } - - glColor4f (1.0, 1.0, 1.0, 1.0); - glBegin (GL_QUADS); - glVertex3f (-1.0 + 2.0 * (0.75), -1.0 + 2.0 * 1, 0); - glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0); - glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (3.0 / 4.0), 0); - glVertex3f (-1.0 + 2.0 * (0.75), -1.0 + 2.0 * (3.0 / 4.0), 0); - glEnd (); - +#endif } void gst_gl_test_src_snow (GstGLTestSrc * v, GstBuffer * buffer, int w, int h) { - glClearColor (0.0, 0.0, 0.0, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#if HAVE_OPENGL + if (gst_gl_display_get_gl_api_unlocked (v->display) & GST_GL_API_OPENGL) { + glClearColor (0.0, 0.0, 0.0, 1.0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); - /* FIXME snow requires a fragment shader. Please write. */ - glColor4f (0.5, 0.5, 0.5, 1.0); - glBegin (GL_QUADS); - glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * 1, 0); - glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0); - glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (0.0), 0); - glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * (0.0), 0); - glEnd (); + /* FIXME snow requires a fragment shader. Please write. */ + glColor4f (0.5, 0.5, 0.5, 1.0); + glBegin (GL_QUADS); + glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * 1, 0); + glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0); + glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (0.0), 0); + glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * (0.0), 0); + glEnd (); + } +#endif } static void gst_gl_test_src_unicolor (GstGLTestSrc * v, GstBuffer * buffer, int w, int h, const struct vts_color_struct *color) { - glClearColor (color->R * (1 / 255.0f), color->G * (1 / 255.0f), - color->B * (1 / 255.0f), 1.0f); - glClear (GL_COLOR_BUFFER_BIT); +#if HAVE_OPENGL + if (gst_gl_display_get_gl_api_unlocked (v->display) & GST_GL_API_OPENGL) { + glClearColor (color->R * (1 / 255.0f), color->G * (1 / 255.0f), + color->B * (1 / 255.0f), 1.0f); + glClear (GL_COLOR_BUFFER_BIT); + } +#endif } void diff --git a/gst/gl/gstgldifferencematte.c b/gst/gl/gstgldifferencematte.c index 085d968deb0..8a41f73464d 100644 --- a/gst/gl/gstgldifferencematte.c +++ b/gst/gl/gstgldifferencematte.c @@ -97,7 +97,7 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter * filter) GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - differencematte->shader[i] = gst_gl_shader_new (); + differencematte->shader[i] = gst_gl_shader_new (filter->display); } if (!gst_gl_shader_compile_and_check (differencematte->shader[0], diff --git a/gst/gl/gstgleffects.c b/gst/gl/gstgleffects.c index 8f4852c9da4..febdfea6a74 100644 --- a/gst/gl/gstgleffects.c +++ b/gst/gl/gstgleffects.c @@ -97,7 +97,7 @@ gst_gl_effects_effect_get_type (void) {GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity"}, {GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror"}, {GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze"}, -#ifndef OPENGL_ES2 +#if HAVE_OPENGL {GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"}, {GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"}, {GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"}, @@ -136,7 +136,7 @@ gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type) case GST_GL_EFFECT_SQUEEZE: effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_squeeze; break; -#ifndef OPENGL_ES2 +#if HAVE_OPENGL case GST_GL_EFFECT_STRETCH: effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_stretch; break; @@ -270,83 +270,84 @@ void gst_gl_effects_draw_texture (GstGLEffects * effects, GLuint tex, guint width, guint height) { -#ifndef OPENGL_ES2 - glActiveTexture (GL_TEXTURE0); - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex); +#if HAVE_OPENGL + if (gst_gl_display_get_gl_api_unlocked (GST_GL_FILTER (effects)->display) & + GST_GL_API_OPENGL) { + glActiveTexture (GL_TEXTURE0); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex); - glBegin (GL_QUADS); + glBegin (GL_QUADS); - glTexCoord2f (0.0, 0.0); - glVertex2f (-1.0, -1.0); - glTexCoord2f ((gfloat) width, 0.0); - glVertex2f (1.0, -1.0); - glTexCoord2f ((gfloat) width, (gfloat) height); - glVertex2f (1.0, 1.0); - glTexCoord2f (0.0, (gfloat) height); - glVertex2f (-1.0, 1.0); + glTexCoord2f (0.0, 0.0); + glVertex2f (-1.0, -1.0); + glTexCoord2f ((gfloat) width, 0.0); + glVertex2f (1.0, -1.0); + glTexCoord2f ((gfloat) width, (gfloat) height); + glVertex2f (1.0, 1.0); + glTexCoord2f (0.0, (gfloat) height); + glVertex2f (-1.0, 1.0); - glEnd (); -#else + glEnd (); + } +#endif +#if HAVE_GLES2 + if (gst_gl_display_get_gl_api_unlocked (GST_GL_FILTER (effects)->display) & + GST_GL_API_GLES2) + ) { + const GLfloat vVertices[] = { + -1.0f, -1.0f, 0.0f, + 0.0f, 0.0f, + 1.0, -1.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f}; - const GLfloat vVertices[] = { -1.0f, -1.0f, 0.0f, - 0.0f, 0.0f, - 1.0, -1.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, - 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, - 0.0f, 1.0f - }; + GLushort indices[] = { + 0, 1, 2, 0, 2, 3}; - GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; + /* glClear (GL_COLOR_BUFFER_BIT); */ - //glClear (GL_COLOR_BUFFER_BIT); + /* Load the vertex position */ + glVertexAttribPointer (effects->draw_attr_position_loc, 3, GL_FLOAT, + GL_FALSE, 5 * sizeof (GLfloat), vVertices); - //Load the vertex position - glVertexAttribPointer (effects->draw_attr_position_loc, 3, GL_FLOAT, - GL_FALSE, 5 * sizeof (GLfloat), vVertices); + /* Load the texture coordinate */ + glVertexAttribPointer (effects->draw_attr_texture_loc, 2, GL_FLOAT, + GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); - //Load the texture coordinate - glVertexAttribPointer (effects->draw_attr_texture_loc, 2, GL_FLOAT, - GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]); + glEnableVertexAttribArray (effects->draw_attr_position_loc); + glEnableVertexAttribArray (effects->draw_attr_texture_loc); - glEnableVertexAttribArray (effects->draw_attr_position_loc); - glEnableVertexAttribArray (effects->draw_attr_texture_loc); - - glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + } #endif glUseProgramObjectARB (0); } -static void -set_horizontal_swap (GstGLDisplay * display, gpointer data) +static void set_horizontal_swap (GstGLDisplay * display, gpointer data) { -// GstGLEffects *effects = GST_GL_EFFECTS (data); - -#ifndef OPENGL_ES2 - const double mirrormatrix[16] = { +#if HAVE_OPENGL + if (USING_OPENGL (display)) { + const double mirrormatrix[16] = { -1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; + 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0}; - glMatrixMode (GL_MODELVIEW); - glLoadMatrixd (mirrormatrix); + glMatrixMode (GL_MODELVIEW); + glLoadMatrixd (mirrormatrix); + } #endif } -static void -gst_gl_effects_init (GstGLEffects * effects) +static void gst_gl_effects_init (GstGLEffects * effects) { effects->effect = gst_gl_effects_identity; effects->horizontal_swap = FALSE; } static void -gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data) + gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, + gpointer data) { GstGLShader *shader = (GstGLShader *) value; GstGLFilter *filter = (GstGLFilter *) data; @@ -357,26 +358,23 @@ gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data) value = NULL; } -static void -gst_gl_effects_reset_resources (GstGLFilter * filter) +static void gst_gl_effects_reset_resources (GstGLFilter * filter) { GstGLEffects *effects = GST_GL_EFFECTS (filter); -// g_message ("reset resources"); - - //release shaders in the gl thread + /* release shaders in the gl thread */ g_hash_table_foreach (effects->shaderstable, gst_gl_effects_ghash_func_clean, filter); - //clean the htable without calling values destructors - //because shaders have been released in the glthread - //through the foreach func + /* clean the htable without calling values destructors + * because shaders have been released in the glthread + * through the foreach func */ g_hash_table_unref (effects->shaderstable); effects->shaderstable = NULL; } static void -gst_gl_effects_set_property (GObject * object, guint prop_id, + gst_gl_effects_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstGLEffects *effects = GST_GL_EFFECTS (object); @@ -385,17 +383,15 @@ gst_gl_effects_set_property (GObject * object, guint prop_id, case PROP_EFFECT: gst_gl_effects_set_effect (effects, g_value_get_enum (value)); break; - case PROP_HSWAP: - effects->horizontal_swap = g_value_get_boolean (value); + case PROP_HSWAP:effects->horizontal_swap = g_value_get_boolean (value); break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + default:G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void -gst_gl_effects_get_property (GObject * object, guint prop_id, + gst_gl_effects_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstGLEffects *effects = GST_GL_EFFECTS (object); @@ -413,15 +409,13 @@ gst_gl_effects_get_property (GObject * object, guint prop_id, } } -static void -gst_gl_effects_init_resources (GstGLFilter * filter) +static void gst_gl_effects_init_resources (GstGLFilter * filter) { GstGLEffects *effects = GST_GL_EFFECTS (filter); gint i; -// g_message ("init resources"); -// g_message ("init hashtable"); + effects->shaderstable = g_hash_table_new (g_str_hash, g_str_equal); -// g_message ("zero textures and curves"); + for (i = 0; i < NEEDED_TEXTURES; i++) { effects->midtexture[i] = 0; } @@ -430,16 +424,15 @@ gst_gl_effects_init_resources (GstGLFilter * filter) } } -static gboolean -gst_gl_effects_on_init_gl_context (GstGLFilter * filter) +static gboolean gst_gl_effects_on_init_gl_context (GstGLFilter * filter) { - //check that your hardware supports shader - //if not the pipeline correctly shut down + /* check that your hardware supports shader + * if not the pipeline correctly shut down */ return gst_gl_display_gen_shader (filter->display, 0, 0, NULL); } static gboolean -gst_gl_effects_filter_texture (GstGLFilter * filter, guint in_tex, + gst_gl_effects_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex) { GstGLEffects *effects = GST_GL_EFFECTS (filter); diff --git a/gst/gl/gstgleffects.h b/gst/gl/gstgleffects.h index 054928bfeed..b51c49f97f9 100644 --- a/gst/gl/gstgleffects.h +++ b/gst/gl/gstgleffects.h @@ -71,7 +71,7 @@ struct _GstGLEffects gboolean horizontal_swap; /* switch left to right */ -#ifdef OPENGL_ES2 +#if HAVE_GLES2 GLint draw_attr_position_loc; GLint draw_attr_texture_loc; #endif diff --git a/gst/gl/gstglfiltercube.c b/gst/gl/gstglfiltercube.c index 3127a17d868..815a79d4f3a 100644 --- a/gst/gl/gstglfiltercube.c +++ b/gst/gl/gstglfiltercube.c @@ -44,6 +44,7 @@ #include "config.h" #endif +#include #include "gstglfiltercube.h" #define GST_CAT_DEFAULT gst_gl_filter_cube_debug @@ -74,17 +75,21 @@ static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id, static gboolean gst_gl_filter_cube_set_caps (GstGLFilter * filter, GstCaps * incaps, GstCaps * outcaps); -#ifdef OPENGL_ES2 +#if HAVE_GLES2 static void gst_gl_filter_cube_reset (GstGLFilter * filter); static gboolean gst_gl_filter_cube_init_shader (GstGLFilter * filter); +static void _callback_gles2 (gint width, gint height, guint texture, + gpointer stuff); +#endif +#if HAVE_OPENGL +static void _callback_opengl (gint width, gint height, guint texture, + gpointer stuff); #endif static gboolean gst_gl_filter_cube_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex); -static void gst_gl_filter_cube_callback (gint width, gint height, guint texture, - gpointer stuff); -#ifdef OPENGL_ES2 -//vertex source +#if HAVE_GLES2 +/* vertex source */ static const gchar *cube_v_src = "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" @@ -116,7 +121,7 @@ static const gchar *cube_v_src = " v_texCoord = a_texCoord; \n" "} \n"; -//fragment source +/* fragment source */ static const gchar *cube_f_src = "precision mediump float; \n" "varying vec2 v_texCoord; \n" @@ -139,7 +144,7 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) gobject_class->set_property = gst_gl_filter_cube_set_property; gobject_class->get_property = gst_gl_filter_cube_get_property; -#ifdef OPENGL_ES2 +#if HAVE_GLES2 GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_cube_init_shader; GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_cube_reset; #endif @@ -186,9 +191,7 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) static void gst_gl_filter_cube_init (GstGLFilterCube * filter) { -#ifdef OPENGL_ES filter->shader = NULL; -#endif filter->fovy = 45; filter->aspect = 0; filter->znear = 0.1; @@ -233,8 +236,6 @@ static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - //GstGLFilterCube* filter = GST_GL_FILTER_CUBE (object); - switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -255,14 +256,15 @@ gst_gl_filter_cube_set_caps (GstGLFilter * filter, GstCaps * incaps, return TRUE; } -#ifdef OPENGL_ES2 +#if HAVE_GLES2 static void gst_gl_filter_cube_reset (GstGLFilter * filter) { GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter); - //blocking call, wait the opengl thread has destroyed the shader - gst_gl_display_del_shader (filter->display, cube_filter->shader); + /* blocking call, wait the opengl thread has destroyed the shader */ + if (cube_filter->shader) + gst_gl_display_del_shader (filter->display, cube_filter->shader); } static gboolean @@ -270,9 +272,12 @@ gst_gl_filter_cube_init_shader (GstGLFilter * filter) { GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter); - //blocking call, wait the opengl thread has compiled the shader - return gst_gl_display_gen_shader (filter->display, cube_v_src, cube_f_src, - &cube_filter->shader); + if (gst_gl_display_get_gl_api (filter->display) & GST_GL_API_GLES2) { + /* blocking call, wait the opengl thread has compiled the shader */ + return gst_gl_display_gen_shader (filter->display, cube_v_src, cube_f_src, + &cube_filter->shader); + } + return TRUE; } #endif @@ -281,13 +286,27 @@ gst_gl_filter_cube_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex) { GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter); + GLCB cb = NULL; + GstGLAPI api; - //blocking call, use a FBO + api = + gst_gl_display_get_gl_api_unlocked (GST_GL_FILTER (cube_filter)->display); + +#if HAVE_OPENGL + if (api & GST_GL_API_OPENGL) + cb = _callback_opengl; +#endif +#if HAVE_GLES2 + if (api & GST_GL_API_GLES2) + cb = _callback_gles2; +#endif + + /* blocking call, use a FBO */ gst_gl_display_use_fbo (filter->display, GST_VIDEO_INFO_WIDTH (&filter->out_info), GST_VIDEO_INFO_HEIGHT (&filter->out_info), filter->fbo, filter->depthbuffer, out_tex, - gst_gl_filter_cube_callback, + cb, GST_VIDEO_INFO_WIDTH (&filter->in_info), GST_VIDEO_INFO_HEIGHT (&filter->in_info), in_tex, cube_filter->fovy, cube_filter->aspect, @@ -297,10 +316,10 @@ gst_gl_filter_cube_filter_texture (GstGLFilter * filter, guint in_tex, return TRUE; } -//opengl scene, params: input texture (not the output filter->texture) +/* opengl scene, params: input texture (not the output filter->texture) */ +#if HAVE_OPENGL static void -gst_gl_filter_cube_callback (gint width, gint height, guint texture, - gpointer stuff) +_callback_opengl (gint width, gint height, guint texture, gpointer stuff) { GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (stuff); @@ -308,7 +327,6 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, static GLfloat yrot = 0; static GLfloat zrot = 0; -#ifndef OPENGL_ES2 glEnable (GL_DEPTH_TEST); glEnable (GL_TEXTURE_RECTANGLE_ARB); @@ -319,9 +337,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#ifndef OPENGL_ES2 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -#endif glClearColor (cube_filter->red, cube_filter->green, cube_filter->blue, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -336,7 +352,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glRotatef (zrot, 0.0f, 0.0f, 1.0f); glBegin (GL_QUADS); - // Front Face + /* Front Face */ glTexCoord2f ((gfloat) width, 0.0f); glVertex3f (-1.0f, -1.0f, 1.0f); glTexCoord2f (0.0f, 0.0f); @@ -345,7 +361,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glVertex3f (1.0f, 1.0f, 1.0f); glTexCoord2f ((gfloat) width, (gfloat) height); glVertex3f (-1.0f, 1.0f, 1.0f); - // Back Face + /* Back Face */ glTexCoord2f (0.0f, 0.0f); glVertex3f (-1.0f, -1.0f, -1.0f); glTexCoord2f (0.0f, (gfloat) height); @@ -354,7 +370,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glVertex3f (1.0f, 1.0f, -1.0f); glTexCoord2f ((gfloat) width, 0.0f); glVertex3f (1.0f, -1.0f, -1.0f); - // Top Face + /* Top Face */ glTexCoord2f ((gfloat) width, (gfloat) height); glVertex3f (-1.0f, 1.0f, -1.0f); glTexCoord2f ((gfloat) width, 0.0f); @@ -363,7 +379,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glVertex3f (1.0f, 1.0f, 1.0f); glTexCoord2f (0.0f, (gfloat) height); glVertex3f (1.0f, 1.0f, -1.0f); - // Bottom Face + /* Bottom Face */ glTexCoord2f ((gfloat) width, 0.0f); glVertex3f (-1.0f, -1.0f, -1.0f); glTexCoord2f (0.0f, 0.0f); @@ -372,7 +388,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glVertex3f (1.0f, -1.0f, 1.0f); glTexCoord2f ((gfloat) width, (gfloat) height); glVertex3f (-1.0f, -1.0f, 1.0f); - // Right face + /* Right face */ glTexCoord2f (0.0f, 0.0f); glVertex3f (1.0f, -1.0f, -1.0f); glTexCoord2f (0.0f, (gfloat) height); @@ -381,7 +397,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glVertex3f (1.0f, 1.0f, 1.0f); glTexCoord2f ((gfloat) width, 0.0f); glVertex3f (1.0f, -1.0f, 1.0f); - // Left Face + /* Left Face */ glTexCoord2f ((gfloat) width, 0.0f); glVertex3f (-1.0f, -1.0f, -1.0f); glTexCoord2f (0.0f, 0.0f); @@ -391,10 +407,28 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glTexCoord2f ((gfloat) width, (gfloat) height); glVertex3f (-1.0f, 1.0f, -1.0f); glEnd (); -#else + + glDisable (GL_DEPTH_TEST); + + xrot += 0.3f; + yrot += 0.2f; + zrot += 0.4f; +} +#endif + +#if HAVE_GLES2 +static void +_callback_gles2 (gint width, gint height, guint texture, gpointer stuff) +{ + GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (stuff); + + static GLfloat xrot = 0; + static GLfloat yrot = 0; + static GLfloat zrot = 0; + const GLfloat v_vertices[] = { - //front face + /* front face */ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, @@ -403,7 +437,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, - //back face + /* back face */ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, @@ -412,7 +446,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, - //right face + /* right face */ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, @@ -421,7 +455,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, - //left face + /* left face */ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, -1.0f, @@ -430,7 +464,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, - //top face + /* top face */ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, @@ -439,7 +473,7 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, - //bottom face + /* bottom face */ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, @@ -487,11 +521,11 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, attr_texture_loc = gst_gl_shader_get_attribute_location (cube_filter->shader, "a_texCoord"); - //Load the vertex position + /* Load the vertex position */ glVertexAttribPointer (attr_position_loc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), v_vertices); - //Load the texture coordinate + /* Load the texture coordinate */ glVertexAttribPointer (attr_texture_loc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &v_vertices[3]); @@ -511,7 +545,6 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, glDisableVertexAttribArray (attr_position_loc); glDisableVertexAttribArray (attr_texture_loc); -#endif glDisable (GL_DEPTH_TEST); @@ -519,3 +552,4 @@ gst_gl_filter_cube_callback (gint width, gint height, guint texture, yrot += 0.2f; zrot += 0.4f; } +#endif diff --git a/gst/gl/gstglfiltercube.h b/gst/gl/gstglfiltercube.h index f42953bc5b4..18338181430 100644 --- a/gst/gl/gstglfiltercube.h +++ b/gst/gl/gstglfiltercube.h @@ -39,16 +39,14 @@ struct _GstGLFilterCube { GstGLFilter filter; -#ifdef OPENGL_ES2 GstGLShader *shader; -#endif - //background color + /* background color */ gfloat red; gfloat green; gfloat blue; - //perspective + /* perspective */ gdouble fovy; gdouble aspect; gdouble znear; diff --git a/gst/gl/gstopengl.c b/gst/gl/gstopengl.c index 86b0ecb83a4..001b4632d2b 100644 --- a/gst/gl/gstopengl.c +++ b/gst/gl/gstopengl.c @@ -51,7 +51,7 @@ GType gst_gl_filter_cube_get_type (void); GType gst_gl_effects_get_type (void); -#ifndef OPENGL_ES2 +#if HAVE_OPENGL #include "gstgltestsrc.h" #include "gstglfilterlaplacian.h" #include "gstglfilterglass.h" @@ -72,21 +72,21 @@ GType gst_gl_filter_laplacian_get_type (void); GType gst_gl_filter_glass_get_type (void); GType gst_gl_mosaic_get_type (void); -#ifdef HAVE_PNG +#if HAVE_PNG #include "gstgldifferencematte.h" #include "gstglbumper.h" GType gst_gl_differencematte_get_type (void); GType gst_gl_bumper_get_type (void); -#ifdef HAVE_JPEG +#if HAVE_JPEG #include "gstgloverlay.h" GType gst_gl_overlay_get_type (void); -#endif -#endif -#endif +#endif /* HAVE_JPEG */ +#endif /* HAVE_PNG */ +#endif /* HAVE_OPENGL */ #define GST_CAT_DEFAULT gst_gl_gstgl_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -111,7 +111,7 @@ plugin_init (GstPlugin * plugin) GST_RANK_NONE, gst_gl_effects_get_type ())) { return FALSE; } -#ifndef OPENGL_ES2 +#if HAVE_OPENGL if (!gst_element_register (plugin, "gltestsrc", GST_RANK_NONE, GST_TYPE_GL_TEST_SRC)) { return FALSE; @@ -166,7 +166,7 @@ plugin_init (GstPlugin * plugin) GST_RANK_NONE, GST_TYPE_GL_MOSAIC)) { return FALSE; } -#ifdef HAVE_PNG +#if HAVE_PNG if (!gst_element_register (plugin, "gldifferencematte", GST_RANK_NONE, gst_gl_differencematte_get_type ())) { return FALSE; @@ -176,14 +176,14 @@ plugin_init (GstPlugin * plugin) GST_RANK_NONE, gst_gl_bumper_get_type ())) { return FALSE; } -#ifdef HAVE_JPEG +#if HAVE_JPEG if (!gst_element_register (plugin, "gloverlay", GST_RANK_NONE, gst_gl_overlay_get_type ())) { return FALSE; } -#endif -#endif -#endif +#endif /* HAVE_JPEG */ +#endif /* HAVE_PNG */ +#endif /* HAVE_OPENGL */ return TRUE; } diff --git a/tests/check/pipelines/simple-launch-lines.c b/tests/check/pipelines/simple-launch-lines.c index 65a07a3336f..bf46c3a737f 100644 --- a/tests/check/pipelines/simple-launch-lines.c +++ b/tests/check/pipelines/simple-launch-lines.c @@ -154,7 +154,7 @@ GST_START_TEST (test_gleffects) GST_END_TEST #undef N_EFFECTS -#ifndef OPENGL_ES2 +#if HAVE_OPENGL #define N_SRCS 13 GST_START_TEST (test_gltestsrc) { @@ -311,7 +311,7 @@ GST_START_TEST (test_glfilterapp) GST_END_TEST #endif /* 0 */ -#endif /* !OPENGL_ES2 */ +#endif /* HAVE_OPENGL */ #endif /* !GST_DISABLE_PARSE */ Suite * simple_launch_lines_suite (void) { @@ -326,7 +326,7 @@ GST_END_TEST tcase_add_test (tc_chain, test_glimagesink); tcase_add_test (tc_chain, test_glfiltercube); tcase_add_test (tc_chain, test_gleffects); -#ifndef OPENGL_ES2 +#if HAVE_OPENGL tcase_add_test (tc_chain, test_gltestsrc); tcase_add_test (tc_chain, test_glfilterblur); tcase_add_test (tc_chain, test_glfiltersobel); @@ -345,7 +345,7 @@ GST_END_TEST #endif /* HAVE_JPEG */ #endif /* HAVE_PNG */ #endif -#endif /* !OPENGL_ES2 */ +#endif /* HAVE_OPENGL */ #endif /* !GST_DISABLE_PARSE */ return s; }