[gtk/wip/otte/memoryformat: 13/17] texture: Refactor downloading
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/memoryformat: 13/17] texture: Refactor downloading
- Date: Tue, 12 Oct 2021 00:07:03 +0000 (UTC)
commit b65b64628d0b5c883ba563eda412d88758c67b89
Author: Benjamin Otte <otte redhat com>
Date: Thu Oct 7 06:19:41 2021 +0200
texture: Refactor downloading
Pass a format do GdkTextureClass::download(). That way we can download
data in any format.
Also replace gdk_texture_download_texture() with
gdk_memory_texture_from_texture() which again takes a format.
The old functionality is still there for code that wants it: Just pass
gdk_texture_get_format (texture) as the format argument.
gdk/gdkgltexture.c | 173 ++++++++++++------------------------------
gdk/gdkmemorytexture.c | 69 ++++++++++-------
gdk/gdkmemorytextureprivate.h | 3 +
gdk/gdktexture.c | 71 ++++++-----------
gdk/gdktextureprivate.h | 14 ++--
gdk/loaders/gdkpng.c | 4 +-
gdk/loaders/gdktiff.c | 4 +-
gsk/gl/gskgldriver.c | 33 ++++----
8 files changed, 144 insertions(+), 227 deletions(-)
---
diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c
index e39fcd3fbb..a6d6d6e9b3 100644
--- a/gdk/gdkgltexture.c
+++ b/gdk/gdkgltexture.c
@@ -109,15 +109,27 @@ gdk_gl_texture_run (GdkGLTexture *self,
while (g_atomic_int_get (&invoke.spinlock) == 0);
}
+typedef struct _Download Download;
+
+struct _Download
+{
+ guint gl_internalformat;
+ guint gl_format;
+ guint gl_type;
+ guchar *data;
+ gsize stride;
+};
+
static inline void
-gdk_gl_texture_get_tex_image (GdkGLTexture *self,
- GLenum gl_format,
- GLenum gl_type,
- GLvoid *data)
+gdk_gl_texture_do_download (gpointer texture_,
+ gpointer download_)
{
+ GdkGLTexture *self = texture_;
+ GdkTexture *texture = texture_;
+ Download *download = download_;
+
if (gdk_gl_context_get_use_es (self->context))
{
- GdkTexture *texture = GDK_TEXTURE (self);
GLuint fbo;
glGenFramebuffers (1, &fbo);
@@ -125,9 +137,9 @@ gdk_gl_texture_get_tex_image (GdkGLTexture *self,
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
glReadPixels (0, 0,
texture->width, texture->height,
- gl_format,
- gl_type,
- data);
+ download->gl_format,
+ download->gl_type,
+ download->data);
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glDeleteFramebuffers (1, &fbo);
}
@@ -135,136 +147,48 @@ gdk_gl_texture_get_tex_image (GdkGLTexture *self,
{
glGetTexImage (GL_TEXTURE_2D,
0,
- gl_format,
- gl_type,
- data);
+ download->gl_format,
+ download->gl_type,
+ download->data);
}
}
static void
-gdk_gl_texture_do_download_texture (gpointer texture_,
- gpointer result_)
-{
- GdkTexture *texture = texture_;
- GdkTexture **result = result_;
- guint gl_internalformat, gl_format, gl_type;
- guchar *data;
- gsize stride;
- GBytes *bytes;
-
- if (!gdk_memory_format_gl_format (texture->format,
- gdk_gl_context_get_use_es (gdk_gl_context_get_current ()),
- &gl_internalformat,
- &gl_format,
- &gl_type))
- {
- g_assert_not_reached ();
- }
-
- stride = gdk_memory_format_bytes_per_pixel (texture->format) * texture->width;
- data = g_malloc_n (stride, texture->height);
-
- gdk_gl_texture_get_tex_image (texture_,
- gl_format,
- gl_type,
- data);
-
- bytes = g_bytes_new_take (data, stride * texture->height);
- *result = gdk_memory_texture_new (texture->width,
- texture->height,
- texture->format,
- bytes,
- stride);
-
- g_bytes_unref (bytes);
-}
-
-static GdkTexture *
-gdk_gl_texture_download_texture (GdkTexture *texture)
-{
- GdkGLTexture *self = GDK_GL_TEXTURE (texture);
- GdkTexture *result;
-
- if (self->saved)
- return g_object_ref (self->saved);
-
- gdk_gl_texture_run (self, gdk_gl_texture_do_download_texture, &result);
-
- return result;
-}
-
-static void
-gdk_gl_texture_do_download (gpointer texture,
- gpointer data)
-{
- glGetTexImage (GL_TEXTURE_2D,
- 0,
- GL_BGRA,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- GL_UNSIGNED_INT_8_8_8_8_REV,
-#elif G_BYTE_ORDER == G_BIG_ENDIAN
- GL_UNSIGNED_BYTE,
-#else
-#error "Unknown byte order for gdk_gl_texture_download()"
-#endif
- data);
-}
-
-static void
-gdk_gl_texture_download (GdkTexture *texture,
- guchar *data,
- gsize stride)
+gdk_gl_texture_download (GdkTexture *texture,
+ GdkMemoryFormat format,
+ guchar *data,
+ gsize stride)
{
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
+ Download download;
if (self->saved)
{
- gdk_texture_download (self->saved, data, stride);
+ gdk_texture_do_download (self->saved, format, data, stride);
return;
}
- if (gdk_gl_context_get_use_es (self->context) ||
- stride != texture->width * 4)
- {
- GDK_TEXTURE_CLASS (gdk_gl_texture_parent_class)->download (texture, data, stride);
- return;
- }
-
- gdk_gl_texture_run (self, gdk_gl_texture_do_download, data);
-}
-
-static void
-gdk_gl_texture_do_download_float (gpointer texture,
- gpointer data)
-{
- glGetTexImage (GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- GL_FLOAT,
- data);
-}
-
-static void
-gdk_gl_texture_download_float (GdkTexture *texture,
- float *data,
- gsize stride)
-{
- GdkGLTexture *self = GDK_GL_TEXTURE (texture);
+ download.data = data;
+ download.stride = stride;
- if (self->saved)
+ if (stride != texture->width * gdk_memory_format_bytes_per_pixel (format) ||
+ !gdk_memory_format_gl_format (format,
+ gdk_gl_context_get_use_es (self->context),
+ &download.gl_internalformat,
+ &download.gl_format,
+ &download.gl_type))
{
- gdk_texture_download_float (self->saved, data, stride);
- return;
- }
+ GdkMemoryTexture *memtex;
- if (gdk_gl_context_get_use_es (self->context) ||
- stride != texture->width * 4)
- {
- GDK_TEXTURE_CLASS (gdk_gl_texture_parent_class)->download_float (texture, data, stride);
+ memtex = gdk_memory_texture_from_texture (texture,
+ format == texture->format ? GDK_MEMORY_R8G8B8A8_PREMULTIPLIED
+ : texture->format);
+ gdk_texture_do_download (GDK_TEXTURE (memtex), format, data, stride);
+ g_object_unref (memtex);
return;
}
- gdk_gl_texture_run (self, gdk_gl_texture_do_download_float, data);
+ gdk_gl_texture_run (self, gdk_gl_texture_do_download, &download);
}
static void
@@ -273,9 +197,8 @@ gdk_gl_texture_class_init (GdkGLTextureClass *klass)
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- texture_class->download_texture = gdk_gl_texture_download_texture;
texture_class->download = gdk_gl_texture_download;
- texture_class->download_float = gdk_gl_texture_download_float;
+
gobject_class->dispose = gdk_gl_texture_dispose;
}
@@ -309,10 +232,14 @@ gdk_gl_texture_get_id (GdkGLTexture *self)
void
gdk_gl_texture_release (GdkGLTexture *self)
{
+ GdkTexture *texture;
+
g_return_if_fail (GDK_IS_GL_TEXTURE (self));
g_return_if_fail (self->saved == NULL);
- self->saved = gdk_texture_download_texture (GDK_TEXTURE (self));
+ texture = GDK_TEXTURE (self);
+ self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture,
+ gdk_texture_get_format (texture)));
if (self->destroy)
{
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index e658ad97ee..4402998ebb 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -55,38 +55,16 @@ gdk_memory_texture_dispose (GObject *object)
G_OBJECT_CLASS (gdk_memory_texture_parent_class)->dispose (object);
}
-static GdkTexture *
-gdk_memory_texture_download_texture (GdkTexture *texture)
-{
- return g_object_ref (texture);
-}
-
static void
-gdk_memory_texture_download (GdkTexture *texture,
- guchar *data,
- gsize stride)
+gdk_memory_texture_download (GdkTexture *texture,
+ GdkMemoryFormat format,
+ guchar *data,
+ gsize stride)
{
GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (texture);
gdk_memory_convert (data, stride,
- GDK_MEMORY_DEFAULT,
- (guchar *) g_bytes_get_data (self->bytes, NULL),
- self->stride,
- texture->format,
- gdk_texture_get_width (texture),
- gdk_texture_get_height (texture));
-}
-
-static void
-gdk_memory_texture_download_float (GdkTexture *texture,
- float *data,
- gsize stride)
-{
- GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (texture);
-
- gdk_memory_convert ((guchar *) data,
- stride * sizeof (float),
- GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
+ format,
(guchar *) g_bytes_get_data (self->bytes, NULL),
self->stride,
texture->format,
@@ -100,9 +78,8 @@ gdk_memory_texture_class_init (GdkMemoryTextureClass *klass)
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- texture_class->download_texture = gdk_memory_texture_download_texture;
texture_class->download = gdk_memory_texture_download;
- texture_class->download_float = gdk_memory_texture_download_float;
+
gobject_class->dispose = gdk_memory_texture_dispose;
}
@@ -189,6 +166,40 @@ gdk_memory_texture_new (int width,
return GDK_TEXTURE (self);
}
+GdkMemoryTexture *
+gdk_memory_texture_from_texture (GdkTexture *texture,
+ GdkMemoryFormat format)
+{
+ GdkTexture *result;
+ GBytes *bytes;
+ guchar *data;
+ gsize stride;
+
+ g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
+
+ if (GDK_IS_MEMORY_TEXTURE (texture))
+ {
+ GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (texture);
+
+ if (gdk_texture_get_format (texture) == format)
+ return g_object_ref (memtex);
+ }
+
+ stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
+ data = g_malloc_n (stride, texture->height);
+
+ gdk_texture_do_download (texture, format, data, stride);
+ bytes = g_bytes_new_take (data, stride);
+ result = gdk_memory_texture_new (texture->width,
+ texture->height,
+ format,
+ bytes,
+ stride);
+ g_bytes_unref (bytes);
+
+ return GDK_MEMORY_TEXTURE (result);
+}
+
const guchar *
gdk_memory_texture_get_data (GdkMemoryTexture *self)
{
diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h
index 0cd5e91f27..a71648a950 100644
--- a/gdk/gdkmemorytextureprivate.h
+++ b/gdk/gdkmemorytextureprivate.h
@@ -29,6 +29,9 @@ G_BEGIN_DECLS
#define GDK_MEMORY_GDK_PIXBUF_OPAQUE GDK_MEMORY_R8G8B8
#define GDK_MEMORY_GDK_PIXBUF_ALPHA GDK_MEMORY_R8G8B8A8
+GdkMemoryTexture * gdk_memory_texture_from_texture (GdkTexture *texture,
+ GdkMemoryFormat format);
+
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index f4c5928c8d..b2213fd367 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -221,35 +221,13 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkTexture, gdk_texture, G_TYPE_OBJECT,
#define GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD(obj,method) \
g_critical ("Texture of type '%s' does not implement GdkTexture::" # method, G_OBJECT_TYPE_NAME (obj))
-static GdkTexture *
-gdk_texture_real_download_texture (GdkTexture *self)
-{
- GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download_texture);
- return NULL;
-}
-
-static void
-gdk_texture_real_download (GdkTexture *texture,
- guchar *data,
- gsize stride)
-{
- GdkTexture *memory_texture;
-
- memory_texture = gdk_texture_download_texture (texture);
- gdk_texture_download (memory_texture, data, stride);
- g_object_unref (memory_texture);
-}
-
static void
-gdk_texture_real_download_float (GdkTexture *self,
- float *data,
- gsize stride)
+gdk_texture_default_download (GdkTexture *texture,
+ GdkMemoryFormat format,
+ guchar *data,
+ gsize stride)
{
- GdkTexture *memory_texture;
-
- memory_texture = gdk_texture_download_texture (self);
- gdk_texture_download_float (memory_texture, data, stride);
- g_object_unref (memory_texture);
+ GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (texture, download);
}
static void
@@ -315,9 +293,7 @@ gdk_texture_class_init (GdkTextureClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- klass->download_texture = gdk_texture_real_download_texture;
- klass->download = gdk_texture_real_download;
- klass->download_float = gdk_texture_real_download_float;
+ klass->download = gdk_texture_default_download;
gobject_class->set_property = gdk_texture_set_property;
gobject_class->get_property = gdk_texture_get_property;
@@ -692,6 +668,15 @@ gdk_texture_get_height (GdkTexture *texture)
return texture->height;
}
+void
+gdk_texture_do_download (GdkTexture *texture,
+ GdkMemoryFormat format,
+ guchar *data,
+ gsize stride)
+{
+ GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data,stride);
+}
+
cairo_surface_t *
gdk_texture_download_surface (GdkTexture *texture)
{
@@ -750,7 +735,10 @@ gdk_texture_download (GdkTexture *texture,
g_return_if_fail (data != NULL);
g_return_if_fail (stride >= gdk_texture_get_width (texture) * 4);
- GDK_TEXTURE_GET_CLASS (texture)->download (texture, data, stride);
+ gdk_texture_do_download (texture,
+ GDK_MEMORY_DEFAULT,
+ data,
+ stride);
}
/**
@@ -789,23 +777,10 @@ gdk_texture_download_float (GdkTexture *texture,
g_return_if_fail (data != NULL);
g_return_if_fail (stride >= gdk_texture_get_width (texture) * 4);
- GDK_TEXTURE_GET_CLASS (texture)->download_float (texture, data, stride);
-}
-
-GdkTexture *
-gdk_texture_download_texture (GdkTexture *texture)
-{
- g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
-
- g_object_ref (texture);
- while (!GDK_IS_MEMORY_TEXTURE (texture))
- {
- GdkTexture *downloaded = GDK_TEXTURE_GET_CLASS (texture)->download_texture (texture);
- g_object_unref (texture);
- texture = downloaded;
- }
-
- return texture;
+ gdk_texture_do_download (texture,
+ GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
+ (guchar *) data,
+ stride);
}
GdkMemoryFormat
diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h
index 994c9901f8..a9e6ac51a2 100644
--- a/gdk/gdktextureprivate.h
+++ b/gdk/gdktextureprivate.h
@@ -27,24 +27,22 @@ struct _GdkTexture
struct _GdkTextureClass {
GObjectClass parent_class;
- /* mandatory: Download into a GdkMemoryTexture */
- GdkTexture * (* download_texture) (GdkTexture *texture);
- /* optional */
+ /* mandatory: Download in the given format into data */
void (* download) (GdkTexture *texture,
+ GdkMemoryFormat format,
guchar *data,
gsize stride);
- void (* download_float) (GdkTexture *texture,
- float *data,
- gsize stride);
};
gboolean gdk_texture_can_load (GBytes *bytes);
GdkTexture * gdk_texture_new_for_surface (cairo_surface_t *surface);
cairo_surface_t * gdk_texture_download_surface (GdkTexture *texture);
-/* NB: GdkMemoryTexture */
-GdkTexture * gdk_texture_download_texture (GdkTexture *texture);
+void gdk_texture_do_download (GdkTexture *texture,
+ GdkMemoryFormat format,
+ guchar *data,
+ gsize stride);
GdkMemoryFormat gdk_texture_get_format (GdkTexture *self);
gboolean gdk_texture_set_render_data (GdkTexture *self,
gpointer key,
diff --git a/gdk/loaders/gdkpng.c b/gdk/loaders/gdkpng.c
index 69f85eaa98..6e2278386c 100644
--- a/gdk/loaders/gdkpng.c
+++ b/gdk/loaders/gdkpng.c
@@ -479,9 +479,9 @@ gdk_save_png (GdkTexture *texture)
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
+ format = gdk_texture_get_format (texture);
- mtexture = gdk_texture_download_texture (texture);
- format = gdk_texture_get_format (mtexture);
+ mtexture = GDK_TEXTURE (gdk_memory_texture_from_texture (texture, format));
switch (format)
{
diff --git a/gdk/loaders/gdktiff.c b/gdk/loaders/gdktiff.c
index d2d8dfdbde..994f50e353 100644
--- a/gdk/loaders/gdktiff.c
+++ b/gdk/loaders/gdktiff.c
@@ -283,8 +283,8 @@ gdk_save_tiff (GdkTexture *texture)
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
- memory_texture = gdk_texture_download_texture (texture);
- format = gdk_texture_get_format (memory_texture);
+ format = gdk_texture_get_format (texture);
+ memory_texture = GDK_TEXTURE (gdk_memory_texture_from_texture (texture, format));
for (int i = 0; i < G_N_ELEMENTS (format_data); i++)
{
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
index a19522c8ca..61b8469d52 100644
--- a/gsk/gl/gskgldriver.c
+++ b/gsk/gl/gskgldriver.c
@@ -23,17 +23,14 @@
#include "config.h"
-#include <gdk/gdkglcontextprivate.h>
-#include <gdk/gdkdisplayprivate.h>
-#include <gdk/gdktextureprivate.h>
-#include <gdk/gdkprofilerprivate.h>
+#include "gskngldriverprivate.h"
+
#include <gsk/gskdebugprivate.h>
#include <gsk/gskglshaderprivate.h>
#include <gsk/gskrendererprivate.h>
#include "gskglcommandqueueprivate.h"
#include "gskglcompilerprivate.h"
-#include "gskgldriverprivate.h"
#include "gskglglyphlibraryprivate.h"
#include "gskgliconlibraryprivate.h"
#include "gskglprogramprivate.h"
@@ -41,6 +38,12 @@
#include "gskgltextureprivate.h"
#include "fp16private.h"
+#include <gdk/gdkglcontextprivate.h>
+#include <gdk/gdkdisplayprivate.h>
+#include <gdk/gdkmemorytextureprivate.h>
+#include <gdk/gdkprofilerprivate.h>
+#include <gdk/gdktextureprivate.h>
+
#define ATLAS_SIZE 512
#define MAX_OLD_RATIO 0.5
@@ -746,7 +749,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
int mag_filter)
{
GdkGLContext *context;
- GdkTexture *downloaded_texture;
+ GdkMemoryTexture *downloaded_texture;
GskGLTexture *t;
guint texture_id;
int height;
@@ -773,7 +776,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
}
else
{
- downloaded_texture = gdk_texture_download_texture (texture);
+ downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
}
}
else
@@ -784,7 +787,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
return t->texture_id;
}
- downloaded_texture = gdk_texture_download_texture (texture);
+ downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
}
/* The download_texture() call may have switched the GL context. Make sure
@@ -794,13 +797,13 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
- downloaded_texture,
- 0,
- 0,
- width,
- height,
- min_filter,
- mag_filter);
+ GDK_TEXTURE (downloaded_texture),
+ 0,
+ 0,
+ width,
+ height,
+ min_filter,
+ mag_filter);
t = gsk_gl_texture_new (texture_id,
width, height, format, min_filter, mag_filter,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]