[gtk/gamma-shenanigans: 15/29] Support 32-bit floating point textures




commit dcde46ab30ab9415480a3660e6577c32ec898189
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Sep 9 06:36:06 2021 -0400

    Support 32-bit floating point textures
    
    Add R32G32B32_FLOAT and R32G32B32A32_FLOAT_PREMULTIPLIED
    formats which are using floats.
    
    The intention is to use these for HDR content.
    
    Not done here: Update memory texture tests
    to include floating point textures.

 gdk/gdkglcontext.c            | 14 ++++++++
 gdk/gdkgltexture.c            |  7 ++++
 gdk/gdkmemorytexture.c        | 74 +++++++++++++++++++++++++++++++++++++++++--
 gdk/gdkmemorytexture.h        |  7 ++++
 testsuite/gdk/memorytexture.c |  4 ++-
 5 files changed, 103 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 7c535f2ce8..34bc0d45a4 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -306,6 +306,20 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
           gl_type = GL_HALF_FLOAT;
           bpp = 8;
         }
+      else if (data_format == GDK_MEMORY_R32G32B32_FLOAT)
+        {
+          gl_internalformat = GL_RGB32F;
+          gl_format = GL_RGB;
+          gl_type = GL_FLOAT;
+          bpp = 12;
+        }
+      else if (data_format == GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED)
+        {
+          gl_internalformat = GL_RGBA32F;
+          gl_format = GL_RGBA;
+          gl_type = GL_FLOAT;
+          bpp = 16;
+        }
       else /* Fall-back, convert to cairo-surface-format */
         {
           copy = g_malloc (width * height * 4);
diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c
index 45226fa50c..5ba0d52c48 100644
--- a/gdk/gdkgltexture.c
+++ b/gdk/gdkgltexture.c
@@ -123,6 +123,9 @@ type_from_internal_format (int internal_format)
     case GL_RGB16F:
     case GL_RGBA16F:
       return GL_HALF_FLOAT;
+    case GL_RGB32F:
+    case GL_RGBA32F:
+      return GL_FLOAT;
     default:
       g_assert_not_reached ();
     }
@@ -141,6 +144,10 @@ internal_format_for_format (GdkMemoryFormat format)
       return GL_RGB16F;
     case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
       return GL_RGB16F;
+    case GDK_MEMORY_R32G32B32_FLOAT:
+      return GL_RGB32F;
+    case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
+      return GL_RGB32F;
     default:
       g_assert_not_reached ();
     }
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index c0c20cb06c..529db62e30 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -73,6 +73,12 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
     case GDK_MEMORY_R16G16B16_FLOAT:
       return 6;
 
+    case GDK_MEMORY_R32G32B32_FLOAT:
+      return 12;
+
+    case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
+      return 16;
+
     case GDK_MEMORY_N_FORMATS:
     default:
       g_assert_not_reached ();
@@ -172,7 +178,7 @@ gdk_memory_texture_new (int              width,
   return GDK_TEXTURE (self);
 }
 
-GdkMemoryFormat 
+GdkMemoryFormat
 gdk_memory_texture_get_format (GdkMemoryTexture *self)
 {
   return self->format;
@@ -437,6 +443,68 @@ SWIZZLE_FP16(3,2,1,0)
 SWIZZLE_FP16(0,1,2,3)
 SWIZZLE_FP16(3,0,1,2)
 
+#define SWIZZLE_FLOAT_OPAQUE(A,R,G,B) \
+static void \
+convert_float_swizzle_opaque_ ## A ## R ## G ## B (guchar       *dest_data, \
+                                                   gsize         dest_stride, \
+                                                   const guchar *src_data, \
+                                                   gsize         src_stride, \
+                                                   gsize         width, \
+                                                   gsize         height) \
+{ \
+  gsize x, y; \
+\
+  for (y = 0; y < height; y++) \
+    { \
+      float *src = (float *)src_data; \
+      for (x = 0; x < width; x++) \
+        { \
+          dest_data[4 * x + A] = 255; \
+          dest_data[4 * x + R] = (guchar)(255 * src[3 * x + 0]); \
+          dest_data[4 * x + G] = (guchar)(255 * src[3 * x + 1]); \
+          dest_data[4 * x + B] = (guchar)(255 * src[3 * x + 2]); \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
+
+SWIZZLE_FLOAT_OPAQUE(3,2,1,0)
+SWIZZLE_FLOAT_OPAQUE(0,1,2,3)
+SWIZZLE_FLOAT_OPAQUE(3,0,1,2)
+
+#define SWIZZLE_FLOAT(A,R,G,B) \
+static void \
+convert_float_swizzle_ ## A ## R ## G ## B (guchar       *dest_data, \
+                                            gsize         dest_stride, \
+                                            const guchar *src_data, \
+                                            gsize         src_stride, \
+                                            gsize         width, \
+                                            gsize         height) \
+{ \
+  gsize x, y; \
+\
+  for (y = 0; y < height; y++) \
+    { \
+      float *src = (float *)src_data; \
+      for (x = 0; x < width; x++) \
+        { \
+          dest_data[4 * x + A] = (guchar)(255 * src[3 * x + 0]); \
+          dest_data[4 * x + R] = (guchar)(255 * src[3 * x + 1]); \
+          dest_data[4 * x + G] = (guchar)(255 * src[3 * x + 2]); \
+          dest_data[4 * x + B] = (guchar)(255 * src[3 * x + 3]); \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
+
+SWIZZLE_FLOAT(3,2,1,0)
+SWIZZLE_FLOAT(0,1,2,3)
+SWIZZLE_FLOAT(3,0,1,2)
+
 typedef void (* ConversionFunc) (guchar       *dest_data,
                                  gsize         dest_stride,
                                  const guchar *src_data,
@@ -458,7 +526,9 @@ static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
   { convert_16to8_swizzle_opaque_2103, convert_16to8_swizzle_opaque_1230, convert_16to8_swizzle_opaque_0123 
},
   { convert_16to8_swizzle_2103, convert_16to8_swizzle_1230, convert_16to8_swizzle_0123 },
   { convert_fp16_swizzle_opaque_3210, convert_fp16_swizzle_opaque_0123, convert_fp16_swizzle_opaque_3012 },
-  { convert_fp16_swizzle_3210, convert_fp16_swizzle_0123, convert_fp16_swizzle_3012 }
+  { convert_fp16_swizzle_3210, convert_fp16_swizzle_0123, convert_fp16_swizzle_3012 },
+  { convert_float_swizzle_opaque_3210, convert_float_swizzle_opaque_0123, convert_float_swizzle_opaque_3012 
},
+  { convert_float_swizzle_3210, convert_float_swizzle_0123, convert_float_swizzle_3012 }
 };
 
 void
diff --git a/gdk/gdkmemorytexture.h b/gdk/gdkmemorytexture.h
index 5bab062d6f..9057bf3cb0 100644
--- a/gdk/gdkmemorytexture.h
+++ b/gdk/gdkmemorytexture.h
@@ -51,6 +51,11 @@ G_BEGIN_DECLS
  * @GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: 4 half-float values; for
  *   red, green, blue and alpha. The color values are premultiplied with
  *   the alpha value. Since 4.6
+ * @GDK_MEMORY_B32G32R32_FLOAT: 3 float values; for blue, green, red.
+ *   The data is opaque. Since 4.6
+ * @GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED: 4 float values; for
+ *   red, green, blue and alpha. The color values are premultiplied with
+ *   the alpha value. Since 4.6
  * @GDK_MEMORY_N_FORMATS: The number of formats. This value will change as
  *   more formats get added, so do not rely on its concrete integer.
  *
@@ -82,6 +87,8 @@ typedef enum {
   GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
   GDK_MEMORY_R16G16B16_FLOAT,
   GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED,
+  GDK_MEMORY_R32G32B32_FLOAT,
+  GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
 
   GDK_MEMORY_N_FORMATS
 } GdkMemoryFormat;
diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c
index 8645a96fec..7ae68517a0 100644
--- a/testsuite/gdk/memorytexture.c
+++ b/testsuite/gdk/memorytexture.c
@@ -190,7 +190,9 @@ main (int argc, char *argv[])
   for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
     {
       if (format == GDK_MEMORY_R16G16B16_FLOAT ||
-          format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED)
+          format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED ||
+          format == GDK_MEMORY_R32G32B32_FLOAT ||
+          format == GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED)
         continue;
 
       for (color = 0; color < N_COLORS; color++)


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