[vlc-devel] [PATCH 2/4] opengl: Make the ES1/ES2 video outputs compileable

Martin Storsjö martin at martin.st
Tue Mar 12 19:02:07 CET 2013


This mostly consists of ifdeffing out parts selectively from
opengl.c based on whether shaders or the fixed pipeline are
absent.

Both the ES1 and ES2 outputs have been tested on Ubuntu on
a pandaboard. They seem to mostly work fine, but overlay
subpictures seem garbled.

---
I'm not exactly sure of what the comments about these being
broken/unfinished refer to, but with this patch it seems to
work reasonably well for me at least. I'm aware that there
have been other patchsets before trying to finish these vouts,
I didn't look up what the blocking issues were at that point.

Felix, can you check to make sure it doesn't break the vout on
iOS, where I assume this code actually is used with ES2. (Also,
do subtitle subpictures work properly there?) And also on some
plain-GL normal desktop...
---
 configure.ac                    |    8 ++---
 modules/video_output/Modules.am |    2 +-
 modules/video_output/gl.c       |    1 -
 modules/video_output/opengl.c   |   67 +++++++++++++++++++++++++++++++++++++--
 4 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8068ddc..321258e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2897,10 +2897,10 @@ PKG_CHECK_MODULES([GL], [gl], [
   ])
 ])
 
-dnl OpenGL ES 2: depends on EGL 1.1 and is currently unfinished
-dnl PKG_ENABLE_MODULES_VLC([GLES2], [], [glesv2], [OpenGL ES v2 support], [auto])
-dnl OpenGL ES 1: depends on EGL 1.0 and is currently broken
-dnl PKG_ENABLE_MODULES_VLC([GLES1], [], [glesv1_cm], [OpenGL ES v1 support], [auto])
+dnl OpenGL ES 2: depends on EGL 1.1
+PKG_ENABLE_MODULES_VLC([GLES2], [], [glesv2], [OpenGL ES v2 support], [auto])
+dnl OpenGL ES 1: depends on EGL 1.0
+PKG_ENABLE_MODULES_VLC([GLES1], [], [glesv1_cm], [OpenGL ES v1 support], [auto])
 
 AC_ARG_ENABLE(egl,
   [  --enable-egl            OpenGL support through EGL (default disabled)],, [
diff --git a/modules/video_output/Modules.am b/modules/video_output/Modules.am
index db20784..55b72fb 100644
--- a/modules/video_output/Modules.am
+++ b/modules/video_output/Modules.am
@@ -36,7 +36,7 @@ EXTRA_LTLIBRARIES += \
 	libgles1_plugin.la \
 	libgl_plugin.la
 libvlc_LTLIBRARIES += \
-	$(LTLIBgl)
+	$(LTLIBgles2) $(LTLIBgles1) $(LTLIBgl)
 
 
 ### XCB ###
diff --git a/modules/video_output/gl.c b/modules/video_output/gl.c
index 2e39073..b31b3ac 100644
--- a/modules/video_output/gl.c
+++ b/modules/video_output/gl.c
@@ -45,7 +45,6 @@ static void Close (vlc_object_t *);
 
 vlc_module_begin ()
 #if USE_OPENGL_ES == 2
-# error The OpenGL ES2 plugin is incomplete and not functional. FIXME.
 # define API VLC_OPENGL_ES2
 # define MODULE_VARNAME "gles2"
     set_shortname (N_("OpenGL ES2"))
diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index 4277581..193db2c 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -40,7 +40,7 @@
 # define GL_CLAMP_TO_EDGE 0x812F
 #endif
 
-#ifdef __APPLE__
+#if USE_OPENGL_ES == 2 || defined(__APPLE__)
 #   define PFNGLGETPROGRAMIVPROC             typeof(glGetProgramiv)*
 #   define PFNGLGETPROGRAMINFOLOGPROC        typeof(glGetProgramInfoLog)*
 #   define PFNGLGETSHADERIVPROC              typeof(glGetShaderiv)*
@@ -61,7 +61,7 @@
 #   define PFNGLUSEPROGRAMPROC               typeof(glUseProgram)*
 #   define PFNGLDELETEPROGRAMPROC            typeof(glDeleteProgram)*
 #   define PFNGLATTACHSHADERPROC             typeof(glAttachShader)*
-#if USE_OPENGL_ES
+#if defined(__APPLE__) && USE_OPENGL_ES
 #   import <CoreFoundation/CoreFoundation.h>
 #endif
 #endif
@@ -71,11 +71,20 @@
 #   define VLCGL_TEXTURE_COUNT 1
 #   define VLCGL_PICTURE_MAX 1
 #   define PRECISION "precision highp float;"
+#if USE_OPENGL_ES == 2
+#   define SUPPORTS_SHADERS
+#   define glClientActiveTexture(x)
+#else
+#   define SUPPORTS_FIXED_PIPELINE
+#   define GL_MAX_TEXTURE_IMAGE_UNITS GL_MAX_TEXTURE_UNITS
+#endif
 #else
 #   define GLSL_VERSION "120"
 #   define VLCGL_TEXTURE_COUNT 1
 #   define VLCGL_PICTURE_MAX 128
 #   define PRECISION ""
+#   define SUPPORTS_SHADERS
+#   define SUPPORTS_FIXED_PIPELINE
 #endif
 
 static const vlc_fourcc_t gl_subpicture_chromas[] = {
@@ -128,6 +137,7 @@ struct vout_display_opengl_t {
     GLfloat    local_value[16];
 
     /* Shader variables commands*/
+#ifdef SUPPORTS_SHADERS
     PFNGLGETUNIFORMLOCATIONPROC      GetUniformLocation;
     PFNGLGETATTRIBLOCATIONPROC       GetAttribLocation;
     PFNGLVERTEXATTRIBPOINTERPROC     VertexAttribPointer;
@@ -155,6 +165,7 @@ struct vout_display_opengl_t {
     PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
     PFNGLGETSHADERIVPROC   GetShaderiv;
     PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+#endif
 
 
     /* multitexture */
@@ -189,6 +200,7 @@ static bool IsLuminance16Supported(int target)
 }
 #endif
 
+#ifdef SUPPORTS_SHADERS
 static void BuildVertexShader(vout_display_opengl_t *vgl,
                               GLint *shader)
 {
@@ -322,6 +334,7 @@ static void BuildRGBAFragmentShader(vout_display_opengl_t *vgl,
     vgl->ShaderSource(*shader, 1, &code, NULL);
     vgl->CompileShader(*shader);
 }
+#endif
 
 vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
                                                const vlc_fourcc_t **subpicture_chromas,
@@ -351,6 +364,33 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     bool supports_shaders = false;
 #endif
 
+#if USE_OPENGL_ES == 2
+    vgl->CreateShader  = glCreateShader;
+    vgl->ShaderSource  = glShaderSource;
+    vgl->CompileShader = glCompileShader;
+    vgl->AttachShader  = glAttachShader;
+
+    vgl->GetProgramiv  = glGetProgramiv;
+    vgl->GetShaderiv   = glGetShaderiv;
+    vgl->GetProgramInfoLog  = glGetProgramInfoLog;
+    vgl->GetShaderInfoLog   = glGetShaderInfoLog;
+
+    vgl->DeleteShader  = glDeleteShader;
+
+    vgl->GetUniformLocation = glGetUniformLocation;
+    vgl->GetAttribLocation  = glGetAttribLocation;
+    vgl->VertexAttribPointer= glVertexAttribPointer;
+    vgl->EnableVertexAttribArray = glEnableVertexAttribArray;
+    vgl->Uniform4fv    = glUniform4fv;
+    vgl->Uniform4f     = glUniform4f;
+    vgl->Uniform1i     = glUniform1i;
+
+    vgl->CreateProgram = glCreateProgram;
+    vgl->LinkProgram   = glLinkProgram;
+    vgl->UseProgram    = glUseProgram;
+    vgl->DeleteProgram = glDeleteProgram;
+    supports_shaders = true;
+#elif defined(SUPPORTS_SHADERS)
     vgl->CreateShader  = (PFNGLCREATESHADERPROC)vlc_gl_GetProcAddress(vgl->gl, "glCreateShader");
     vgl->ShaderSource  = (PFNGLSHADERSOURCEPROC)vlc_gl_GetProcAddress(vgl->gl, "glShaderSource");
     vgl->CompileShader = (PFNGLCOMPILESHADERPROC)vlc_gl_GetProcAddress(vgl->gl, "glCompileShader");
@@ -378,6 +418,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
 
     if (!vgl->CreateShader || !vgl->ShaderSource || !vgl->CreateProgram)
         supports_shaders = false;
+#endif
 
     vgl->supports_npot = HasExtension(extensions, "GL_ARB_texture_non_power_of_two") ||
                          HasExtension(extensions, "GL_APPLE_texture_2D_limited_npot");
@@ -474,6 +515,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     vgl->shader[2] = -1;
     vgl->local_count = 0;
     if (supports_shaders && need_fs_yuv) {
+#ifdef SUPPORTS_SHADERS
         BuildYUVFragmentShader(vgl, &vgl->shader[0], &vgl->local_count,
                                vgl->local_value, fmt, yuv_range_correction);
         BuildRGBAFragmentShader(vgl, &vgl->shader[1]);
@@ -524,6 +566,7 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
                 return NULL;
             }
         }
+#endif
     }
 
     /* */
@@ -566,12 +609,14 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
         }
         free(vgl->region);
 
+#ifdef SUPPORTS_SHADERS
         if (vgl->program[0]) {
             for (int i = 0; i < 2; i++)
                 vgl->DeleteProgram(vgl->program[i]);
             for (int i = 0; i < 3; i++)
                 vgl->DeleteShader(vgl->shader[i]);
         }
+#endif
 
         vlc_gl_Unlock(vgl->gl);
     }
@@ -788,6 +833,7 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
     return VLC_SUCCESS;
 }
 
+#ifdef SUPPORTS_FIXED_PIPELINE
 static void DrawWithoutShaders(vout_display_opengl_t *vgl,
                                float *left, float *top, float *right, float *bottom)
 {
@@ -823,7 +869,9 @@ static void DrawWithoutShaders(vout_display_opengl_t *vgl,
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisable(vgl->tex_target);
 }
+#endif
 
+#ifdef SUPPORTS_SHADERS
 static void DrawWithShaders(vout_display_opengl_t *vgl,
                             float *left, float *top, float *right, float *bottom)
 {
@@ -864,6 +912,7 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 }
+#endif
 
 int vout_display_opengl_Display(vout_display_opengl_t *vgl,
                                 const video_format_t *source)
@@ -900,16 +949,24 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
         bottom[j] = (source->i_y_offset + source->i_visible_height) * scale_h;
     }
 
+#ifdef SUPPORTS_SHADERS
     if (vgl->program[0])
         DrawWithShaders(vgl, left, top ,right, bottom);
     else
+#endif
+    {
+#ifdef SUPPORTS_FIXED_PIPELINE
         DrawWithoutShaders(vgl, left, top, right, bottom);
+#endif
+    }
 
     /* Draw the subpictures */
     if (vgl->program[1]) {
+#ifdef SUPPORTS_SHADERS
         // Change the program for overlays
         vgl->UseProgram(vgl->program[1]);
         vgl->Uniform1i(vgl->GetUniformLocation(vgl->program[1], "Texture"), 0);
+#endif
     }
 
     glEnable(GL_TEXTURE_2D);
@@ -935,24 +992,30 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
 
         glBindTexture(GL_TEXTURE_2D, glr->texture);
         if (vgl->program[1]) {
+#ifdef SUPPORTS_SHADERS
             vgl->Uniform4f(vgl->GetUniformLocation(vgl->program[1], "FillColor"), 1.0f, 1.0f, 1.0f, glr->alpha);
             vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[1], "MultiTexCoord0"));
             vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "MultiTexCoord0"), 2, GL_FLOAT, 0, 0, textureCoord);
             vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"));
             vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord);
+#endif
         } else {
+#ifdef SUPPORTS_FIXED_PIPELINE
             glEnableClientState(GL_VERTEX_ARRAY);
             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
             glColor4f(1.0f, 1.0f, 1.0f, glr->alpha);
             glTexCoordPointer(2, GL_FLOAT, 0, textureCoord);
             glVertexPointer(2, GL_FLOAT, 0, vertexCoord);
+#endif
         }
 
         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
         if (!vgl->program[1]) {
+#ifdef SUPPORTS_FIXED_PIPELINE
             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
             glDisableClientState(GL_VERTEX_ARRAY);
+#endif
         }
     }
     glDisable(GL_BLEND);
-- 
1.7.10.4




More information about the vlc-devel mailing list