[gtk/wip/otte/color-profiles: 65/82] memoryformat: Do some gdk_memory_convert() massaging




commit 1b9243fed5a15e0c11711e51b642b36bc4a327f1
Author: Benjamin Otte <otte redhat com>
Date:   Sun Sep 26 06:06:48 2021 +0200

    memoryformat: Do some gdk_memory_convert() massaging
    
    * Add name support to the formats
    * Add profiler mark to gdk_memory_convert()
    * Split up the different branches of conversion
    * Use memcpy for straight copies

 gdk/gdkmemoryformat.c | 173 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 142 insertions(+), 31 deletions(-)
---
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index df3df7d0a2..f7d0c97978 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -22,6 +22,7 @@
 #include "gdkmemoryformatprivate.h"
 
 #include "gdkcolorprofileprivate.h"
+#include "gdkprofilerprivate.h"
 #include "gsk/ngl/fp16private.h"
 
 #include <epoxy/gl.h>
@@ -169,6 +170,7 @@ r32g32b32a32_float_from_float (guchar      *dest,
 
 struct _GdkMemoryFormatDescription
 {
+  const char *name;
   GdkMemoryAlpha alpha;
   gsize bytes_per_pixel;
   gsize alignment;
@@ -193,6 +195,7 @@ struct _GdkMemoryFormatDescription
 
 static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
   [GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
+    "B8G8R8A8_PREMULTIPLIED",
     GDK_MEMORY_ALPHA_PREMULTIPLIED,
     4,
     G_ALIGNOF (guchar),
@@ -202,6 +205,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     b8g8r8a8_premultiplied_from_float,
   },
   [GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
+    "A8R8G8B8_PREMULTIPLIED",
     GDK_MEMORY_ALPHA_PREMULTIPLIED,
     4,
     G_ALIGNOF (guchar),
@@ -211,6 +215,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     a8r8g8b8_premultiplied_from_float,
   },
   [GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
+    "R8G8B8A8_PREMULTIPLIED",
     GDK_MEMORY_ALPHA_PREMULTIPLIED,
     4,
     G_ALIGNOF (guchar),
@@ -220,6 +225,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r8g8b8a8_premultiplied_from_float,
   },
   [GDK_MEMORY_B8G8R8A8] = {
+    "B8G8R8A8",
     GDK_MEMORY_ALPHA_STRAIGHT,
     4,
     G_ALIGNOF (guchar),
@@ -229,6 +235,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     b8g8r8a8_from_float,
   },
   [GDK_MEMORY_A8R8G8B8] = {
+    "A8R8G8B8",
     GDK_MEMORY_ALPHA_STRAIGHT,
     4,
     G_ALIGNOF (guchar),
@@ -238,6 +245,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     a8r8g8b8_from_float,
   },
   [GDK_MEMORY_R8G8B8A8] = {
+    "R8G8B8A8",
     GDK_MEMORY_ALPHA_STRAIGHT,
     4,
     G_ALIGNOF (guchar),
@@ -247,6 +255,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r8g8b8a8_from_float,
   },
   [GDK_MEMORY_A8B8G8R8] = {
+    "A8B8G8R8",
     GDK_MEMORY_ALPHA_STRAIGHT,
     4,
     G_ALIGNOF (guchar),
@@ -256,6 +265,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     a8b8g8r8_from_float,
   },
   [GDK_MEMORY_R8G8B8] = {
+    "R8G8B8",
     GDK_MEMORY_ALPHA_OPAQUE,
     3,
     G_ALIGNOF (guchar),
@@ -265,6 +275,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r8g8b8_from_float,
   },
   [GDK_MEMORY_B8G8R8] = {
+    "B8G8R8",
     GDK_MEMORY_ALPHA_OPAQUE,
     3,
     G_ALIGNOF (guchar),
@@ -274,6 +285,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     b8g8r8_from_float,
   },
   [GDK_MEMORY_R16G16B16] = {
+    "R16G16B16",
     GDK_MEMORY_ALPHA_OPAQUE,
     6,
     G_ALIGNOF (guint16),
@@ -283,6 +295,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r16g16b16_from_float,
   },
   [GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
+    "R16G16B16A16_PREMULTIPLIED",
     GDK_MEMORY_ALPHA_PREMULTIPLIED,
     8,
     G_ALIGNOF (guint16),
@@ -292,6 +305,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r16g16b16a16_from_float,
   },
   [GDK_MEMORY_R16G16B16_FLOAT] = {
+    "R16G16B16_FLOAT",
     GDK_MEMORY_ALPHA_OPAQUE,
     6,
     G_ALIGNOF (guint16),
@@ -301,6 +315,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r16g16b16_float_from_float,
   },
   [GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
+    "R16G16B16A16_FLOAT_PREMULTIPLIED",
     GDK_MEMORY_ALPHA_PREMULTIPLIED,
     8,
     G_ALIGNOF (guint16),
@@ -310,6 +325,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r16g16b16a16_float_from_float,
   },
   [GDK_MEMORY_R32G32B32_FLOAT] = {
+    "R32G32B32_FLOAT",
     GDK_MEMORY_ALPHA_OPAQUE,
     12,
     G_ALIGNOF (float),
@@ -319,6 +335,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r32g32b32_float_from_float,
   },
   [GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
+    "R32G32B32A32_FLOAT_PREMULTIPLIED",
     GDK_MEMORY_ALPHA_PREMULTIPLIED,
     16,
     G_ALIGNOF (float),
@@ -396,6 +413,113 @@ unpremultiply (float *rgba,
     }
 }
 
+static void
+gdk_memory_convert_same_format (guchar          *dest_data,
+                                gsize            dest_stride,
+                                const guchar    *src_data,
+                                gsize            src_stride,
+                                gsize            width,
+                                gsize            height,
+                                GdkMemoryFormat  format)
+{
+  const GdkMemoryFormatDescription *desc = &memory_formats[format];
+  gsize y, stride;
+
+  stride = desc->bytes_per_pixel * width;
+  if (stride == src_stride && stride == dest_stride)
+    {
+      memcpy (dest_data, src_data, stride * height);
+    }
+  else
+    {
+      for (y = 0; y < height; y++)
+        {
+          memcpy (dest_data + y * dest_stride,
+                  src_data + y * src_stride,
+                  stride);
+        }
+    }
+}
+
+static void
+gdk_memory_convert_no_transform (guchar              *dest_data,
+                                 gsize                dest_stride,
+                                 GdkMemoryFormat      dest_format,
+                                 const guchar        *src_data,
+                                 gsize                src_stride,
+                                 GdkMemoryFormat      src_format,
+                                 gsize                width,
+                                 gsize                height)
+{
+  if (dest_format == src_format)
+    {
+      gdk_memory_convert_same_format (dest_data, dest_stride,
+                                      src_data, src_stride,
+                                      width, height,
+                                      dest_format);
+    }
+  else
+    {
+      const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
+      const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+      float *tmp;
+      gsize y;
+
+      tmp = g_new (float, width * 4);
+
+      for (y = 0; y < height; y++)
+        {
+          src_desc->to_float (tmp, src_data, width);
+          if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == 
GDK_MEMORY_ALPHA_STRAIGHT)
+            unpremultiply (tmp, width);
+          else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != 
GDK_MEMORY_ALPHA_STRAIGHT)
+            premultiply (tmp, width);
+          dest_desc->from_float (dest_data, tmp, width);
+          src_data += src_stride;
+          dest_data += dest_stride;
+        }
+
+      g_free (tmp);
+    }
+}
+
+static void
+gdk_memory_convert_transform (guchar              *dest_data,
+                              gsize                dest_stride,
+                              GdkMemoryFormat      dest_format,
+                              const guchar        *src_data,
+                              gsize                src_stride,
+                              GdkMemoryFormat      src_format,
+                              gsize                width,
+                              gsize                height,
+                              cmsHTRANSFORM        transform)
+{
+  const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
+  const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+  float *tmp;
+  gsize y;
+
+  tmp = g_new (float, width * 4);
+
+  for (y = 0; y < height; y++)
+    {
+      src_desc->to_float (tmp, src_data, width);
+      if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED)
+        unpremultiply (tmp, width);
+      cmsDoTransform (transform,
+                      tmp,
+                      tmp,
+                      width);
+      if (dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
+        premultiply (tmp, width);
+      dest_desc->from_float (dest_data, tmp, width);
+      src_data += src_stride;
+      dest_data += dest_stride;
+    }
+
+  g_free (tmp);
+}
+
 void
 gdk_memory_convert (guchar              *dest_data,
                     gsize                dest_stride,
@@ -408,17 +532,12 @@ gdk_memory_convert (guchar              *dest_data,
                     gsize                width,
                     gsize                height)
 {
-  const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
-  const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+  G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
   cmsHTRANSFORM transform;
-  float *tmp;
-  gsize y;
 
   g_assert (dest_format < GDK_MEMORY_N_FORMATS);
   g_assert (src_format < GDK_MEMORY_N_FORMATS);
 
-  tmp = g_new (float, width * 4);
-
   if (gdk_color_profile_equal (src_profile, dest_profile))
     {
       transform = NULL;
@@ -433,32 +552,24 @@ gdk_memory_convert (guchar              *dest_data,
                                       cmsFLAGS_COPY_ALPHA);
     }
 
-  for (y = 0; y < height; y++)
+  if (transform)
     {
-      src_desc->to_float (tmp, src_data, width);
-      if (transform)
-        {
-          if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED)
-            unpremultiply (tmp, width);
-          cmsDoTransform (transform,
-                          tmp,
-                          tmp,
-                          width);
-          if (dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
-            premultiply (tmp, width);
-        }
-      else
-        {
-          if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == 
GDK_MEMORY_ALPHA_STRAIGHT)
-            unpremultiply (tmp, width);
-          else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != 
GDK_MEMORY_ALPHA_STRAIGHT)
-            premultiply (tmp, width);
-        }
-      dest_desc->from_float (dest_data, tmp, width);
-      src_data += src_stride;
-      dest_data += dest_stride;
+      gdk_memory_convert_transform (dest_data, dest_stride, dest_format,
+                                    src_data, src_stride, src_format,
+                                    width, height,
+                                    transform);
+      cmsDeleteTransform (transform);
+    }
+  else
+    {
+      gdk_memory_convert_no_transform (dest_data, dest_stride, dest_format,
+                                       src_data, src_stride, src_format,
+                                       width, height);
     }
 
-  g_free (tmp);
-  g_clear_pointer (&transform, cmsDeleteTransform);
+  gdk_profiler_end_markf (start_time, "memory convert", "%zu pixels %s => %s%s",
+                          width * height,
+                          memory_formats[src_format].name,
+                          memory_formats[dest_format].name,
+                          transform ? " transformed" : "");
 }


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