gl/memory: store the internal format as the texture format
authorMatthew Waters <matthew@centricular.com>
Wed, 14 Mar 2018 07:12:21 +0000 (18:12 +1100)
committerMatthew Waters <matthew@centricular.com>
Sat, 5 May 2018 11:24:25 +0000 (21:24 +1000)
Instead of having special cases at each GL texture creation, upload,
readback or copy for all non-8-bits-per-components.
Simply store the more specific format and retrieve the generic
component/type tuple from that.

Introduce a helper function for retrieving the generic GL format (RGBA,
RGB, RG, R, L, A) and type (BYTE, SHORT, SHORT_5_6_5) from a sized
GL format enum (RGBA8, RGB565, RG8, etc).

gst-libs/gst/gl/gstglformat.c
gst-libs/gst/gl/gstglformat.h
gst-libs/gst/gl/gstglmemory.c
gst-libs/gst/gl/gstglmemorypbo.c

index 8427be4..b12e882 100644 (file)
@@ -56,21 +56,26 @@ _gl_format_n_components (guint format)
   switch (format) {
     case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
     case GST_GL_RGBA:
+    case GST_GL_RGBA8:
       return 4;
     case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
     case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
     case GST_GL_RGB:
+    case GST_GL_RGB8:
     case GST_GL_RGB565:
       return 3;
     case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
     case GST_VIDEO_GL_TEXTURE_TYPE_RG:
     case GST_GL_LUMINANCE_ALPHA:
     case GST_GL_RG:
+    case GST_GL_RG8:
       return 2;
     case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
     case GST_VIDEO_GL_TEXTURE_TYPE_R:
     case GST_GL_LUMINANCE:
+    case GST_GL_ALPHA:
     case GST_GL_RED:
+    case GST_GL_R8:
       return 1;
     default:
       return 0;
@@ -159,6 +164,7 @@ gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
     case GST_VIDEO_FORMAT_RGB16:
     case GST_VIDEO_FORMAT_BGR16:
       return GST_GL_RGB565;
+      break;
     case GST_VIDEO_FORMAT_GRAY16_BE:
     case GST_VIDEO_FORMAT_GRAY16_LE:
     case GST_VIDEO_FORMAT_YUY2:
@@ -278,6 +284,59 @@ gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
 }
 
 /**
+ * gst_gl_format_type_from_sized_gl_format:
+ * @format: the sized internal #GstGLFormat
+ * @unsized_format: (out): location for the resulting unsized #GstGLFormat
+ * @gl_type: (out): location for the resulting GL type
+ *
+ * Get the unsized format and type from @format for usage in glReadPixels,
+ * glTex{Sub}Image*, glTexImage* and similar functions.
+ */
+void
+gst_gl_format_type_from_sized_gl_format (GstGLFormat format,
+    GstGLFormat * unsized_format, guint * gl_type)
+{
+  g_return_if_fail (unsized_format != NULL);
+  g_return_if_fail (gl_type != NULL);
+
+  switch (format) {
+    case GST_GL_RGBA8:
+      *unsized_format = GST_GL_RGBA;
+      *gl_type = GL_UNSIGNED_BYTE;
+      break;
+    case GST_GL_RGB8:
+      *unsized_format = GST_GL_RGB;
+      *gl_type = GL_UNSIGNED_BYTE;
+      break;
+    case GST_GL_RGB565:
+      *unsized_format = GST_GL_RGB;
+      *gl_type = GL_UNSIGNED_SHORT_5_6_5;
+      break;
+    case GST_GL_RG8:
+      *unsized_format = GST_GL_RG;
+      *gl_type = GL_UNSIGNED_BYTE;
+      break;
+    case GST_GL_R8:
+      *unsized_format = GST_GL_RED;
+      *gl_type = GL_UNSIGNED_BYTE;
+      break;
+    case GST_GL_RGBA:
+    case GST_GL_RGB:
+    case GST_GL_RG:
+    case GST_GL_RED:
+    case GST_GL_LUMINANCE:
+    case GST_GL_LUMINANCE_ALPHA:
+    case GST_GL_ALPHA:
+      *unsized_format = format;
+      *gl_type = GL_UNSIGNED_BYTE;
+      break;
+    default:
+      g_assert_not_reached ();
+      return;
+  }
+}
+
+/**
  * gst_gl_texture_target_to_string:
  * @target: a #GstGLTextureTarget
  *
index a799d40..a9f499f 100644 (file)
@@ -131,6 +131,10 @@ GST_GL_API
 guint                   gst_gl_sized_gl_format_from_gl_format_type  (GstGLContext * context,
                                                                      guint format,
                                                                      guint type);
+GST_GL_API
+void                    gst_gl_format_type_from_sized_gl_format     (GstGLFormat format,
+                                                                     GstGLFormat * unsized_format,
+                                                                     guint * gl_type);
 
 GST_GL_API
 GstGLTextureTarget      gst_gl_texture_target_from_string           (const gchar * str);
index 30d5f5e..bf9782d 100644 (file)
@@ -123,18 +123,16 @@ static inline void
 _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
 {
   guint n_gl_bytes;
-  guint tex_type;
+  guint tex_format, tex_type;
 
   gl_mem->tex_scaling[0] = 1.0f;
   gl_mem->tex_scaling[1] = 1.0f;
   gl_mem->unpack_length = 1;
   gl_mem->tex_width = GL_MEM_WIDTH (gl_mem);
 
-  tex_type = GL_UNSIGNED_BYTE;
-  if (gl_mem->tex_format == GST_GL_RGB565)
-    tex_type = GL_UNSIGNED_SHORT_5_6_5;
-
-  n_gl_bytes = gst_gl_format_type_n_bytes (gl_mem->tex_format, tex_type);
+  gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &tex_format,
+      &tex_type);
+  n_gl_bytes = gst_gl_format_type_n_bytes (tex_format, tex_type);
   if (n_gl_bytes == 0) {
     GST_ERROR ("Unsupported texture type %d", gl_mem->tex_format);
     return;
@@ -243,16 +241,9 @@ _gl_tex_create (GstGLMemory * gl_mem, GError ** error)
   GLenum tex_format;
   GLenum tex_type;
 
-  tex_format = gl_mem->tex_format;
-  tex_type = GL_UNSIGNED_BYTE;
-  if (gl_mem->tex_format == GST_GL_RGB565) {
-    tex_format = GST_GL_RGB;
-    tex_type = GL_UNSIGNED_SHORT_5_6_5;
-  }
-
-  internal_format =
-      gst_gl_sized_gl_format_from_gl_format_type (context, tex_format,
-      tex_type);
+  internal_format = gl_mem->tex_format;
+  gst_gl_format_type_from_sized_gl_format (internal_format, &tex_format,
+      &tex_type);
 
   if (!gl_mem->texture_wrapped) {
     gl_mem->tex_id =
@@ -363,10 +354,7 @@ gst_gl_memory_read_pixels (GstGLMemory * gl_mem, gpointer read_pointer)
   guint format, type;
   guint fbo;
 
-  format = gl_mem->tex_format;
-  type = GL_UNSIGNED_BYTE;
-  if (gl_mem->tex_format == GST_GL_RGB565)
-    type = GL_UNSIGNED_SHORT_5_6_5;
+  gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &format, &type);
 
   /* FIXME: avoid creating a framebuffer every download/copy */
   gl->GenFramebuffers (1, &fbo);
@@ -441,10 +429,8 @@ _gl_tex_download_get_tex_image (GstGLMemory * gl_mem, GstMapInfo * info,
     GST_CAT_TRACE (GST_CAT_GL_MEMORY, "attempting download of texture %u "
         "using glGetTexImage", gl_mem->tex_id);
 
-    format = gl_mem->tex_format;
-    type = GL_UNSIGNED_BYTE;
-    if (gl_mem->tex_format == GST_GL_RGB565)
-      type = GL_UNSIGNED_SHORT_5_6_5;
+    gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &format,
+        &type);
 
     target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
     gl->BindTexture (target, gl_mem->tex_id);
@@ -524,12 +510,8 @@ gst_gl_memory_texsubimage (GstGLMemory * gl_mem, gpointer read_pointer)
 
   gl = context->gl_vtable;
 
-  gl_type = GL_UNSIGNED_BYTE;
-  gl_format = gl_mem->tex_format;
-  if (gl_mem->tex_format == GST_GL_RGB565) {
-    gl_format = GST_GL_RGB;
-    gl_type = GL_UNSIGNED_SHORT_5_6_5;
-  }
+  gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &gl_format,
+      &gl_type);
 
   gl_target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
 
@@ -784,16 +766,9 @@ _gl_tex_copy_thread (GstGLContext * context, gpointer data)
     guint internal_format, out_gl_format, out_gl_type, out_tex_target;
 
     out_tex_target = gst_gl_texture_target_to_gl (copy_params->tex_target);
-    out_gl_format = copy_params->src->tex_format;
-    out_gl_type = GL_UNSIGNED_BYTE;
-    if (copy_params->out_format == GST_GL_RGB565) {
-      out_gl_format = GST_GL_RGB;
-      out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
-    }
-
-    internal_format =
-        gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
-        out_gl_type);
+    internal_format = copy_params->src->tex_format;
+    gst_gl_format_type_from_sized_gl_format (internal_format, &out_gl_format,
+        &out_gl_type);
 
     copy_params->tex_id =
         _new_texture (context, out_tex_target,
index 4a62a38..ced13df 100644 (file)
@@ -420,16 +420,11 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
   out_stride = copy_params->out_stride;
 
   gl = context->gl_vtable;
-  out_gl_format = copy_params->out_format;
-  out_gl_type = GL_UNSIGNED_BYTE;
-  if (copy_params->out_format == GST_GL_RGB565) {
-    out_gl_format = GST_GL_RGB;
-    out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
-  }
-  in_gl_format = src->mem.tex_format;
-  in_gl_type = GL_UNSIGNED_BYTE;
-  if (src->mem.tex_format == GST_GL_RGB565)
-    in_gl_type = GL_UNSIGNED_SHORT_5_6_5;
+
+  gst_gl_format_type_from_sized_gl_format (copy_params->out_format,
+      &out_gl_format, &out_gl_type);
+  gst_gl_format_type_from_sized_gl_format (src->mem.tex_format, &in_gl_format,
+      &in_gl_type);
 
   if (!gl->GenFramebuffers) {
     GST_CAT_ERROR (GST_CAT_GL_MEMORY,
@@ -450,21 +445,10 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
   }
 
   if (!tex_id) {
-    guint internal_format;
-    guint out_gl_type;
-
-    out_gl_type = GL_UNSIGNED_BYTE;
-    if (copy_params->out_format == GST_GL_RGB565)
-      out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
-
-    internal_format =
-        gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
-        out_gl_type);
-
     tex_id =
         _new_texture (context, out_tex_target,
-        internal_format, out_gl_format, out_gl_type, copy_params->out_width,
-        copy_params->out_height);
+        copy_params->out_format, out_gl_format, out_gl_type,
+        copy_params->out_width, copy_params->out_height);
   }
 
   if (!tex_id) {