[gtk/gamma-shenanigans: 10/10] Add gdk_texture_download_float
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gamma-shenanigans: 10/10] Add gdk_texture_download_float
- Date: Thu, 9 Sep 2021 23:30:14 +0000 (UTC)
commit fe03bfa5d0eafca965409627362e2acb7069d89e
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Sep 8 07:50:52 2021 -0400
Add gdk_texture_download_float
This will allow getting float data out of textures.
gdk/gdktexture.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
gdk/gdktexture.h | 3 ++
gdk/gdktextureprivate.h | 2 ++
3 files changed, 84 insertions(+)
---
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index 5002f3460d..118bd7930f 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -572,6 +572,85 @@ gdk_texture_download_format (GdkTexture *texture,
return GDK_TEXTURE_GET_CLASS (texture)->download_format (texture, format);
}
+/* Returns the texture data in the requested format, converting
+ * it if necessary. This will only return NULL if we don't know
+ * how to convert from the texture's format to the requested one.
+ */
+GBytes *
+gdk_texture_convert_format (GdkTexture *texture,
+ GdkMemoryFormat format)
+{
+ GdkMemoryFormat src_format;
+ GBytes *bytes;
+ int width, height, stride;
+ guchar *data;
+
+ for (int i = 0; i < GDK_MEMORY_N_FORMATS; i++)
+ {
+ bytes = gdk_texture_download_format (texture, i);
+ if (bytes)
+ {
+ src_format = i;
+ break;
+ }
+ }
+
+ if (!bytes || src_format == format)
+ return bytes;
+
+ /* convert from src_format to format */
+
+ width = gdk_texture_get_width (texture);
+ height = gdk_texture_get_height (texture);
+ stride = width * gdk_memory_format_bytes_per_pixel (format);
+ data = g_malloc (height * stride);
+
+ gdk_memory_convert (data, stride, format,
+ g_bytes_get_data (bytes, NULL),
+ g_bytes_get_size (bytes) / height,
+ src_format,
+ width, height);
+
+ g_bytes_unref (bytes);
+
+ return g_bytes_new_take (data, height * stride);
+}
+
+/*
+ * gdk_texture_download_float:
+ * @texture: a `GdkTexture`
+ * @data: (array): pointer to enough memory to be filled with the
+ * downloaded data of @texture
+ *
+ * Downloads the @texture into local memory.
+ *
+ * This may be an expensive operation, as the actual texture data
+ * may reside on a GPU or on a remote display server.
+ *
+ * The data format of the downloaded data is equivalent to
+ * GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, so every downloaded
+ * pixel requires 16 bytes of memory.
+ *
+ * Note that the caller is responsible to provide sufficiently
+ * aligned memory to access the resulting data directly as floats.
+ *
+ * Since: 4.6
+ */
+void
+gdk_texture_download_float (GdkTexture *texture,
+ float *data)
+{
+ GBytes *bytes;
+
+ bytes = gdk_texture_convert_format (texture, GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED);
+
+ g_assert (bytes);
+
+ memcpy (data, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
+
+ g_bytes_unref (bytes);
+}
+
gboolean
gdk_texture_set_render_data (GdkTexture *self,
gpointer key,
diff --git a/gdk/gdktexture.h b/gdk/gdktexture.h
index 7318ef8500..1547cce23a 100644
--- a/gdk/gdktexture.h
+++ b/gdk/gdktexture.h
@@ -59,6 +59,9 @@ GDK_AVAILABLE_IN_ALL
void gdk_texture_download (GdkTexture *texture,
guchar *data,
gsize stride);
+GDK_AVAILABLE_IN_4_6
+void gdk_texture_download_float (GdkTexture *texture,
+ float *data);
GDK_AVAILABLE_IN_ALL
gboolean gdk_texture_save_to_png (GdkTexture *texture,
const char *filename);
diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h
index f00d712d08..716071d686 100644
--- a/gdk/gdktextureprivate.h
+++ b/gdk/gdktextureprivate.h
@@ -53,6 +53,8 @@ gpointer gdk_texture_get_render_data (GdkTexture
GBytes * gdk_texture_download_format (GdkTexture *texture,
GdkMemoryFormat format);
+GBytes * gdk_texture_convert_format (GdkTexture *texture,
+ GdkMemoryFormat format);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]