[vlc-commits] vout/opengl: use GL_UNPACK_ROW_LENGTH with OpenGLES 2

Thomas Guillem git at videolan.org
Fri Jan 6 10:27:35 CET 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Jan  6 10:22:54 2017 +0100| [f7ba7eddb69d4e179e361a182a505c3332e9ed84] | committer: Thomas Guillem

vout/opengl: use GL_UNPACK_ROW_LENGTH with OpenGLES 2

GL_UNPACK_ROW_LENGTH is also available with OpenGLES 2 if it has the
"GL_EXT_unpack_subimage" extension.

This avoids an extra memcpy of the video buffer in some corner cases.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f7ba7eddb69d4e179e361a182a505c3332e9ed84
---

 modules/video_output/opengl/converters.c | 78 +++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 31 deletions(-)

diff --git a/modules/video_output/opengl/converters.c b/modules/video_output/opengl/converters.c
index 8b6b4b4..080064b 100644
--- a/modules/video_output/opengl/converters.c
+++ b/modules/video_output/opengl/converters.c
@@ -35,16 +35,20 @@
 #define GL_R16 0
 #endif
 
+#ifndef GL_UNPACK_ROW_LENGTH
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define NEED_GL_EXT_unpack_subimage
+#endif
+
 struct priv
 {
     GLint  tex_internal;
     GLenum tex_format;
     GLenum tex_type;
 
-#ifndef GL_UNPACK_ROW_LENGTH
+    bool   has_unpack_subimage;
     void * texture_temp_buf;
     size_t texture_temp_buf_size;
-#endif
 };
 
 struct yuv_priv
@@ -106,42 +110,48 @@ upload_plane(const opengl_tex_converter_t *tc,
     /* This unpack alignment is the default, but setting it just in case. */
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
-#ifndef GL_UNPACK_ROW_LENGTH
-# define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
-    unsigned dst_width = width;
-    unsigned dst_pitch = ALIGN(dst_width * pixel_pitch, 4);
-    if (pitch != dst_pitch)
+    if (!priv->has_unpack_subimage)
     {
-        size_t buf_size = dst_pitch * height * pixel_pitch;
-        const uint8_t *source = pixels;
-        uint8_t *destination;
-        if (priv->texture_temp_buf_size < buf_size)
+#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
+        unsigned dst_width = width;
+        unsigned dst_pitch = ALIGN(dst_width * pixel_pitch, 4);
+        if (pitch != dst_pitch)
         {
-            priv->texture_temp_buf =
-                realloc_or_free(priv->texture_temp_buf, buf_size);
-            if (priv->texture_temp_buf == NULL)
+            size_t buf_size = dst_pitch * height * pixel_pitch;
+            const uint8_t *source = pixels;
+            uint8_t *destination;
+            if (priv->texture_temp_buf_size < buf_size)
             {
-                priv->texture_temp_buf_size = 0;
-                return VLC_ENOMEM;
+                priv->texture_temp_buf =
+                    realloc_or_free(priv->texture_temp_buf, buf_size);
+                if (priv->texture_temp_buf == NULL)
+                {
+                    priv->texture_temp_buf_size = 0;
+                    return VLC_ENOMEM;
+                }
+                priv->texture_temp_buf_size = buf_size;
             }
-            priv->texture_temp_buf_size = buf_size;
-        }
-        destination = priv->texture_temp_buf;
+            destination = priv->texture_temp_buf;
 
-        for (unsigned h = 0; h < height ; h++)
+            for (unsigned h = 0; h < height ; h++)
+            {
+                memcpy(destination, source, width * pixel_pitch);
+                source += pitch;
+                destination += dst_pitch;
+            }
+            glTexSubImage2D(tex_target, 0, 0, 0, width, height,
+                            tex_format, tex_type, priv->texture_temp_buf);
+        }
+        else
         {
-            memcpy(destination, source, width * pixel_pitch);
-            source += pitch;
-            destination += dst_pitch;
+            glTexSubImage2D(tex_target, 0, 0, 0, width, height,
+                            tex_format, tex_type, pixels);
         }
-        glTexSubImage2D(tex_target, 0, 0, 0, width, height,
-                        tex_format, tex_type, priv->texture_temp_buf);
-    } else {
-# undef ALIGN
-#else
+#undef ALIGN
+    }
+    else
     {
         glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / pixel_pitch);
-#endif
         glTexSubImage2D(tex_target, 0, 0, 0, width, height,
                         tex_format, tex_type, pixels);
     }
@@ -176,10 +186,9 @@ tc_common_release(const opengl_tex_converter_t *tc)
 {
     tc->api->DeleteShader(tc->fragment_shader);
 
-#ifndef GL_UNPACK_ROW_LENGTH
     struct priv *priv = tc->priv;
     free(priv->texture_temp_buf);
-#endif
+
     free(tc->priv);
 }
 
@@ -205,6 +214,13 @@ common_init(opengl_tex_converter_t *tc, size_t priv_size, vlc_fourcc_t chroma,
     priv->tex_format    = tex_format;
     priv->tex_type      = tex_type;
 
+#ifdef NEED_GL_EXT_unpack_subimage
+    priv->has_unpack_subimage = HasExtension(tc->glexts,
+                                             "GL_EXT_unpack_subimage");
+#else
+    priv->has_unpack_subimage = true;
+#endif
+
     return VLC_SUCCESS;
 }
 



More information about the vlc-commits mailing list