[gtk/gamma-shenanigans: 4/7] Support 16-bit floating point textures




commit 9dc0cae647839d38db7f1af10cc0b158ad32f6ba
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Sep 6 08:27:42 2021 -0400

    Support 16-bit floating point textures
    
    Add support for a R16G16B16_FLOAT format
    which is using half floats.
    
    The intention is to use this for HDR content.
    
    I did not add a variant with alpha, since I'm
    not sure how important alpha is for HDR content
    and I don't really know what to do about
    premultiplication for float textures.
    
    Not done here: Update memory texture tests
    to include floating point textures.

 gdk/gdkglcontext.c            |  7 +++++++
 gdk/gdkmemorytexture.c        | 41 ++++++++++++++++++++++++++++++++++++++++-
 gdk/gdkmemorytexture.h        |  2 ++
 testsuite/gdk/memorytexture.c |  3 +++
 4 files changed, 52 insertions(+), 1 deletion(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 464612e616..774d33780c 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -285,6 +285,13 @@ gdk_gl_context_upload_texture (GdkGLContext    *context,
           gl_type = GL_UNSIGNED_SHORT;
           bpp = 8;
         }
+      else if (data_format == GDK_MEMORY_R16G16B16_FLOAT)
+        {
+          gl_internalformat = GL_RGB16F;
+          gl_format = GL_RGB;
+          gl_type = GL_HALF_FLOAT;
+          bpp = 6;
+        }
       else /* Fall-back, convert to cairo-surface-format */
         {
           copy = g_malloc (width * height * 4);
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 672f24469f..bd00d71795 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -20,6 +20,7 @@
 #include "config.h"
 
 #include "gdkmemorytextureprivate.h"
+#include "gsk/ngl/fp16private.h"
 
 /**
  * GdkMemoryTexture:
@@ -65,6 +66,9 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
     case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
       return 8;
 
+    case GDK_MEMORY_R16G16B16_FLOAT:
+      return 6;
+
     case GDK_MEMORY_N_FORMATS:
     default:
       g_assert_not_reached ();
@@ -330,6 +334,40 @@ SWIZZLE_16TO8(0,1,2,3)
 SWIZZLE_16TO8(2,1,0,3)
 SWIZZLE_16TO8(1,2,3,0)
 
+#define SWIZZLE_FP16_OPAQUE(A,R,G,B) \
+static void \
+convert_fp16_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++) \
+    { \
+      guint16 *src = (guint16 *)src_data; \
+      for (x = 0; x < width; x++) \
+        { \
+          float c[4]; \
+          half_to_float4 (&src[3 * x], c); \
+          c[3] = 1.0; \
+          dest_data[4 * x + A] = 255 * c[4 * x + 3]; \
+          dest_data[4 * x + R] = 255 * c[4 * x + 0]; \
+          dest_data[4 * x + G] = 255 * c[4 * x + 1]; \
+          dest_data[4 * x + B] = 255 * c[4 * x + 2]; \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
+
+SWIZZLE_FP16_OPAQUE(3,2,1,0)
+SWIZZLE_FP16_OPAQUE(0,1,2,3)
+SWIZZLE_FP16_OPAQUE(3,0,1,2)
+
 typedef void (* ConversionFunc) (guchar       *dest_data,
                                  gsize         dest_stride,
                                  const guchar *src_data,
@@ -348,7 +386,8 @@ static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
   { convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321, 
convert_swizzle_premultiply_3012_0321 },
   { convert_swizzle_opaque_3210, convert_swizzle_opaque_0123, convert_swizzle_opaque_3012 },
   { convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210 },
-  { convert_16to8_swizzle_2103, convert_16to8_swizzle_1230, convert_16to8_swizzle_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 }
 };
 
 void
diff --git a/gdk/gdkmemorytexture.h b/gdk/gdkmemorytexture.h
index 8fa3b22521..07ff7ac0a8 100644
--- a/gdk/gdkmemorytexture.h
+++ b/gdk/gdkmemorytexture.h
@@ -44,6 +44,7 @@ G_BEGIN_DECLS
  * @GDK_MEMORY_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
  * @GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: 4 guint16 values; for red, green, blue, alpha.
  *   The color values are premultiplied with the alpha value.
+ * @GDK_MEMORY_B16G16R16_FLOAT: 3 half-float values; for blue, green, red. The data is opaque.
  * @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.
  *
@@ -72,6 +73,7 @@ typedef enum {
   GDK_MEMORY_R8G8B8,
   GDK_MEMORY_B8G8R8,
   GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
+  GDK_MEMORY_R16G16B16_FLOAT,
 
   GDK_MEMORY_N_FORMATS
 } GdkMemoryFormat;
diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c
index 00bb489b63..099cbacdf1 100644
--- a/testsuite/gdk/memorytexture.c
+++ b/testsuite/gdk/memorytexture.c
@@ -189,6 +189,9 @@ main (int argc, char *argv[])
 
   for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
     {
+      if (format == GDK_MEMORY_R16G16B16_FLOAT)
+        continue;
+
       for (color = 0; color < N_COLORS; color++)
         {
           TestData *test_data = g_new (TestData, 1);


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