From 01ff6c1c22051cbc943b72bad8ecefbf6123dcc5 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 06:18:37 +0100 Subject: [PATCH 01/10] memorytexture: Use right size for GBytes The GBytes were created with the wrong size. Nobody seems to have looked at it. --- gdk/gdkmemorytexture.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c index e241ebd0a3..6f9967dcfb 100644 --- a/gdk/gdkmemorytexture.c +++ b/gdk/gdkmemorytexture.c @@ -222,7 +222,7 @@ gdk_memory_texture_from_texture (GdkTexture *texture, data = g_malloc_n (stride, texture->height); gdk_texture_do_download (texture, format, data, stride); - bytes = g_bytes_new_take (data, stride); + bytes = g_bytes_new_take (data, stride * texture->height); result = gdk_memory_texture_new (texture->width, texture->height, format, @@ -239,6 +239,12 @@ gdk_memory_texture_get_data (GdkMemoryTexture *self) return g_bytes_get_data (self->bytes, NULL); } +GBytes * +gdk_memory_texture_get_bytes (GdkMemoryTexture *self) +{ + return self->bytes; +} + gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self) { From 51ed1442a2b49893feae50e8a4c704c72c549759 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:00:39 +0100 Subject: [PATCH 02/10] gdk: Add GdkTextureDownloader It's the new object that allows more control about accessing texture data. --- gdk/gdk.h | 1 + gdk/gdkmemorytextureprivate.h | 1 + gdk/gdktexturedownloader.c | 269 ++++++++++++++++++++++++++++++ gdk/gdktexturedownloader.h | 69 ++++++++ gdk/gdktexturedownloaderprivate.h | 41 +++++ gdk/gdktypes.h | 1 + gdk/meson.build | 2 + 7 files changed, 384 insertions(+) create mode 100644 gdk/gdktexturedownloader.c create mode 100644 gdk/gdktexturedownloader.h create mode 100644 gdk/gdktexturedownloaderprivate.h diff --git a/gdk/gdk.h b/gdk/gdk.h index a91ec39f45..af43c7f175 100644 --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h index 57dafd567b..7e4092b77c 100644 --- a/gdk/gdkmemorytextureprivate.h +++ b/gdk/gdkmemorytextureprivate.h @@ -38,6 +38,7 @@ GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture * int height); const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self); +GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self); gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self); diff --git a/gdk/gdktexturedownloader.c b/gdk/gdktexturedownloader.c new file mode 100644 index 0000000000..f45a6aceb7 --- /dev/null +++ b/gdk/gdktexturedownloader.c @@ -0,0 +1,269 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2023 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 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 . + */ + +/** + * GdkTextureDownloader: + * + * The `GdkTextureDownloader` is used to download the contents of a + * [class@Gdk.Texture]. + * + * It is intended to be created as a short-term object for a single download, + * but can be used for multipe downloads of different textures or with different + * settings. + * + * `GdkTextureDownloader` can be used to convert data between different formats. + * Create a `GdkTexture` for the existing format and then download it in a + * different format. + * + * Since: 4.10 + */ + +#include "config.h" + +#include "gdktexturedownloaderprivate.h" + +#include "gdkmemoryformatprivate.h" +#include "gdkmemorytextureprivate.h" +#include "gdktextureprivate.h" + +G_DEFINE_BOXED_TYPE (GdkTextureDownloader, gdk_texture_downloader, + gdk_texture_downloader_copy, + gdk_texture_downloader_free) + + +void +gdk_texture_downloader_init (GdkTextureDownloader *self, + GdkTexture *texture) +{ + self->texture = g_object_ref (texture); + self->format = GDK_MEMORY_DEFAULT; +} + +void +gdk_texture_downloader_finish (GdkTextureDownloader *self) +{ + g_object_unref (self->texture); +} + +/** + * gdk_texture_downloader_new: + * @texture: texture to download + * + * Creates a new texture downloader for @texture. + * + * Returns: A new texture downloader + * + * Since: 4.10 + **/ +GdkTextureDownloader * +gdk_texture_downloader_new (GdkTexture *texture) +{ + GdkTextureDownloader *self; + + g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL); + + self = g_slice_new (GdkTextureDownloader); + gdk_texture_downloader_init (self, texture); + + return self; +} + +/** + * gdk_texture_downloader_copy: + * @self: the downloader to copy + * + * Creates a copy of the downloader. + * + * This function is meant for language bindings. + * + * Returns: A copy of the downloader + * + * Since: 4.10 + **/ +GdkTextureDownloader * +gdk_texture_downloader_copy (const GdkTextureDownloader *self) +{ + GdkTextureDownloader *copy; + + g_return_val_if_fail (self != NULL, NULL); + + copy = gdk_texture_downloader_new (self->texture); + gdk_texture_downloader_set_format (copy, self->format); + + return copy; +} + +/** + * gdk_texture_downloader_free: + * @self: texture downloader to free + * + * Frees the given downloader and all its associated resources. + * + * Since: 4.10 + **/ +void +gdk_texture_downloader_free (GdkTextureDownloader *self) +{ + g_return_if_fail (self != NULL); + + gdk_texture_downloader_finish (self); + g_slice_free (GdkTextureDownloader, self); +} + +/** + * gdk_texture_downloader_set_texture: + * @self: a texture downloader + * @texture: the new texture to download + * + * Changes the texture the downloader will download. + * + * Since: 4.10 + **/ +void +gdk_texture_downloader_set_texture (GdkTextureDownloader *self, + GdkTexture *texture) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (GDK_IS_TEXTURE (texture)); + + g_set_object (&self->texture, texture); +} + +/** + * gdk_texture_downloader_get_texture: + * @self: a texture downloader + * + * Gets the texture that the downloader will download. + * + * Returns: (transfer none): The texture to download + * + * Since: 4.10 + **/ +GdkTexture * +gdk_texture_downloader_get_texture (const GdkTextureDownloader *self) +{ + g_return_val_if_fail (self != NULL, NULL); + + return self->texture; +} + +/** + * gdk_texture_downloader_set_format: + * @self: a texture downloader + * @format: the format to use + * + * Sets the format the downloader will download. + * + * By default, GDK_MEMORY_DEFAULT is set. + * + * Since: 4.10 + */ +void +gdk_texture_downloader_set_format (GdkTextureDownloader *self, + GdkMemoryFormat format) +{ + g_return_if_fail (self != NULL); + + self->format = format; +} + +/** + * gdk_texture_downloader_get_format: + * @self: a texture downloader + * + * Gets the format that the data will be downloaded in. + * + * Returns: The format of the download + * + * Since: 4.10 + **/ +GdkMemoryFormat +gdk_texture_downloader_get_format (const GdkTextureDownloader *self) +{ + g_return_val_if_fail (self != NULL, GDK_MEMORY_DEFAULT); + + return self->format; +} + +/** + * gdk_texture_downloader_download_into: + * @self: a texture downloader + * @data: (array): pointer to enough memory to be filled with the + * downloaded data of the texture + * @stride: rowstride in bytes + * + * Downloads the @texture into local memory. + * + * Since: 4.10 + **/ +void +gdk_texture_downloader_download_into (const GdkTextureDownloader *self, + guchar *data, + gsize stride) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (data != NULL); + g_return_if_fail (stride >= gdk_texture_get_width (self->texture) * gdk_memory_format_bytes_per_pixel (self->format)); + + gdk_texture_do_download (self->texture, self->format, data, stride); +} + +/** + * gdk_texture_downloader_download_bytes: + * @self: the downloader + * @out_stride: (out): The stride of the resulting data in bytes. + * + * Downloads the given texture pixels into a `GBytes`. The rowstride will + * be stored in the stride value. + * + * This function will abort if it tries to download a large texture and + * fails to allocate memory. If you think that may happen, you should + * handle memory allocation yourself and use + * gdk_texture_downloader_download_into() once allocation succeeded. + * + * Returns: The downloaded pixels. + * + * Since: 4.10 + **/ +GBytes * +gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self, + gsize *out_stride) +{ + guchar *data; + gsize stride; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (out_stride != NULL, NULL); + + if (GDK_IS_MEMORY_TEXTURE (self->texture) && + gdk_texture_get_format (self->texture) == self->format) + { + GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (self->texture); + + *out_stride = gdk_memory_texture_get_stride (memtex); + return g_bytes_ref (gdk_memory_texture_get_bytes (memtex)); + } + + stride = self->texture->width * gdk_memory_format_bytes_per_pixel (self->format); + data = g_malloc_n (stride, self->texture->height); + + gdk_texture_do_download (self->texture, self->format, data, stride); + + *out_stride = stride; + return g_bytes_new_take (data, stride * self->texture->height); +} + diff --git a/gdk/gdktexturedownloader.h b/gdk/gdktexturedownloader.h new file mode 100644 index 0000000000..0bdb75b573 --- /dev/null +++ b/gdk/gdktexturedownloader.h @@ -0,0 +1,69 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2023 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 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 . + */ + +#ifndef __GTK_TEXTURE_DOWNLOADER_H__ +#define __GTK_TEXTURE_DOWNLOADER_H__ + +#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + + +#include +#include +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_TEXTURE_DOWNLOADER (gdk_texture_downloader_get_type ()) + +GDK_AVAILABLE_IN_4_10 +GType gdk_texture_downloader_get_type (void) G_GNUC_CONST; +GDK_AVAILABLE_IN_4_10 +GdkTextureDownloader * gdk_texture_downloader_new (GdkTexture *texture); + +GDK_AVAILABLE_IN_4_10 +GdkTextureDownloader * gdk_texture_downloader_copy (const GdkTextureDownloader *self); +GDK_AVAILABLE_IN_4_10 +void gdk_texture_downloader_free (GdkTextureDownloader *self); + + +GDK_AVAILABLE_IN_4_10 +void gdk_texture_downloader_set_texture (GdkTextureDownloader *self, + GdkTexture *texture); +GDK_AVAILABLE_IN_4_10 +GdkTexture * gdk_texture_downloader_get_texture (const GdkTextureDownloader *self); +GDK_AVAILABLE_IN_4_10 +void gdk_texture_downloader_set_format (GdkTextureDownloader *self, + GdkMemoryFormat format); +GDK_AVAILABLE_IN_4_10 +GdkMemoryFormat gdk_texture_downloader_get_format (const GdkTextureDownloader *self); + + +GDK_AVAILABLE_IN_4_10 +void gdk_texture_downloader_download_into (const GdkTextureDownloader *self, + guchar *data, + gsize stride); +GDK_AVAILABLE_IN_4_10 +GBytes * gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self, + gsize *out_stride); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkTextureDownloader, gdk_texture_downloader_free) + +G_END_DECLS + +#endif /* __GTK_TEXTURE_DOWNLOADER_H__ */ diff --git a/gdk/gdktexturedownloaderprivate.h b/gdk/gdktexturedownloaderprivate.h new file mode 100644 index 0000000000..ca83889210 --- /dev/null +++ b/gdk/gdktexturedownloaderprivate.h @@ -0,0 +1,41 @@ +/* GTK - The GIMP Toolkit + * + * Copyright (C) 2023 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 . + */ + + +#ifndef __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__ +#define __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__ + +#include "gdktexturedownloader.h" + +G_BEGIN_DECLS + +struct _GdkTextureDownloader +{ + /*< private >*/ + GdkTexture *texture; + GdkMemoryFormat format; +}; + +void gdk_texture_downloader_init (GdkTextureDownloader *self, + GdkTexture *texture); +void gdk_texture_downloader_finish (GdkTextureDownloader *self); + + +G_END_DECLS + +#endif /* __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__ */ diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 3cf195df09..fc3b16e3c7 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -77,6 +77,7 @@ typedef struct _GdkContentFormats GdkContentFormats; typedef struct _GdkContentProvider GdkContentProvider; typedef struct _GdkCursor GdkCursor; typedef struct _GdkTexture GdkTexture; +typedef struct _GdkTextureDownloader GdkTextureDownloader; typedef struct _GdkDevice GdkDevice; typedef struct _GdkDrag GdkDrag; typedef struct _GdkDrop GdkDrop; diff --git a/gdk/meson.build b/gdk/meson.build index c690ef821e..b903747fc6 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -43,6 +43,7 @@ gdk_public_sources = files([ 'gdkseatdefault.c', 'gdksnapshot.c', 'gdktexture.c', + 'gdktexturedownloader.c', 'gdkvulkancontext.c', 'gdksurface.c', 'gdkpopuplayout.c', @@ -95,6 +96,7 @@ gdk_public_headers = files([ 'gdkseat.h', 'gdksnapshot.h', 'gdktexture.h', + 'gdktexturedownloader.h', 'gdktypes.h', 'gdkvulkancontext.h', 'gdksurface.h', From 4afec951c7e22c729131c007cb102b0204bf6574 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:18:34 +0100 Subject: [PATCH 03/10] pixbuf: Use GdkTextureDownloader when downloading pixbufs --- gdk/gdkpixbuf.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/gdk/gdkpixbuf.c b/gdk/gdkpixbuf.c index 15b886357e..7a4e35962d 100644 --- a/gdk/gdkpixbuf.c +++ b/gdk/gdkpixbuf.c @@ -28,6 +28,7 @@ #include "gdkmemorytextureprivate.h" #include "gdksurface.h" #include "gdktextureprivate.h" +#include "gdktexturedownloaderprivate.h" #include @@ -218,9 +219,9 @@ gdk_pixbuf_get_from_surface (cairo_surface_t *surface, static void pixbuf_texture_unref_cb (guchar *pixels, - gpointer texture) + gpointer bytes) { - g_object_unref (texture); + g_bytes_unref (bytes); } /** @@ -238,22 +239,27 @@ pixbuf_texture_unref_cb (guchar *pixels, GdkPixbuf * gdk_pixbuf_get_from_texture (GdkTexture *texture) { - GdkMemoryTexture *memtex; + GdkTextureDownloader downloader; + GBytes *bytes; + gsize stride; gboolean alpha; alpha = gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_OPAQUE; - memtex = gdk_memory_texture_from_texture (texture, - alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA - : GDK_MEMORY_GDK_PIXBUF_OPAQUE); + gdk_texture_downloader_init (&downloader, texture); + gdk_texture_downloader_set_format (&downloader, + alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA + : GDK_MEMORY_GDK_PIXBUF_OPAQUE); + bytes = gdk_texture_downloader_download_bytes (&downloader, &stride); + gdk_texture_downloader_finish (&downloader); - return gdk_pixbuf_new_from_data (gdk_memory_texture_get_data (memtex), + return gdk_pixbuf_new_from_data (g_bytes_get_data (bytes, NULL), GDK_COLORSPACE_RGB, alpha, 8, - gdk_texture_get_width (GDK_TEXTURE (memtex)), - gdk_texture_get_height (GDK_TEXTURE (memtex)), - gdk_memory_texture_get_stride (memtex), + gdk_texture_get_width (texture), + gdk_texture_get_height (texture), + stride, pixbuf_texture_unref_cb, - memtex); + bytes); } From f05d801e28c13f8741e673d974df106a8d6b8f3d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:18:59 +0100 Subject: [PATCH 04/10] jpeg: Use GdkTexureDownloader when saving --- gdk/loaders/gdkjpeg.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/gdk/loaders/gdkjpeg.c b/gdk/loaders/gdkjpeg.c index 6eada9d515..29f9756bb3 100644 --- a/gdk/loaders/gdkjpeg.c +++ b/gdk/loaders/gdkjpeg.c @@ -23,7 +23,7 @@ #include #include "gdktexture.h" -#include "gdkmemorytextureprivate.h" +#include "gdktexturedownloaderprivate.h" #include "gdkprofilerprivate.h" @@ -251,7 +251,8 @@ gdk_save_jpeg (GdkTexture *texture) guchar *data = NULL; gulong size = 0; guchar *input = NULL; - GdkMemoryTexture *memtex = NULL; + GdkTextureDownloader downloader; + GBytes *texbytes; const guchar *texdata; gsize texstride; guchar *row; @@ -270,7 +271,7 @@ gdk_save_jpeg (GdkTexture *texture) free (data); g_free (input); jpeg_destroy_compress (&info); - g_clear_object (&memtex); + g_clear_pointer (&texbytes, g_bytes_unref); return NULL; } @@ -289,10 +290,11 @@ gdk_save_jpeg (GdkTexture *texture) jpeg_mem_dest (&info, &data, &size); - memtex = gdk_memory_texture_from_texture (texture, - GDK_MEMORY_R8G8B8); - texdata = gdk_memory_texture_get_data (memtex); - texstride = gdk_memory_texture_get_stride (memtex); + gdk_texture_downloader_init (&downloader, texture); + gdk_texture_downloader_set_format (&downloader, GDK_MEMORY_R8G8B8); + texbytes = gdk_texture_downloader_download_bytes (&downloader, &texstride); + gdk_texture_downloader_finish (&downloader); + texdata = g_bytes_get_data (texbytes, NULL); jpeg_start_compress (&info, TRUE); @@ -304,7 +306,7 @@ gdk_save_jpeg (GdkTexture *texture) jpeg_finish_compress (&info); - g_object_unref (memtex); + g_bytes_unref (texbytes); g_free (input); jpeg_destroy_compress (&info); From eb45b8083aa86d3a14e46d725d192fce0c946950 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:19:18 +0100 Subject: [PATCH 05/10] png: Use GdkTexureDownloader when saving --- gdk/loaders/gdkpng.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/gdk/loaders/gdkpng.c b/gdk/loaders/gdkpng.c index 3d4172f9ed..fb4158f3cb 100644 --- a/gdk/loaders/gdkpng.c +++ b/gdk/loaders/gdkpng.c @@ -21,9 +21,9 @@ #include #include "gdkmemoryformatprivate.h" -#include "gdkmemorytextureprivate.h" +#include "gdkmemorytexture.h" #include "gdkprofilerprivate.h" -#include "gdktexture.h" +#include "gdktexturedownloaderprivate.h" #include "gdktextureprivate.h" #include "gsk/gl/fp16private.h" #include @@ -297,11 +297,12 @@ gdk_save_png (GdkTexture *texture) png_info *info; png_io io = { NULL, 0, 0 }; int width, height; + int y; + GdkMemoryFormat format; + GdkTextureDownloader downloader; + GBytes *bytes; gsize stride; const guchar *data; - int y; - GdkMemoryTexture *memtex; - GdkMemoryFormat format; int png_format; int depth; @@ -370,11 +371,15 @@ gdk_save_png (GdkTexture *texture) return NULL; } - memtex = gdk_memory_texture_from_texture (texture, format); + gdk_texture_downloader_init (&downloader, texture); + gdk_texture_downloader_set_format (&downloader, format); + bytes = gdk_texture_downloader_download_bytes (&downloader, &stride); + gdk_texture_downloader_finish (&downloader); + data = g_bytes_get_data (bytes, NULL); if (sigsetjmp (png_jmpbuf (png), 1)) { - g_object_unref (memtex); + g_bytes_unref (bytes); g_free (io.data); png_destroy_read_struct (&png, &info, NULL); return NULL; @@ -394,8 +399,6 @@ gdk_save_png (GdkTexture *texture) png_set_swap (png); #endif - data = gdk_memory_texture_get_data (memtex); - stride = gdk_memory_texture_get_stride (memtex); for (y = 0; y < height; y++) png_write_row (png, data + y * stride); @@ -403,7 +406,7 @@ gdk_save_png (GdkTexture *texture) png_destroy_write_struct (&png, &info); - g_object_unref (memtex); + g_bytes_unref (bytes); return g_bytes_new_take (io.data, io.size); } From b30af72125e2b79562223fecba5a7506df218f48 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:19:27 +0100 Subject: [PATCH 06/10] tiff: Use GdkTexureDownloader when saving --- gdk/loaders/gdktiff.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/gdk/loaders/gdktiff.c b/gdk/loaders/gdktiff.c index eab69bb2d9..489a962bd8 100644 --- a/gdk/loaders/gdktiff.c +++ b/gdk/loaders/gdktiff.c @@ -21,9 +21,9 @@ #include #include "gdkmemoryformatprivate.h" -#include "gdkmemorytextureprivate.h" +#include "gdkmemorytexture.h" #include "gdkprofilerprivate.h" -#include "gdktexture.h" +#include "gdktexturedownloaderprivate.h" #include "gdktextureprivate.h" #include @@ -260,11 +260,12 @@ GBytes * gdk_save_tiff (GdkTexture *texture) { TIFF *tif; - int width, height, stride; + int width, height; + gsize stride; const guchar *line; const guchar *data; - GBytes *result = NULL; - GdkMemoryTexture *memtex; + GBytes *bytes, *result = NULL; + GdkTextureDownloader downloader; GdkMemoryFormat format; const FormatData *fdata = NULL; @@ -292,9 +293,11 @@ gdk_save_tiff (GdkTexture *texture) TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - memtex = gdk_memory_texture_from_texture (texture, fdata->format); - data = gdk_memory_texture_get_data (memtex); - stride = gdk_memory_texture_get_stride (memtex); + gdk_texture_downloader_init (&downloader, texture); + gdk_texture_downloader_set_format (&downloader, fdata->format); + bytes = gdk_texture_downloader_download_bytes (&downloader, &stride); + gdk_texture_downloader_finish (&downloader); + data = g_bytes_get_data (bytes, NULL); line = (const guchar *)data; for (int y = 0; y < height; y++) @@ -302,7 +305,7 @@ gdk_save_tiff (GdkTexture *texture) if (TIFFWriteScanline (tif, (void *)line, y, 0) == -1) { TIFFClose (tif); - g_object_unref (memtex); + g_bytes_unref (bytes); return NULL; } @@ -314,7 +317,7 @@ gdk_save_tiff (GdkTexture *texture) g_assert (result); - g_object_unref (memtex); + g_bytes_unref (bytes); return result; } From ce0123ea584dd6052331962182f4360cdccceb29 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:20:40 +0100 Subject: [PATCH 07/10] docs: Link from gdk_texture_download() to GdkTextureDownloader --- gdk/gdktexture.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c index bac18dc9fe..c37fd248aa 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -722,6 +722,9 @@ gdk_texture_download_surface (GdkTexture *texture) * cairo_image_surface_get_stride (surface)); * cairo_surface_mark_dirty (surface); * ``` + * + * For more flexible download capabilites, see + * [struct@Gdk.TextureDownloader]. */ void gdk_texture_download (GdkTexture *texture, From c9f54ca37105cfe248717a5b4122ec8fd8ebe598 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:33:46 +0100 Subject: [PATCH 08/10] texture: Export gdk_texture_get_format() The API docs outline why quite well. This should make it possible to do saving of textures to image files without any private API with the same featureset that GTK uses. Also remove the gsktextureprivate.h include where gdk_texture_get_format() was the only reason for it. --- gdk/gdkgltexture.c | 1 - gdk/gdkpixbuf.c | 1 - gdk/gdktexture.c | 20 ++++++++++++++++++++ gdk/gdktexture.h | 3 +++ gdk/gdktextureprivate.h | 1 - gdk/loaders/gdkpng.c | 1 - gdk/loaders/gdktiff.c | 1 - gsk/gl/gskgldriver.c | 1 - 8 files changed, 23 insertions(+), 6 deletions(-) diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c index a5be81e676..f8ff9344c1 100644 --- a/gdk/gdkgltexture.c +++ b/gdk/gdkgltexture.c @@ -24,7 +24,6 @@ #include "gdkglcontextprivate.h" #include "gdkmemoryformatprivate.h" #include "gdkmemorytextureprivate.h" -#include "gdktextureprivate.h" #include diff --git a/gdk/gdkpixbuf.c b/gdk/gdkpixbuf.c index 7a4e35962d..3e3a20336f 100644 --- a/gdk/gdkpixbuf.c +++ b/gdk/gdkpixbuf.c @@ -27,7 +27,6 @@ #include "gdkmemoryformatprivate.h" #include "gdkmemorytextureprivate.h" #include "gdksurface.h" -#include "gdktextureprivate.h" #include "gdktexturedownloaderprivate.h" #include diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c index c37fd248aa..007901ffe8 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -741,9 +741,29 @@ gdk_texture_download (GdkTexture *texture, stride); } +/** + * gdk_texture_get_format: + * @self: a GdkTexture + * + * Gets the memory format most closely associated with the data of + * the texture. + * + * Note that it may not be an exact match for texture data + * stored on the GPU or with compression. + * + * The format can give an indication about the bit depth and opacity + * of the texture and is useful to determine the best format for + * downloading the texture. + * + * Returns: the preferred format for the texture's data + * + * Since: 4.10 + **/ GdkMemoryFormat gdk_texture_get_format (GdkTexture *self) { + g_return_val_if_fail (GDK_IS_TEXTURE (self), GDK_MEMORY_DEFAULT); + return self->format; } diff --git a/gdk/gdktexture.h b/gdk/gdktexture.h index 8ce4bae5b2..5a28f55ad0 100644 --- a/gdk/gdktexture.h +++ b/gdk/gdktexture.h @@ -24,6 +24,7 @@ #endif #include +#include #include #include @@ -82,6 +83,8 @@ GDK_AVAILABLE_IN_ALL int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE; GDK_AVAILABLE_IN_ALL int gdk_texture_get_height (GdkTexture *texture) G_GNUC_PURE; +GDK_AVAILABLE_IN_4_10 +GdkMemoryFormat gdk_texture_get_format (GdkTexture *self) G_GNUC_PURE; GDK_AVAILABLE_IN_ALL void gdk_texture_download (GdkTexture *texture, diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h index fd9f78053e..3a2330c373 100644 --- a/gdk/gdktextureprivate.h +++ b/gdk/gdktextureprivate.h @@ -43,7 +43,6 @@ void gdk_texture_do_download (GdkTexture GdkMemoryFormat format, guchar *data, gsize stride); -GdkMemoryFormat gdk_texture_get_format (GdkTexture *self); gboolean gdk_texture_set_render_data (GdkTexture *self, gpointer key, gpointer data, diff --git a/gdk/loaders/gdkpng.c b/gdk/loaders/gdkpng.c index fb4158f3cb..d5991fde38 100644 --- a/gdk/loaders/gdkpng.c +++ b/gdk/loaders/gdkpng.c @@ -24,7 +24,6 @@ #include "gdkmemorytexture.h" #include "gdkprofilerprivate.h" #include "gdktexturedownloaderprivate.h" -#include "gdktextureprivate.h" #include "gsk/gl/fp16private.h" #include #include diff --git a/gdk/loaders/gdktiff.c b/gdk/loaders/gdktiff.c index 489a962bd8..d112ff1626 100644 --- a/gdk/loaders/gdktiff.c +++ b/gdk/loaders/gdktiff.c @@ -24,7 +24,6 @@ #include "gdkmemorytexture.h" #include "gdkprofilerprivate.h" #include "gdktexturedownloaderprivate.h" -#include "gdktextureprivate.h" #include diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 4e38dad685..727ce079bb 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -35,7 +35,6 @@ #include "gskgliconlibraryprivate.h" #include "gskglprogramprivate.h" #include "gskglshadowlibraryprivate.h" -#include "gskgltextureprivate.h" #include "fp16private.h" #include From 774696011d4ae81fa422772ea59d7053474fd8fb Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:41:11 +0100 Subject: [PATCH 09/10] glrenderer: Use GdkTexureDownloader --- gsk/gl/gskglcommandqueue.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c index 72d2b320d0..8fee49fd15 100644 --- a/gsk/gl/gskglcommandqueue.c +++ b/gsk/gl/gskglcommandqueue.c @@ -27,8 +27,8 @@ #include #include -#include #include +#include #include #include @@ -1359,7 +1359,8 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self, GdkGLContext *context; const guchar *data; gsize stride; - GdkMemoryTexture *memtex; + GBytes *bytes; + GdkTextureDownloader downloader; GdkMemoryFormat data_format; int width, height; GLenum gl_internalformat; @@ -1394,9 +1395,11 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self, } } - memtex = gdk_memory_texture_from_texture (texture, data_format); - data = gdk_memory_texture_get_data (memtex); - stride = gdk_memory_texture_get_stride (memtex); + gdk_texture_downloader_init (&downloader, texture); + gdk_texture_downloader_set_format (&downloader, data_format); + bytes = gdk_texture_downloader_download_bytes (&downloader, &stride); + gdk_texture_downloader_finish (&downloader); + data = g_bytes_get_data (bytes, NULL); bpp = gdk_memory_format_bytes_per_pixel (data_format); glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format)); @@ -1426,7 +1429,7 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self, } glPixelStorei (GL_UNPACK_ALIGNMENT, 4); - g_object_unref (memtex); + g_bytes_unref (bytes); } int From cca5de3c7f0de75fdd4476caa3def9581b8ea7fc Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 14 Feb 2023 07:45:52 +0100 Subject: [PATCH 10/10] memorytexture: Export less private API It's not needed anymore with GdkTextureDownloader now. --- gdk/gdkmemorytexture.c | 16 +++------------- gdk/gdkmemorytextureprivate.h | 5 ++--- gdk/gdktexturedownloader.c | 3 +-- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c index 6f9967dcfb..641386b786 100644 --- a/gdk/gdkmemorytexture.c +++ b/gdk/gdkmemorytexture.c @@ -233,21 +233,11 @@ gdk_memory_texture_from_texture (GdkTexture *texture, return GDK_MEMORY_TEXTURE (result); } -const guchar * -gdk_memory_texture_get_data (GdkMemoryTexture *self) -{ - return g_bytes_get_data (self->bytes, NULL); -} - GBytes * -gdk_memory_texture_get_bytes (GdkMemoryTexture *self) +gdk_memory_texture_get_bytes (GdkMemoryTexture *self, + gsize *out_stride) { + *out_stride = self->stride; return self->bytes; } -gsize -gdk_memory_texture_get_stride (GdkMemoryTexture *self) -{ - return self->stride; -} - diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h index 7e4092b77c..f182f7fbd9 100644 --- a/gdk/gdkmemorytextureprivate.h +++ b/gdk/gdkmemorytextureprivate.h @@ -37,9 +37,8 @@ GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture * int width, int height); -const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self); -GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self); -gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self); +GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self, + gsize *out_stride); G_END_DECLS diff --git a/gdk/gdktexturedownloader.c b/gdk/gdktexturedownloader.c index f45a6aceb7..4a948dc40a 100644 --- a/gdk/gdktexturedownloader.c +++ b/gdk/gdktexturedownloader.c @@ -254,8 +254,7 @@ gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self, { GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (self->texture); - *out_stride = gdk_memory_texture_get_stride (memtex); - return g_bytes_ref (gdk_memory_texture_get_bytes (memtex)); + return g_bytes_ref (gdk_memory_texture_get_bytes (memtex, out_stride)); } stride = self->texture->width * gdk_memory_format_bytes_per_pixel (self->format);