gl: Only allow RGB(A)8 on GLES2
authorBenjamin Otte <otte@redhat.com>
Mon, 17 Apr 2023 03:42:19 +0000 (05:42 +0200)
committerBenjamin Otte <otte@redhat.com>
Mon, 17 Apr 2023 03:57:44 +0000 (05:57 +0200)
GLES2 has no idea what 16bit textures even are, let alone floating point.

gdk/gdkgltexture.c
gdk/gdkmemoryformat.c
gdk/gdkmemoryformatprivate.h
gsk/gl/gskglcommandqueue.c

index ece45ed28c9055d4e2ed82dbeddadcc4474a3805..bb727ce7e5658d1f69e073c904d2d753abdbf860 100644 (file)
@@ -131,6 +131,8 @@ struct _Download
 
 static gboolean
 gdk_gl_texture_find_format (gboolean         use_es,
+                            guint            gl_major,
+                            guint            gl_minor,
                             GLint            gl_format,
                             GLint            gl_type,
                             GdkMemoryFormat *out_format)
@@ -141,7 +143,7 @@ gdk_gl_texture_find_format (gboolean         use_es,
     {
       GLenum q_internal_format, q_format, q_type;
 
-      if (!gdk_memory_format_gl_format (format, use_es, &q_internal_format, &q_format, &q_type))
+      if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type))
         continue;
 
       if (q_format != gl_format || q_type != gl_type)
@@ -163,12 +165,14 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
   gsize expected_stride;
   Download *download = download_;
   GLenum gl_internal_format, gl_format, gl_type;
+  int major, minor;
 
   expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
+  gdk_gl_context_get_version (context, &major, &minor);
 
   if (download->stride == expected_stride &&
       !gdk_gl_context_get_use_es (context) &&
-      gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
+      gdk_memory_format_gl_format (download->format, TRUE, major, minor, &gl_internal_format, &gl_format, &gl_type))
     {
       glGetTexImage (GL_TEXTURE_2D,
                      0,
@@ -187,9 +191,10 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
       glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
       if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
         {
+          gdk_gl_context_get_version (context, &major, &minor);
           glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
           glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
-          if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), gl_read_format, gl_read_type, &actual_format))
+          if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), major, minor, gl_read_format, gl_read_type, &actual_format))
             actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
         }
       else
index 5bd7b228d40e7fe58244c7898311a99f6b03b552..5b7000e229c7c3fc6d0120038893c2b9620232d1 100644 (file)
@@ -220,7 +220,12 @@ struct _GdkMemoryFormatDescription
   gsize bytes_per_pixel;
   gsize alignment;
   gboolean prefers_high_depth;
-  gboolean supports_gles;
+  struct {
+    guint gl_major;
+    guint gl_minor;
+    guint gles_major;
+    guint gles_minor;
+  } min_gl_version;
   struct {
     guint internal_format;
     guint format;
@@ -245,7 +250,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    FALSE,
+    { 0, 0, G_MAXUINT, G_MAXUINT },
     { GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
     b8g8r8a8_premultiplied_to_float,
     b8g8r8a8_premultiplied_from_float,
@@ -255,7 +260,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    FALSE,
+    { 0, 0, G_MAXUINT, G_MAXUINT },
     { GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
     a8r8g8b8_premultiplied_to_float,
     a8r8g8b8_premultiplied_from_float,
@@ -265,7 +270,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    TRUE,
+    { 0, 0, 0, 0 },
     { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
     r8g8b8a8_premultiplied_to_float,
     r8g8b8a8_premultiplied_from_float,
@@ -275,7 +280,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    FALSE,
+    { 0, 0, G_MAXUINT, G_MAXUINT },
     { GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
     b8g8r8a8_to_float,
     b8g8r8a8_from_float,
@@ -285,7 +290,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    FALSE,
+    { 0, 0, G_MAXUINT, G_MAXUINT },
     { GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
     a8r8g8b8_to_float,
     a8r8g8b8_from_float,
@@ -295,7 +300,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    TRUE,
+    { 0, 0, 0, 0 },
     { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
     r8g8b8a8_to_float,
     r8g8b8a8_from_float,
@@ -305,7 +310,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     4,
     G_ALIGNOF (guchar),
     FALSE,
-    FALSE,
+    { 0, 0, G_MAXUINT, G_MAXUINT },
     { GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
     a8b8g8r8_to_float,
     a8b8g8r8_from_float,
@@ -315,7 +320,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     3,
     G_ALIGNOF (guchar),
     FALSE,
-    TRUE,
+    { 0, 0, 0, 0 },
     { GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE },
     r8g8b8_to_float,
     r8g8b8_from_float,
@@ -325,7 +330,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     3,
     G_ALIGNOF (guchar),
     FALSE,
-    FALSE,
+    { 0, 0, G_MAXUINT, G_MAXUINT },
     { GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE },
     b8g8r8_to_float,
     b8g8r8_from_float,
@@ -335,7 +340,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     6,
     G_ALIGNOF (guint16),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT },
     r16g16b16_to_float,
     r16g16b16_from_float,
@@ -345,7 +350,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     8,
     G_ALIGNOF (guint16),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
     r16g16b16a16_to_float,
     r16g16b16a16_from_float,
@@ -355,7 +360,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     8,
     G_ALIGNOF (guint16),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
     r16g16b16a16_to_float,
     r16g16b16a16_from_float,
@@ -365,7 +370,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     6,
     G_ALIGNOF (guint16),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGB16F, GL_RGB, GL_HALF_FLOAT },
     r16g16b16_float_to_float,
     r16g16b16_float_from_float,
@@ -375,7 +380,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     8,
     G_ALIGNOF (guint16),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
     r16g16b16a16_float_to_float,
     r16g16b16a16_float_from_float,
@@ -385,7 +390,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     8,
     G_ALIGNOF (guint16),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
     r16g16b16a16_float_to_float,
     r16g16b16a16_float_from_float,
@@ -395,7 +400,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     12,
     G_ALIGNOF (float),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGB32F, GL_RGB, GL_FLOAT },
     r32g32b32_float_to_float,
     r32g32b32_float_from_float,
@@ -405,7 +410,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     16,
     G_ALIGNOF (float),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGBA32F, GL_RGBA, GL_FLOAT },
     r32g32b32a32_float_to_float,
     r32g32b32a32_float_from_float,
@@ -415,7 +420,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     16,
     G_ALIGNOF (float),
     TRUE,
-    TRUE,
+    { 0, 0, 3, 0 },
     { GL_RGBA32F, GL_RGBA, GL_FLOAT },
     r32g32b32a32_float_to_float,
     r32g32b32a32_float_from_float,
@@ -463,6 +468,8 @@ gdk_memory_format_prefers_high_depth (GdkMemoryFormat format)
 gboolean
 gdk_memory_format_gl_format (GdkMemoryFormat  format,
                              gboolean         gles,
+                             guint            gl_major,
+                             guint            gl_minor,
                              guint           *out_internal_format,
                              guint           *out_format,
                              guint           *out_type)
@@ -474,8 +481,20 @@ gdk_memory_format_gl_format (GdkMemoryFormat  format,
   if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT)
     return FALSE;
 
-  if (gles && !memory_formats[format].supports_gles)
-    return FALSE;
+  if (gles)
+    {
+      if (memory_formats[format].min_gl_version.gles_major > gl_major ||
+          (memory_formats[format].min_gl_version.gles_major == gl_major &&
+           memory_formats[format].min_gl_version.gles_minor > gl_minor))
+        return FALSE;
+    }
+  else
+    {
+      if (memory_formats[format].min_gl_version.gl_major > gl_major ||
+          (memory_formats[format].min_gl_version.gl_major == gl_major &&
+           memory_formats[format].min_gl_version.gl_minor > gl_minor))
+        return FALSE;
+    }
 
   return TRUE;
 }
index 0d3a87b24deda07db6513974d9f0f5467af66db0..477baef25ed2cea50005ddd95fa04ab7d904c95c 100644 (file)
@@ -35,6 +35,8 @@ gsize                   gdk_memory_format_bytes_per_pixel   (GdkMemoryFormat
 gboolean                gdk_memory_format_prefers_high_depth(GdkMemoryFormat             format) G_GNUC_CONST;
 gboolean                gdk_memory_format_gl_format         (GdkMemoryFormat             format,
                                                              gboolean                    gles,
+                                                             guint                       gl_major,
+                                                             guint                       gl_minor,
                                                              guint                      *out_internal_format,
                                                              guint                      *out_format,
                                                              guint                      *out_type);
index 2a4f2c2d4894bcd2bf5ffc9c2700902841dfe6bd..3a0db1d5c3621954d64ca53095d797ae9ea7dbbf 100644 (file)
@@ -1429,28 +1429,44 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
 static GdkMemoryFormat
 memory_format_gl_format (GdkMemoryFormat  data_format,
                          gboolean         use_es,
+                         guint            major,
+                         guint            minor,
                          guint           *gl_internalformat,
                          guint           *gl_format,
                          guint           *gl_type)
 {
+  if (gdk_memory_format_gl_format (data_format,
+                                   use_es,
+                                   major,
+                                   minor,
+                                   gl_internalformat,
+                                   gl_format,
+                                   gl_type))
+    return data_format;
+
+  if (gdk_memory_format_prefers_high_depth (data_format))
+    {
+      data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
+      if (gdk_memory_format_gl_format (data_format,
+                                       use_es,
+                                       major,
+                                       minor,
+                                       gl_internalformat,
+                                       gl_format,
+                                       gl_type))
+        return data_format;
+    }
+
+  data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
   if (!gdk_memory_format_gl_format (data_format,
                                     use_es,
+                                    major,
+                                    minor,
                                     gl_internalformat,
                                     gl_format,
                                     gl_type))
     {
-      if (gdk_memory_format_prefers_high_depth (data_format))
-        data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
-      else
-        data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
-      if (!gdk_memory_format_gl_format (data_format,
-                                        use_es,
-                                        gl_internalformat,
-                                        gl_format,
-                                        gl_type))
-        {
-          g_assert_not_reached ();
-        }
+      g_assert_not_reached ();
     }
 
   return data_format;
@@ -1462,7 +1478,6 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
                                               int                x,
                                               int                y)
 {
-  GdkGLContext *context;
   const guchar *data;
   gsize stride;
   GBytes *bytes;
@@ -1474,15 +1489,18 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
   GLenum gl_type;
   gsize bpp;
   gboolean use_es;
+  int major, minor;
 
-  context = gdk_gl_context_get_current ();
-  use_es = gdk_gl_context_get_use_es (context);
+  use_es = gdk_gl_context_get_use_es (self->context);
+  gdk_gl_context_get_version (self->context, &major, &minor);
   data_format = gdk_texture_get_format (texture);
   width = gdk_texture_get_width (texture);
   height = gdk_texture_get_height (texture);
 
   data_format = memory_format_gl_format (data_format,
                                          use_es,
+                                         major,
+                                         minor,
                                          &gl_internalformat,
                                          &gl_format,
                                          &gl_type);
@@ -1504,7 +1522,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
       glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, data);
     }
   else if (stride % bpp == 0 &&
-           (gdk_gl_context_check_version (context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
+           (gdk_gl_context_check_version (self->context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (self->context)))
     {
       glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
 
@@ -1536,6 +1554,7 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue    *self,
   GLenum gl_type;
   gboolean use_es;
   int texture_id;
+  int major, minor;
 
   g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
 
@@ -1568,10 +1587,13 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue    *self,
   glBindTexture (GL_TEXTURE_2D, texture_id);
 
   /* Initialize the texture */
-  use_es = gdk_gl_context_get_use_es (gdk_gl_context_get_current ());
+  use_es = gdk_gl_context_get_use_es (self->context);
+  gdk_gl_context_get_version (self->context, &major, &minor);
   data_format = gdk_texture_get_format (chunks[0].texture);
   memory_format_gl_format (data_format,
                            use_es,
+                           major,
+                           minor,
                            &gl_internalformat,
                            &gl_format,
                            &gl_type);