[gtk/wip/otte/memoryformat: 1/4] memorytexture: Split out GdkMemoryFormat handling
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/memoryformat: 1/4] memorytexture: Split out GdkMemoryFormat handling
- Date: Wed, 6 Oct 2021 16:27:44 +0000 (UTC)
commit cc6cc19e42c201b56965e260dd8d1d8e4227b6ba
Author: Benjamin Otte <otte redhat com>
Date: Wed Sep 22 02:01:41 2021 +0200
memorytexture: Split out GdkMemoryFormat handling
Also, now make gdk_memory_convert() the only conversion functions
and allow conversions between any 2 formats by going via a float[4].
This could be optimized via fast-paths, but so far it isn't.
gdk/gdkglcontext.c | 3 +-
gdk/gdkgltexture.c | 1 +
gdk/gdkmemoryformat.c | 366 +++++++++++++++++++++++++++++
gdk/gdkmemoryformatprivate.h | 42 ++++
gdk/gdkmemorytexture.c | 518 +-----------------------------------------
gdk/gdkmemorytextureprivate.h | 35 ---
gdk/loaders/gdkpng.c | 1 +
gdk/loaders/gdktiff.c | 1 +
gdk/meson.build | 1 +
gsk/ngl/gsknglcommandqueue.c | 1 +
gsk/ngl/gsknglglyphlibrary.c | 4 +-
gsk/ngl/gskngliconlibrary.c | 4 +-
12 files changed, 430 insertions(+), 547 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 11c3f77dd4..ece50c8cd2 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -79,6 +79,7 @@
#include "gdkdebug.h"
#include "gdkdisplayprivate.h"
#include "gdkintl.h"
+#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
@@ -303,7 +304,7 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
{
copy = g_malloc (width * height * 4);
gdk_memory_convert (copy, width * 4,
- GDK_MEMORY_CONVERT_GLES_RGBA,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
data, stride, data_format,
width, height);
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c
index e2e292964d..1a321fa879 100644
--- a/gdk/gdkgltexture.c
+++ b/gdk/gdkgltexture.c
@@ -21,6 +21,7 @@
#include "gdkgltextureprivate.h"
#include "gdkdisplayprivate.h"
+#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdktextureprivate.h"
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
new file mode 100644
index 0000000000..f0b48d0e85
--- /dev/null
+++ b/gdk/gdkmemoryformat.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright © 2021 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gdkmemoryformatprivate.h"
+
+#include "gsk/ngl/fp16private.h"
+
+typedef struct _GdkMemoryFormatDescription GdkMemoryFormatDescription;
+
+typedef enum {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ GDK_MEMORY_ALPHA_STRAIGHT,
+ GDK_MEMORY_ALPHA_OPAQUE
+} GdkMemoryAlpha;
+
+#define TYPED_FUNCS(name, T, R, G, B, A, bpp, scale) \
+static void \
+name ## _to_float (float *dest, \
+ const guchar *src_data, \
+ gsize n) \
+{ \
+ for (gsize i = 0; i < n; i++) \
+ { \
+ T *src = (T *) (src_data + i * bpp); \
+ dest[0] = (float) src[R] / scale; \
+ dest[1] = (float) src[G] / scale; \
+ dest[2] = (float) src[B] / scale; \
+ if (A >= 0) dest[3] = (float) src[A] / scale; else dest[3] = 1.0; \
+ dest += 4; \
+ } \
+} \
+\
+static void \
+name ## _from_float (guchar *dest_data, \
+ const float *src, \
+ gsize n) \
+{ \
+ for (gsize i = 0; i < n; i++) \
+ { \
+ T *dest = (T *) (dest_data + i * bpp); \
+ dest[R] = CLAMP (src[0] * (scale + 1), 0, scale); \
+ dest[G] = CLAMP (src[1] * (scale + 1), 0, scale); \
+ dest[B] = CLAMP (src[2] * (scale + 1), 0, scale); \
+ if (A >= 0) dest[A] = CLAMP (src[3] * (scale + 1), 0, scale); \
+ src += 4; \
+ } \
+}
+
+TYPED_FUNCS (b8g8r8a8_premultiplied, guchar, 2, 1, 0, 3, 4, 255)
+TYPED_FUNCS (a8r8g8b8_premultiplied, guchar, 1, 2, 3, 0, 4, 255)
+TYPED_FUNCS (r8g8b8a8_premultiplied, guchar, 0, 1, 2, 3, 4, 255)
+TYPED_FUNCS (b8g8r8a8, guchar, 2, 1, 0, 3, 4, 255)
+TYPED_FUNCS (a8r8g8b8, guchar, 1, 2, 3, 0, 4, 255)
+TYPED_FUNCS (r8g8b8a8, guchar, 0, 1, 2, 3, 4, 255)
+TYPED_FUNCS (a8b8g8r8, guchar, 3, 2, 1, 0, 4, 255)
+TYPED_FUNCS (r8g8b8, guchar, 0, 1, 2, -1, 3, 255)
+TYPED_FUNCS (b8g8r8, guchar, 2, 1, 0, -1, 3, 255)
+TYPED_FUNCS (r16g16b16, guint16, 0, 1, 2, -1, 6, 65535)
+TYPED_FUNCS (r16g16b16a16, guint16, 0, 1, 2, 3, 8, 65535)
+
+static void
+r16g16b16_float_to_float (float *dest,
+ const guchar *src_data,
+ gsize n)
+{
+ guint16 *src = (guint16 *) src_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ half_to_float (src, dest, 3);
+ dest[3] = 1.0;
+ dest += 4;
+ src += 3;
+ }
+}
+
+static void
+r16g16b16_float_from_float (guchar *dest_data,
+ const float *src,
+ gsize n)
+{
+ guint16 *dest = (guint16 *) dest_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ float_to_half (src, dest, 3);
+ dest += 3;
+ src += 4;
+ }
+}
+
+static void
+r16g16b16a16_float_to_float (float *dest,
+ const guchar *src,
+ gsize n)
+{
+ half_to_float ((const guint16 *) src, dest, 4 * n);
+}
+
+static void
+r16g16b16a16_float_from_float (guchar *dest,
+ const float *src,
+ gsize n)
+{
+ float_to_half (src, (guint16 *) dest, 4 * n);
+}
+
+static void
+r32g32b32_float_to_float (float *dest,
+ const guchar *src_data,
+ gsize n)
+{
+ float *src = (float *) src_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest[3] = 1.0;
+ dest += 4;
+ src += 3;
+ }
+}
+
+static void
+r32g32b32_float_from_float (guchar *dest_data,
+ const float *src,
+ gsize n)
+{
+ float *dest = (float *) dest_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest += 3;
+ src += 4;
+ }
+}
+
+static void
+r32g32b32a32_float_to_float (float *dest,
+ const guchar *src,
+ gsize n)
+{
+ memcpy (dest, src, sizeof (float) * n * 4);
+}
+
+static void
+r32g32b32a32_float_from_float (guchar *dest,
+ const float *src,
+ gsize n)
+{
+ memcpy (dest, src, sizeof (float) * n * 4);
+}
+
+struct _GdkMemoryFormatDescription
+{
+ GdkMemoryAlpha alpha;
+ gsize bytes_per_pixel;
+ gsize alignment;
+
+ /* no premultiplication going on here */
+ void (* to_float) (float *, const guchar*, gsize);
+ void (* from_float) (guchar *, const float *, gsize);
+};
+
+static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
+ [GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 4,
+ G_ALIGNOF (guchar),
+ b8g8r8a8_premultiplied_to_float,
+ b8g8r8a8_premultiplied_from_float,
+ },
+ [GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 4,
+ G_ALIGNOF (guchar),
+ a8r8g8b8_premultiplied_to_float,
+ a8r8g8b8_premultiplied_from_float,
+ },
+ [GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 4,
+ G_ALIGNOF (guchar),
+ r8g8b8a8_premultiplied_to_float,
+ r8g8b8a8_premultiplied_from_float,
+ },
+ [GDK_MEMORY_B8G8R8A8] = {
+ GDK_MEMORY_ALPHA_STRAIGHT,
+ 4,
+ G_ALIGNOF (guchar),
+ b8g8r8a8_to_float,
+ b8g8r8a8_from_float,
+ },
+ [GDK_MEMORY_A8R8G8B8] = {
+ GDK_MEMORY_ALPHA_STRAIGHT,
+ 4,
+ G_ALIGNOF (guchar),
+ a8r8g8b8_to_float,
+ a8r8g8b8_from_float,
+ },
+ [GDK_MEMORY_R8G8B8A8] = {
+ GDK_MEMORY_ALPHA_STRAIGHT,
+ 4,
+ G_ALIGNOF (guchar),
+ r8g8b8a8_to_float,
+ r8g8b8a8_from_float,
+ },
+ [GDK_MEMORY_A8B8G8R8] = {
+ GDK_MEMORY_ALPHA_STRAIGHT,
+ 4,
+ G_ALIGNOF (guchar),
+ a8b8g8r8_to_float,
+ a8b8g8r8_from_float,
+ },
+ [GDK_MEMORY_R8G8B8] = {
+ GDK_MEMORY_ALPHA_OPAQUE,
+ 3,
+ G_ALIGNOF (guchar),
+ r8g8b8_to_float,
+ r8g8b8_from_float,
+ },
+ [GDK_MEMORY_B8G8R8] = {
+ GDK_MEMORY_ALPHA_OPAQUE,
+ 3,
+ G_ALIGNOF (guchar),
+ b8g8r8_to_float,
+ b8g8r8_from_float,
+ },
+ [GDK_MEMORY_R16G16B16] = {
+ GDK_MEMORY_ALPHA_OPAQUE,
+ 6,
+ G_ALIGNOF (guint16),
+ r16g16b16_to_float,
+ r16g16b16_from_float,
+ },
+ [GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 8,
+ G_ALIGNOF (guint16),
+ r16g16b16a16_to_float,
+ r16g16b16a16_from_float,
+ },
+ [GDK_MEMORY_R16G16B16_FLOAT] = {
+ GDK_MEMORY_ALPHA_OPAQUE,
+ 6,
+ G_ALIGNOF (guint16),
+ r16g16b16_float_to_float,
+ r16g16b16_float_from_float,
+ },
+ [GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 8,
+ G_ALIGNOF (guint16),
+ r16g16b16a16_float_to_float,
+ r16g16b16a16_float_from_float,
+ },
+ [GDK_MEMORY_R32G32B32_FLOAT] = {
+ GDK_MEMORY_ALPHA_OPAQUE,
+ 12,
+ G_ALIGNOF (float),
+ r32g32b32_float_to_float,
+ r32g32b32_float_from_float,
+ },
+ [GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 16,
+ G_ALIGNOF (float),
+ r32g32b32a32_float_to_float,
+ r32g32b32a32_float_from_float,
+ }
+};
+
+gsize
+gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
+{
+ return memory_formats[format].bytes_per_pixel;
+}
+
+gsize
+gdk_memory_format_alignment (GdkMemoryFormat format)
+{
+ return memory_formats[format].alignment;
+}
+
+static void
+premultiply (float *rgba,
+ gsize n)
+{
+ for (gsize i = 0; i < n; i++)
+ {
+ rgba[0] *= rgba[3];
+ rgba[1] *= rgba[3];
+ rgba[2] *= rgba[3];
+ rgba += 4;
+ }
+}
+
+static void
+unpremultiply (float *rgba,
+ gsize n)
+{
+ for (gsize i = 0; i < n; i++)
+ {
+ if (rgba[3] > 1/255.0)
+ {
+ rgba[0] /= rgba[3];
+ rgba[1] /= rgba[3];
+ rgba[2] /= rgba[3];
+ }
+ rgba += 4;
+ }
+}
+
+void
+gdk_memory_convert (guchar *dest_data,
+ gsize dest_stride,
+ GdkMemoryFormat dest_format,
+ const guchar *src_data,
+ gsize src_stride,
+ GdkMemoryFormat src_format,
+ gsize width,
+ gsize height)
+{
+ const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
+ const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+ 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);
+
+ 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);
+}
diff --git a/gdk/gdkmemoryformatprivate.h b/gdk/gdkmemoryformatprivate.h
new file mode 100644
index 0000000000..0de89f0756
--- /dev/null
+++ b/gdk/gdkmemoryformatprivate.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2021 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GDK_MEMORY_CONVERT_PRIVATE_H__
+#define __GDK_MEMORY_CONVERT_PRIVATE_H__
+
+#include "gdkmemorytexture.h"
+
+G_BEGIN_DECLS
+
+gsize gdk_memory_format_alignment (GdkMemoryFormat format)
G_GNUC_CONST;
+gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
G_GNUC_CONST;
+
+void gdk_memory_convert (guchar *dest_data,
+ gsize dest_stride,
+ GdkMemoryFormat dest_format,
+ const guchar *src_data,
+ gsize src_stride,
+ GdkMemoryFormat src_format,
+ gsize width,
+ gsize height);
+
+
+G_END_DECLS
+
+#endif /* __GDK_MEMORY_CONVERT_PRIVATE_H__ */
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 6c08ef531b..33ba90fe5c 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -20,6 +20,8 @@
#include "config.h"
#include "gdkmemorytextureprivate.h"
+
+#include "gdkmemoryformatprivate.h"
#include "gsk/ngl/fp16private.h"
/**
@@ -45,80 +47,6 @@ struct _GdkMemoryTextureClass
G_DEFINE_TYPE (GdkMemoryTexture, gdk_memory_texture, GDK_TYPE_TEXTURE)
-gsize
-gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
-{
- switch (format)
- {
- case GDK_MEMORY_R8G8B8:
- case GDK_MEMORY_B8G8R8:
- return 3;
-
- case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
- case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
- case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
- case GDK_MEMORY_B8G8R8A8:
- case GDK_MEMORY_A8R8G8B8:
- case GDK_MEMORY_R8G8B8A8:
- case GDK_MEMORY_A8B8G8R8:
- return 4;
-
- case GDK_MEMORY_R16G16B16:
- case GDK_MEMORY_R16G16B16_FLOAT:
- return 6;
-
- case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
- case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
- return 8;
-
- 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 ();
- return 4;
- }
-}
-
-static gsize
-gdk_memory_format_alignment (GdkMemoryFormat format)
-{
- switch (format)
- {
- case GDK_MEMORY_R8G8B8:
- case GDK_MEMORY_B8G8R8:
- case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
- case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
- case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
- case GDK_MEMORY_B8G8R8A8:
- case GDK_MEMORY_A8R8G8B8:
- case GDK_MEMORY_R8G8B8A8:
- case GDK_MEMORY_A8B8G8R8:
- return G_ALIGNOF (guchar);
-
- case GDK_MEMORY_R16G16B16:
- case GDK_MEMORY_R16G16B16_FLOAT:
- return G_ALIGNOF (guint16);
-
- case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
- case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
- return G_ALIGNOF (guint16);
-
- case GDK_MEMORY_R32G32B32_FLOAT:
- case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
- return G_ALIGNOF (float);
-
- case GDK_MEMORY_N_FORMATS:
- default:
- g_assert_not_reached ();
- return G_ALIGNOF (double);
- }
-}
-
static void
gdk_memory_texture_dispose (GObject *object)
{
@@ -143,7 +71,7 @@ gdk_memory_texture_download (GdkTexture *texture,
GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (texture);
gdk_memory_convert (data, stride,
- GDK_MEMORY_CONVERT_DOWNLOAD,
+ GDK_MEMORY_DEFAULT,
(guchar *) g_bytes_get_data (self->bytes, NULL),
self->stride,
self->format,
@@ -158,12 +86,14 @@ gdk_memory_texture_download_float (GdkTexture *texture,
{
GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (texture);
- gdk_memory_convert_to_float (data, stride,
- (guchar *) g_bytes_get_data (self->bytes, NULL),
- self->stride,
- self->format,
- gdk_texture_get_width (texture),
- gdk_texture_get_height (texture));
+ gdk_memory_convert ((guchar *) data,
+ stride * sizeof (float),
+ GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
+ (guchar *) g_bytes_get_data (self->bytes, NULL),
+ self->stride,
+ self->format,
+ gdk_texture_get_width (texture),
+ gdk_texture_get_height (texture));
}
static void
@@ -279,429 +209,3 @@ gdk_memory_texture_get_stride (GdkMemoryTexture *self)
return self->stride;
}
-static void
-convert_memcpy (guchar *dest_data,
- gsize dest_stride,
- const guchar *src_data,
- gsize src_stride,
- gsize width,
- gsize height)
-{
- gsize y;
-
- for (y = 0; y < height; y++)
- memcpy (dest_data + y * dest_stride, src_data + y * src_stride, 4 * width);
-}
-
-#define SWIZZLE(A,R,G,B) \
-static void \
-convert_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++) \
- { \
- for (x = 0; x < width; x++) \
- { \
- dest_data[4 * x + A] = src_data[4 * x + 0]; \
- dest_data[4 * x + R] = src_data[4 * x + 1]; \
- dest_data[4 * x + G] = src_data[4 * x + 2]; \
- dest_data[4 * x + B] = src_data[4 * x + 3]; \
- } \
-\
- dest_data += dest_stride; \
- src_data += src_stride; \
- } \
-}
-
-SWIZZLE(3,2,1,0)
-SWIZZLE(2,1,0,3)
-SWIZZLE(3,0,1,2)
-SWIZZLE(1,2,3,0)
-
-#define SWIZZLE_OPAQUE(A,R,G,B) \
-static void \
-convert_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++) \
- { \
- for (x = 0; x < width; x++) \
- { \
- dest_data[4 * x + A] = 0xFF; \
- dest_data[4 * x + R] = src_data[3 * x + 0]; \
- dest_data[4 * x + G] = src_data[3 * x + 1]; \
- dest_data[4 * x + B] = src_data[3 * x + 2]; \
- } \
-\
- dest_data += dest_stride; \
- src_data += src_stride; \
- } \
-}
-
-SWIZZLE_OPAQUE(3,2,1,0)
-SWIZZLE_OPAQUE(3,0,1,2)
-SWIZZLE_OPAQUE(0,1,2,3)
-SWIZZLE_OPAQUE(0,3,2,1)
-
-#define PREMULTIPLY(d,c,a) G_STMT_START { guint t = c * a + 0x80; d = ((t >> 8) + t) >> 8; } G_STMT_END
-#define SWIZZLE_PREMULTIPLY(A,R,G,B, A2,R2,G2,B2) \
-static void \
-convert_swizzle_premultiply_ ## A ## R ## G ## B ## _ ## A2 ## R2 ## G2 ## B2 \
- (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++) \
- { \
- for (x = 0; x < width; x++) \
- { \
- dest_data[4 * x + A] = src_data[4 * x + A2]; \
- PREMULTIPLY(dest_data[4 * x + R], src_data[4 * x + R2], src_data[4 * x + A2]); \
- PREMULTIPLY(dest_data[4 * x + G], src_data[4 * x + G2], src_data[4 * x + A2]); \
- PREMULTIPLY(dest_data[4 * x + B], src_data[4 * x + B2], src_data[4 * x + A2]); \
- } \
-\
- dest_data += dest_stride; \
- src_data += src_stride; \
- } \
-}
-
-SWIZZLE_PREMULTIPLY (3,2,1,0, 3,2,1,0)
-SWIZZLE_PREMULTIPLY (0,1,2,3, 3,2,1,0)
-SWIZZLE_PREMULTIPLY (3,2,1,0, 0,1,2,3)
-SWIZZLE_PREMULTIPLY (0,1,2,3, 0,1,2,3)
-SWIZZLE_PREMULTIPLY (3,2,1,0, 3,0,1,2)
-SWIZZLE_PREMULTIPLY (0,1,2,3, 3,0,1,2)
-SWIZZLE_PREMULTIPLY (3,2,1,0, 0,3,2,1)
-SWIZZLE_PREMULTIPLY (0,1,2,3, 0,3,2,1)
-SWIZZLE_PREMULTIPLY (3,0,1,2, 3,2,1,0)
-SWIZZLE_PREMULTIPLY (3,0,1,2, 0,1,2,3)
-SWIZZLE_PREMULTIPLY (3,0,1,2, 3,0,1,2)
-SWIZZLE_PREMULTIPLY (3,0,1,2, 0,3,2,1)
-
-#define CONVERT_FUNC(name,suffix,R,G,B,A,step) \
-static void \
-convert_ ## name ## _to_ ## suffix (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++) \
- { \
- for (x = 0; x < width; x++) \
- { \
- guchar conv[4]; \
- convert_pixel_ ## name (conv, src_data + step * x); \
- dest_data[4 * x + R] = conv[0]; \
- dest_data[4 * x + G] = conv[1]; \
- dest_data[4 * x + B] = conv[2]; \
- dest_data[4 * x + A] = conv[3]; \
- } \
-\
- dest_data += dest_stride; \
- src_data += src_stride; \
- } \
-}
-
-#define CONVERT_FUNCS(name,step) \
-CONVERT_FUNC(name, download_le, 2, 1, 0, 3, step) \
-CONVERT_FUNC(name, download_be, 1, 2, 3, 0, step) \
-CONVERT_FUNC(name, gles_rgba, 0, 1, 2, 3, step) \
-
-static inline void
-convert_pixel_rgb16 (guchar *dest_data, const guchar *src_data)
-{
- const guint16 *src = (const guint16 *) src_data;
- dest_data[0] = (guchar)(src[0] >> 8);
- dest_data[1] = (guchar)(src[1] >> 8);
- dest_data[2] = (guchar)(src[2] >> 8);
- dest_data[3] = 0xFF;
-}
-CONVERT_FUNCS(rgb16, 3 * sizeof (guint16))
-
-static inline void
-convert_pixel_rgba16 (guchar *dest_data, const guchar *src_data)
-{
- const guint16 *src = (const guint16 *) src_data;
- dest_data[0] = (guchar)(src[0] >> 8);
- dest_data[1] = (guchar)(src[1] >> 8);
- dest_data[2] = (guchar)(src[2] >> 8);
- dest_data[3] = (guchar)(src[3] >> 8);
-}
-CONVERT_FUNCS(rgba16, 4 * sizeof (guint16))
-
-static inline void
-convert_pixel_rgb16f (guchar *dest_data, const guchar *src_data)
-{
- float src[4];
- guint16 tmp[4];
- memcpy(tmp, src_data, sizeof(guint16) * 3);
- half_to_float4(tmp, src);
- dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
- dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
- dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
- dest_data[3] = 0xFF;
-}
-CONVERT_FUNCS(rgb16f, 3 * sizeof (guint16))
-
-static inline void
-convert_pixel_rgba16f (guchar *dest_data, const guchar *src_data)
-{
- float src[4];
- half_to_float4((const guint16 *) src_data, src);
- dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
- dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
- dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
- dest_data[3] = CLAMP (src[3] * 256.f, 0.f, 255.f);
-}
-CONVERT_FUNCS(rgba16f, 4 * sizeof (guint16))
-
-static inline void
-convert_pixel_rgb32f (guchar *dest_data, const guchar *src_data)
-{
- float *src = (float *) src_data;
- dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
- dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
- dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
- dest_data[3] = 0xFF;
-}
-CONVERT_FUNCS(rgb32f, 3 * sizeof (float))
-
-static inline void
-convert_pixel_rgba32f (guchar *dest_data, const guchar *src_data)
-{
- float *src = (float *) src_data;
- dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
- dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
- dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
- dest_data[3] = CLAMP (src[3] * 256.f, 0.f, 255.f);
-}
-CONVERT_FUNCS(rgba32f, 4 * sizeof (float))
-
-typedef void (* ConversionFunc) (guchar *dest_data,
- gsize dest_stride,
- const guchar *src_data,
- gsize src_stride,
- gsize width,
- gsize height);
-
-static ConversionFunc converters[GDK_MEMORY_N_FORMATS][GDK_MEMORY_N_CONVERSIONS] =
-{
- { convert_memcpy, convert_swizzle3210, convert_swizzle2103 },
- { convert_swizzle3210, convert_memcpy, convert_swizzle3012 },
- { convert_swizzle2103, convert_swizzle1230, convert_memcpy },
- { convert_swizzle_premultiply_3210_3210, convert_swizzle_premultiply_0123_3210,
convert_swizzle_premultiply_3012_3210, },
- { convert_swizzle_premultiply_3210_0123, convert_swizzle_premultiply_0123_0123,
convert_swizzle_premultiply_3012_0123 },
- { convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012,
convert_swizzle_premultiply_3012_3012 },
- { 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_rgb16_to_download_le, convert_rgb16_to_download_be, convert_rgb16_to_gles_rgba },
- { convert_rgba16_to_download_le, convert_rgba16_to_download_be, convert_rgba16_to_gles_rgba },
- { convert_rgb16f_to_download_le, convert_rgb16f_to_download_be, convert_rgb16f_to_gles_rgba },
- { convert_rgba16f_to_download_le, convert_rgba16f_to_download_be, convert_rgba16f_to_gles_rgba },
- { convert_rgb32f_to_download_le, convert_rgb32f_to_download_be, convert_rgb32f_to_gles_rgba },
- { convert_rgba32f_to_download_le, convert_rgba32f_to_download_be, convert_rgba32f_to_gles_rgba }
-};
-
-void
-gdk_memory_convert (guchar *dest_data,
- gsize dest_stride,
- GdkMemoryConversion dest_format,
- const guchar *src_data,
- gsize src_stride,
- GdkMemoryFormat src_format,
- gsize width,
- gsize height)
-{
- g_assert (dest_format < 3);
- g_assert (src_format < GDK_MEMORY_N_FORMATS);
-
- converters[src_format][dest_format] (dest_data, dest_stride, src_data, src_stride, width, height);
-}
-
-#define CONVERT_FLOAT(R,G,B,A,premultiply) G_STMT_START {\
- for (y = 0; y < height; y++) \
- { \
- for (x = 0; x < width; x++) \
- { \
- if (A >= 0) \
- { \
- dest_data[4 * x + 0] = src_data[4 * x + R] / 255.0f; \
- dest_data[4 * x + 1] = src_data[4 * x + G] / 255.0f; \
- dest_data[4 * x + 2] = src_data[4 * x + B] / 255.0f; \
- dest_data[4 * x + 3] = src_data[4 * x + A] / 255.0f; \
- if (premultiply) \
- { \
- dest_data[4 * x + 0] *= dest_data[4 * x + 3]; \
- dest_data[4 * x + 1] *= dest_data[4 * x + 3]; \
- dest_data[4 * x + 2] *= dest_data[4 * x + 3]; \
- } \
- } \
- else \
- { \
- dest_data[4 * x + 0] = src_data[3 * x + R] / 255.0f; \
- dest_data[4 * x + 1] = src_data[3 * x + G] / 255.0f; \
- dest_data[4 * x + 2] = src_data[3 * x + B] / 255.0f; \
- dest_data[4 * x + 3] = 1.0; \
- } \
- } \
-\
- dest_data += dest_stride; \
- src_data += src_stride; \
- } \
-}G_STMT_END
-
-#define CONVERT_FLOAT_PIXEL(func,step) G_STMT_START{\
- for (y = 0; y < height; y++) \
- { \
- for (x = 0; x < width; x++) \
- { \
- func (dest_data + 4 * x, src_data + step * x); \
- } \
-\
- dest_data += dest_stride; \
- src_data += src_stride; \
- } \
-}G_STMT_END
-
-static inline void
-convert_rgb16_to_float (float *dest, const guchar *src_data)
-{
- const guint16 *src = (const guint16 *) src_data;
- dest[0] = src[0] / 65535.f;
- dest[1] = src[1] / 65535.f;
- dest[2] = src[2] / 65535.f;
- dest[3] = 1.0;
-}
-
-static inline void
-convert_rgba16_to_float (float *dest, const guchar *src_data)
-{
- const guint16 *src = (const guint16 *) src_data;
- dest[0] = src[0] / 65535.f;
- dest[1] = src[1] / 65535.f;
- dest[2] = src[2] / 65535.f;
- dest[3] = src[3] / 65535.f;
-}
-
-static inline void
-convert_rgb16f_to_float (float *dest, const guchar *src_data)
-{
- guint16 tmp[4];
- memcpy(tmp, src_data, sizeof(guint16) * 3);
- tmp[3] = FP16_ONE;
- half_to_float4 (tmp, dest);
-}
-
-static inline void
-convert_rgba16f_to_float (float *dest, const guchar *src_data)
-{
- half_to_float4 ((const guint16 *) src_data, dest);
-}
-
-static inline void
-convert_rgb32f_to_float (float *dest, const guchar *src_data)
-{
- const float *src = (const float *) src_data;
- dest[0] = src[0];
- dest[1] = src[1];
- dest[2] = src[2];
- dest[3] = 1.0;
-}
-
-static inline void
-convert_rgba32f_to_float (float *dest, const guchar *src_data)
-{
- const float *src = (const float *) src_data;
- dest[0] = src[0];
- dest[1] = src[1];
- dest[2] = src[2];
- dest[3] = src[3];
-}
-
-void
-gdk_memory_convert_to_float (float *dest_data,
- gsize dest_stride,
- const guchar *src_data,
- gsize src_stride,
- GdkMemoryFormat src_format,
- gsize width,
- gsize height)
-{
- gsize x, y;
-
- switch (src_format)
- {
- case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
- CONVERT_FLOAT (2, 1, 0, 3, FALSE);
- break;
- case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
- CONVERT_FLOAT (1, 2, 3, 0, FALSE);
- break;
- case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
- CONVERT_FLOAT (0, 1, 2, 3, FALSE);
- break;
- case GDK_MEMORY_B8G8R8A8:
- CONVERT_FLOAT (2, 1, 0, 3, TRUE);
- break;
- case GDK_MEMORY_A8R8G8B8:
- CONVERT_FLOAT (1, 2, 3, 0, TRUE);
- break;
- case GDK_MEMORY_R8G8B8A8:
- CONVERT_FLOAT (0, 1, 2, 3, TRUE);
- break;
- case GDK_MEMORY_A8B8G8R8:
- CONVERT_FLOAT (3, 2, 1, 0, TRUE);
- break;
- case GDK_MEMORY_R8G8B8:
- CONVERT_FLOAT (0, 1, 2, -1, FALSE);
- break;
- case GDK_MEMORY_B8G8R8:
- CONVERT_FLOAT (2, 1, 0, -1, FALSE);
- break;
- case GDK_MEMORY_R16G16B16:
- CONVERT_FLOAT_PIXEL (convert_rgb16_to_float, 3 * sizeof (guint16));
- break;
- case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
- CONVERT_FLOAT_PIXEL (convert_rgba16_to_float, 4 * sizeof (guint16));
- break;
- case GDK_MEMORY_R16G16B16_FLOAT:
- CONVERT_FLOAT_PIXEL (convert_rgb16f_to_float, 3 * sizeof (guint16));
- break;
- case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
- CONVERT_FLOAT_PIXEL (convert_rgba16f_to_float, 4 * sizeof (guint16));
- break;
- case GDK_MEMORY_R32G32B32_FLOAT:
- CONVERT_FLOAT_PIXEL (convert_rgb32f_to_float, 3 * sizeof (float));
- break;
- case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
- CONVERT_FLOAT_PIXEL (convert_rgba32f_to_float, 4 * sizeof (float));
- break;
-
- case GDK_MEMORY_N_FORMATS:
- default:
- g_assert_not_reached();
- }
-}
diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h
index ddd9fd1c37..f61cccb9ef 100644
--- a/gdk/gdkmemorytextureprivate.h
+++ b/gdk/gdkmemorytextureprivate.h
@@ -29,45 +29,10 @@ G_BEGIN_DECLS
#define GDK_MEMORY_GDK_PIXBUF_OPAQUE GDK_MEMORY_R8G8B8
#define GDK_MEMORY_GDK_PIXBUF_ALPHA GDK_MEMORY_R8G8B8A8
-typedef enum {
- GDK_MEMORY_CONVERT_DOWNLOAD_LITTLE_ENDIAN,
- GDK_MEMORY_CONVERT_DOWNLOAD_BIT_ENDIAN,
- GDK_MEMORY_CONVERT_GLES_RGBA,
-
- GDK_MEMORY_N_CONVERSIONS
-} GdkMemoryConversion;
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define GDK_MEMORY_CONVERT_DOWNLOAD GDK_MEMORY_CONVERT_DOWNLOAD_LITTLE_ENDIAN
-#elif G_BYTE_ORDER == G_BIG_ENDIAN
-#define GDK_MEMORY_CONVERT_DOWNLOAD GDK_MEMORY_CONVERT_DOWNLOAD_BIG_ENDIAN
-#else
-#error "Unknown byte order for GDK_MEMORY_CONVERT_DOWNLOAD"
-#endif
-
-gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format);
-
GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *self);
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
-void gdk_memory_convert (guchar *dest_data,
- gsize dest_stride,
- GdkMemoryConversion dest_format,
- const guchar *src_data,
- gsize src_stride,
- GdkMemoryFormat src_format,
- gsize width,
- gsize height);
-
-void gdk_memory_convert_to_float (float *dest_data,
- gsize dest_stride,
- const guchar *src_data,
- gsize src_stride,
- GdkMemoryFormat src_format,
- gsize width,
- gsize height);
-
G_END_DECLS
diff --git a/gdk/loaders/gdkpng.c b/gdk/loaders/gdkpng.c
index 97e6dfffd0..df453fc6a3 100644
--- a/gdk/loaders/gdkpng.c
+++ b/gdk/loaders/gdkpng.c
@@ -20,6 +20,7 @@
#include "gdkpngprivate.h"
#include "gdkintl.h"
+#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
#include "gdktexture.h"
diff --git a/gdk/loaders/gdktiff.c b/gdk/loaders/gdktiff.c
index d7416391ee..ed1b0e566b 100644
--- a/gdk/loaders/gdktiff.c
+++ b/gdk/loaders/gdktiff.c
@@ -20,6 +20,7 @@
#include "gdktiffprivate.h"
#include "gdkintl.h"
+#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
#include "gdktexture.h"
diff --git a/gdk/meson.build b/gdk/meson.build
index 06905233f8..0756f7667c 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -30,6 +30,7 @@ gdk_public_sources = files([
'gdkhsla.c',
'gdkkeys.c',
'gdkkeyuni.c',
+ 'gdkmemoryformat.c',
'gdkmemorytexture.c',
'gdkmonitor.c',
'gdkpaintable.c',
diff --git a/gsk/ngl/gsknglcommandqueue.c b/gsk/ngl/gsknglcommandqueue.c
index a5fbf0dc8d..b2a474cf59 100644
--- a/gsk/ngl/gsknglcommandqueue.c
+++ b/gsk/ngl/gsknglcommandqueue.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <gdk/gdkglcontextprivate.h>
+#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkmemorytextureprivate.h>
#include <gdk/gdkprofilerprivate.h>
#include <gsk/gskdebugprivate.h>
diff --git a/gsk/ngl/gsknglglyphlibrary.c b/gsk/ngl/gsknglglyphlibrary.c
index 33c86cc967..ede4f19105 100644
--- a/gsk/ngl/gsknglglyphlibrary.c
+++ b/gsk/ngl/gsknglglyphlibrary.c
@@ -21,7 +21,7 @@
#include "config.h"
#include <gdk/gdkglcontextprivate.h>
-#include <gdk/gdkmemorytextureprivate.h>
+#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkprofilerprivate.h>
#include "gsknglcommandqueueprivate.h"
@@ -237,7 +237,7 @@ gsk_ngl_glyph_library_upload_glyph (GskNglGlyphLibrary *self,
pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data,
width * 4,
- GDK_MEMORY_CONVERT_GLES_RGBA,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
cairo_image_surface_get_data (surface),
width * 4,
GDK_MEMORY_DEFAULT,
diff --git a/gsk/ngl/gskngliconlibrary.c b/gsk/ngl/gskngliconlibrary.c
index ab4d1b4d6f..cfc662a9e6 100644
--- a/gsk/ngl/gskngliconlibrary.c
+++ b/gsk/ngl/gskngliconlibrary.c
@@ -21,7 +21,7 @@
#include "config.h"
#include <gdk/gdkglcontextprivate.h>
-#include <gdk/gdkmemorytextureprivate.h>
+#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkprofilerprivate.h>
#include <gdk/gdktextureprivate.h>
@@ -115,7 +115,7 @@ gsk_ngl_icon_library_add (GskNglIconLibrary *self,
{
pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 4,
- GDK_MEMORY_CONVERT_GLES_RGBA,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
surface_data, cairo_image_surface_get_stride (surface),
GDK_MEMORY_DEFAULT, width, height);
gl_format = GL_RGBA;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]