[gtk/wip/otte/float-textures: 7/12] gl: Implement uploading and downloading HDR formats




commit e869578725f733414d037d372551352fa66acb42
Author: Benjamin Otte <otte redhat com>
Date:   Sun Sep 12 05:04:32 2021 +0200

    gl: Implement uploading and downloading HDR formats
    
    Also refactor the GL uploading so it does the fallback in a
    GLES-compatible way, which means we only need one fallback.

 gdk/gdkglcontext.c | 125 ++++++++++++++++++++++++++++++-----------------------
 gdk/gdkgltexture.c |  36 +++++++++++++++
 2 files changed, 108 insertions(+), 53 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index f957d9c1c5..76be3c7ef9 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -229,64 +229,83 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
 {
   GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
   guchar *copy = NULL;
-  guint gl_format;
-  guint gl_type;
-  guint bpp;
+  GLint gl_internalformat;
+  GLint gl_format;
+  GLint gl_type;
+  gsize bpp;
 
   g_return_if_fail (GDK_IS_GL_CONTEXT (context));
 
-  if (priv->use_es)
+  if (!priv->use_es && data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
     {
-      /* GLES only supports rgba, so convert if necessary */
-      if (data_format != GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
-        {
-          copy = g_malloc (width * height * 4);
-          gdk_memory_convert (copy, width * 4,
-                              GDK_MEMORY_CONVERT_GLES_RGBA,
-                              data, stride, data_format,
-                              width, height);
-          stride = width * 4;
-          data = copy;
-        }
-
-      bpp = 4;
-      gl_format = GL_RGBA;
+      gl_internalformat = GL_RGBA8;
+      gl_format = GL_BGRA;
+      gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+    }
+  else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */
+    {
+      gl_internalformat = GL_RGBA8;
+      gl_format = GL_RGB;
       gl_type = GL_UNSIGNED_BYTE;
     }
-  else
+  else if (priv->use_es && data_format == GDK_MEMORY_B8G8R8)
     {
-      if (data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
-        {
-          gl_format = GL_BGRA;
-          gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-          bpp = 4;
-        }
-      else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */
-        {
-          gl_format = GL_RGB;
-          gl_type = GL_UNSIGNED_BYTE;
-          bpp = 3;
-        }
-      else if (data_format == GDK_MEMORY_B8G8R8)
-        {
-          gl_format = GL_BGR;
-          gl_type = GL_UNSIGNED_BYTE;
-          bpp = 3;
-        }
-      else /* Fall-back, convert to cairo-surface-format */
-        {
-          copy = g_malloc (width * height * 4);
-          gdk_memory_convert (copy, width * 4,
-                              GDK_MEMORY_CONVERT_DOWNLOAD,
-                              data, stride, data_format,
-                              width, height);
-          stride = width * 4;
-          bpp = 4;
-          data = copy;
-          gl_format = GL_BGRA;
-          gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-        }
+      gl_internalformat = GL_RGBA8;
+      gl_format = GL_BGR;
+      gl_type = GL_UNSIGNED_BYTE;
+    }
+  else if (data_format == GDK_MEMORY_R16G16B16)
+    {
+      gl_internalformat = GL_RGBA16;
+      gl_format = GL_RGB;
+      gl_type = GL_UNSIGNED_SHORT;
     }
+  else if (data_format == GDK_MEMORY_R16G16B16A16_PREMULTIPLIED)
+    {
+      gl_internalformat = GL_RGBA16;
+      gl_format = GL_RGBA;
+      gl_type = GL_UNSIGNED_SHORT;
+    }
+  else if (data_format == GDK_MEMORY_R16G16B16_FLOAT)
+    {
+      gl_internalformat = GL_RGB16F;
+      gl_format = GL_RGB;
+      gl_type = GL_HALF_FLOAT;
+    }
+  else if (data_format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED)
+    {
+      gl_internalformat = GL_RGBA16F;
+      gl_format = GL_RGBA;
+      gl_type = GL_HALF_FLOAT;
+    }
+  else if (data_format == GDK_MEMORY_R32G32B32_FLOAT)
+    {
+      gl_internalformat = GL_RGB32F;
+      gl_format = GL_RGB;
+      gl_type = GL_FLOAT;
+    }
+  else if (data_format == GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED)
+    {
+      gl_internalformat = GL_RGBA32F;
+      gl_format = GL_RGBA;
+      gl_type = GL_FLOAT;
+    }
+  else /* Fall-back, convert to GLES format */
+    {
+      copy = g_malloc (width * height * 4);
+      gdk_memory_convert (copy, width * 4,
+                          GDK_MEMORY_CONVERT_GLES_RGBA,
+                          data, stride, data_format,
+                          width, height);
+      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
+      stride = width * 4;
+      data = copy;
+      gl_internalformat = GL_RGBA8;
+      gl_format = GL_RGBA;
+      gl_type = GL_UNSIGNED_BYTE;
+    }
+
+  bpp = gdk_memory_format_bytes_per_pixel (data_format);
 
   /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
    * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
@@ -295,7 +314,7 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
     {
       glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
 
-      glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
+      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
       glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
     }
   else if ((!priv->use_es ||
@@ -303,14 +322,14 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
     {
       glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
 
-      glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
+      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
 
       glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
     }
   else
     {
       int i;
-      glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, NULL);
+      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
       for (i = 0; i < height; i++)
         glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
     }
diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c
index 365a3a6ac2..6c91c70f70 100644
--- a/gdk/gdkgltexture.c
+++ b/gdk/gdkgltexture.c
@@ -105,6 +105,42 @@ gdk_gl_texture_download_texture (GdkTexture *texture)
       gl_type = GL_UNSIGNED_BYTE;
       break;
 
+    case GL_RGB16:
+      format = GDK_MEMORY_R16G16B16;
+      gl_format = GL_RGB;
+      gl_type = GL_UNSIGNED_SHORT;
+      break;
+
+    case GL_RGBA16:
+      format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
+      gl_format = GL_RGBA;
+      gl_type = GL_UNSIGNED_SHORT;
+      break;
+
+    case GL_RGB16F:
+      format = GDK_MEMORY_R16G16B16_FLOAT;
+      gl_format = GL_RGB;
+      gl_type = GL_HALF_FLOAT;
+      break;
+
+    case GL_RGBA16F:
+      format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
+      gl_format = GL_RGBA;
+      gl_type = GL_HALF_FLOAT;
+      break;
+
+    case GL_RGB32F:
+      format = GDK_MEMORY_R32G32B32_FLOAT;
+      gl_format = GL_RGB;
+      gl_type = GL_FLOAT;
+      break;
+
+    case GL_RGBA32F:
+      format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
+      gl_format = GL_RGBA;
+      gl_type = GL_FLOAT;
+      break;
+
     default:
       g_warning ("Texture in unexpected format 0x%X (%d). File a bug about adding it to GTK", 
internal_format, internal_format);
       /* fallback to the dumbest possible format


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]