gl/memory: implement GL_EXT_texture_rg support
authorMatthew Waters <ystreet00@gmail.com>
Wed, 21 May 2014 11:47:45 +0000 (21:47 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:41 +0000 (19:31 +0000)
Which is used by default over the Luminance formats due to it
being color renderable with fbos (and deprecation/removal with
GL 3.x).

https://bugzilla.gnome.org/show_bug.cgi?id=729750
https://bugzilla.gnome.org/show_bug.cgi?id=704222
https://bugzilla.gnome.org/show_bug.cgi?id=728890

gst-libs/gst/gl/gstglcolorconvert.c
gst-libs/gst/gl/gstglmemory.c
gst-libs/gst/gl/gstglmemory.h
gst-libs/gst/gl/gstglupload.c

index 5882057..fa57def 100644 (file)
@@ -694,6 +694,9 @@ _YUV_to_RGB (GstGLColorConvert * convert)
   GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
   const gchar *out_format_str = gst_video_format_to_string (out_format);
   gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str);
+  gboolean texture_rg =
+      gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
+      || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg");
 
   info->out_n_textures = 1;
 
@@ -737,21 +740,29 @@ _YUV_to_RGB (GstGLColorConvert * convert)
           GST_VIDEO_INFO_PLANE_STRIDE (&convert->in_info, 0));
       break;
     case GST_VIDEO_FORMAT_NV12:
-      info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, 'r', 'a',
+    {
+      char val2 = texture_rg ? 'g' : 'a';
+      info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, 'r', val2,
           pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
       info->in_n_textures = 2;
       info->shader_tex_names[0] = "Ytex";
       info->shader_tex_names[1] = "UVtex";
       break;
+    }
     case GST_VIDEO_FORMAT_NV21:
-      info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, 'a', 'r',
+    {
+      char val2 = texture_rg ? 'g' : 'a';
+      info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, val2, 'r',
           pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
       info->in_n_textures = 2;
       info->shader_tex_names[0] = "Ytex";
       info->shader_tex_names[1] = "UVtex";
       break;
+    }
     case GST_VIDEO_FORMAT_UYVY:
-      info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, 'a', 'r', 'b',
+    {
+      char y_val = texture_rg ? 'g' : 'a';
+      info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, y_val, 'r', 'b',
           pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
       info->in_n_textures = 1;
       info->shader_tex_names[0] = "Ytex";
@@ -763,6 +774,7 @@ _YUV_to_RGB (GstGLColorConvert * convert)
           GST_VIDEO_INFO_HEIGHT (&convert->in_info),
           GST_VIDEO_INFO_PLANE_STRIDE (&convert->in_info, 0));
       break;
+    }
     default:
       break;
   }
@@ -885,6 +897,9 @@ _GRAY_to_RGB (GstGLColorConvert * convert)
   GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
   const gchar *out_format_str = gst_video_format_to_string (out_format);
   gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str);
+  gboolean texture_rg =
+      gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
+      || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg");
 
   info->in_n_textures = 1;
   info->out_n_textures = 1;
@@ -893,16 +908,22 @@ _GRAY_to_RGB (GstGLColorConvert * convert)
   switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) {
     case GST_VIDEO_FORMAT_GRAY8:
       info->frag_prog = g_strdup_printf (frag_REORDER, "", pixel_order[0],
-          pixel_order[1], pixel_order[2], pixel_order[3]);
+          pixel_order[0], pixel_order[0], pixel_order[3]);
       break;
     case GST_VIDEO_FORMAT_GRAY16_LE:
-      info->frag_prog = g_strdup_printf (frag_COMPOSE, 'a', 'r',
+    {
+      char val2 = texture_rg ? 'g' : 'a';
+      info->frag_prog = g_strdup_printf (frag_COMPOSE, val2, 'r',
           pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
       break;
+    }
     case GST_VIDEO_FORMAT_GRAY16_BE:
-      info->frag_prog = g_strdup_printf (frag_COMPOSE, 'r', 'a',
+    {
+      char val2 = texture_rg ? 'g' : 'a';
+      info->frag_prog = g_strdup_printf (frag_COMPOSE, 'r', val2,
           pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
       break;
+    }
     default:
       break;
   }
index 45d4c1c..5ff8035 100644 (file)
@@ -181,8 +181,14 @@ _gl_texture_type_n_bytes (GstVideoGLTextureType tex_format)
 }
 
 GstVideoGLTextureType
-gst_gl_texture_type_from_format (GstVideoFormat v_format, guint plane)
+gst_gl_texture_type_from_format (GstGLContext * context,
+    GstVideoFormat v_format, guint plane)
 {
+  gboolean texture_rg =
+      gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
+      || gst_gl_context_check_feature (context, "GL_ARB_texture_rg");
+  guint n_plane_components;
+
   switch (v_format) {
     case GST_VIDEO_FORMAT_RGBx:
     case GST_VIDEO_FORMAT_BGRx:
@@ -193,40 +199,56 @@ gst_gl_texture_type_from_format (GstVideoFormat v_format, guint plane)
     case GST_VIDEO_FORMAT_ARGB:
     case GST_VIDEO_FORMAT_ABGR:
     case GST_VIDEO_FORMAT_AYUV:
-      return GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
+      n_plane_components = 4;
       break;
     case GST_VIDEO_FORMAT_RGB:
     case GST_VIDEO_FORMAT_BGR:
-      return GST_VIDEO_GL_TEXTURE_TYPE_RGB;
-      break;
-    case GST_VIDEO_FORMAT_GRAY8:
-      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
+      n_plane_components = 3;
       break;
     case GST_VIDEO_FORMAT_GRAY16_BE:
     case GST_VIDEO_FORMAT_GRAY16_LE:
-      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
-      break;
     case GST_VIDEO_FORMAT_YUY2:
     case GST_VIDEO_FORMAT_UYVY:
-      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
+      n_plane_components = 2;
       break;
     case GST_VIDEO_FORMAT_NV12:
     case GST_VIDEO_FORMAT_NV21:
-      if (plane == 0)
-        return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
-      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
+      n_plane_components = plane == 0 ? 1 : 2;
       break;
+    case GST_VIDEO_FORMAT_GRAY8:
     case GST_VIDEO_FORMAT_Y444:
     case GST_VIDEO_FORMAT_Y42B:
     case GST_VIDEO_FORMAT_Y41B:
     case GST_VIDEO_FORMAT_I420:
     case GST_VIDEO_FORMAT_YV12:
-      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
+      n_plane_components = 1;
       break;
     default:
+      n_plane_components = 4;
       g_assert_not_reached ();
       break;
   }
+
+  switch (n_plane_components) {
+    case 4:
+      return GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
+      break;
+    case 3:
+      return GST_VIDEO_GL_TEXTURE_TYPE_RGB;
+      break;
+    case 2:
+      return texture_rg ? GST_VIDEO_GL_TEXTURE_TYPE_RG :
+          GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
+      break;
+    case 1:
+      return texture_rg ? GST_VIDEO_GL_TEXTURE_TYPE_R :
+          GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+
   return GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
 }
 
@@ -1041,7 +1063,8 @@ gst_gl_memory_setup_buffer (GstGLContext * context, GstVideoInfo * info,
 
   for (i = 0; i < n_mem; i++) {
     tex_type =
-        gst_gl_texture_type_from_format (GST_VIDEO_INFO_FORMAT (info), i);
+        gst_gl_texture_type_from_format (context, GST_VIDEO_INFO_FORMAT (info),
+        i);
     gl_mem[i] =
         (GstGLMemory *) gst_gl_memory_alloc (context, tex_type,
         _get_plane_width (info, i), _get_plane_height (info, i),
@@ -1079,7 +1102,8 @@ gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo * info,
 
   for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
     tex_type =
-        gst_gl_texture_type_from_format (GST_VIDEO_INFO_FORMAT (info), i);
+        gst_gl_texture_type_from_format (context, GST_VIDEO_INFO_FORMAT (info),
+        i);
 
     textures[i] = (GstGLMemory *) gst_gl_memory_wrapped (context, tex_type,
         _get_plane_width (info, i), _get_plane_height (info, i),
index 535bea7..82c9e88 100644 (file)
@@ -173,7 +173,7 @@ gboolean      gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo
                                            gpointer data[GST_VIDEO_MAX_PLANES],
                                            GstGLMemory *textures[GST_VIDEO_MAX_PLANES]);
 
-GstVideoGLTextureType gst_gl_texture_type_from_format (GstVideoFormat v_format, guint plane);
+GstVideoGLTextureType gst_gl_texture_type_from_format (GstGLContext *context, GstVideoFormat v_format, guint plane);
 
 /**
  * GstGLAllocator
index fb87153..f775083 100644 (file)
@@ -568,7 +568,7 @@ gst_gl_upload_add_video_gl_texture_upload_meta (GstGLUpload * upload,
   upload->priv->buffer = buffer;
 
   for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
-    texture_types[i] = gst_gl_texture_type_from_format (v_meta->format, i);
+    texture_types[i] = gst_gl_texture_type_from_format (upload->context, v_meta->format, i);
   }
 
   gst_buffer_add_video_gl_texture_upload_meta (buffer,