[gtk/wip/otte/memoryformat] gl: Refactor texture uploading
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/memoryformat] gl: Refactor texture uploading
- Date: Tue, 12 Oct 2021 22:41:20 +0000 (UTC)
commit 68e42b86318eb531984934bba163345735defa40
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 13 00:07:08 2021 +0200
gl: Refactor texture uploading
Don't pass texture + rect, but instead have
gdk_memory_texture_new_subtexture()
and use it to generate subtextures and pass them.
This has the advantage of downloading the a too large texture only once
instead of N times.
gdk/gdkmemorytexture.c | 33 +++++++++++++++++++++++++++++++++
gdk/gdkmemorytextureprivate.h | 5 +++++
gsk/gl/gskglcommandqueue.c | 15 +++++----------
gsk/gl/gskglcommandqueueprivate.h | 4 ----
gsk/gl/gskgldriver.c | 18 +++++++++++-------
5 files changed, 54 insertions(+), 21 deletions(-)
---
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 4402998ebb..71df887b0b 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -166,6 +166,39 @@ gdk_memory_texture_new (int width,
return GDK_TEXTURE (self);
}
+GdkTexture *
+gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ GdkTexture *texture, *result;
+ gsize bpp, offset, size;
+ GBytes *bytes;
+
+ g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
+ g_return_val_if_fail (x < 0 || x >= GDK_TEXTURE (source)->width, NULL);
+ g_return_val_if_fail (y < 0 || y >= GDK_TEXTURE (source)->height, NULL);
+ g_return_val_if_fail (width <= 0 || x + width > GDK_TEXTURE (source)->width, NULL);
+ g_return_val_if_fail (height <= 0 || y + height > GDK_TEXTURE (source)->height, NULL);
+
+ texture = GDK_TEXTURE (source);
+ bpp = gdk_memory_format_bytes_per_pixel (texture->format);
+ offset = y * source->stride + x * bpp;
+ size = source->stride * (height - 1) + x * bpp;
+ bytes = g_bytes_new_from_bytes (source->bytes, offset, size);
+
+ result = gdk_memory_texture_new (texture->width,
+ texture->height,
+ texture->format,
+ bytes,
+ source->stride);
+ g_bytes_unref (bytes);
+
+ return result;
+}
+
GdkMemoryTexture *
gdk_memory_texture_from_texture (GdkTexture *texture,
GdkMemoryFormat format)
diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h
index a71648a950..57dafd567b 100644
--- a/gdk/gdkmemorytextureprivate.h
+++ b/gdk/gdkmemorytextureprivate.h
@@ -31,6 +31,11 @@ G_BEGIN_DECLS
GdkMemoryTexture * gdk_memory_texture_from_texture (GdkTexture *texture,
GdkMemoryFormat format);
+GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *texture,
+ int x,
+ int y,
+ int width,
+ int height);
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c
index 38f879c5c1..6842b032b8 100644
--- a/gsk/gl/gskglcommandqueue.c
+++ b/gsk/gl/gskglcommandqueue.c
@@ -1422,10 +1422,6 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
int
gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
GdkTexture *texture,
- guint x_offset,
- guint y_offset,
- guint width,
- guint height,
int min_filter,
int mag_filter)
{
@@ -1434,16 +1430,17 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
GdkMemoryFormat data_format;
const guchar *data;
gsize data_stride;
- gsize bpp;
+ int width, height;
int texture_id;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (!GDK_IS_GL_TEXTURE (texture));
- g_assert (x_offset + width <= gdk_texture_get_width (texture));
- g_assert (y_offset + height <= gdk_texture_get_height (texture));
g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST);
g_assert (mag_filter == GL_LINEAR || min_filter == GL_NEAREST);
+ width = gdk_texture_get_width (texture);
+ height = gdk_texture_get_height (texture);
+
if (width > self->max_texture_size || height > self->max_texture_size)
{
g_warning ("Attempt to create texture of size %ux%u but max size is %d. "
@@ -1476,14 +1473,12 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
self->n_uploads++;
- bpp = gdk_memory_format_bytes_per_pixel (data_format);
-
/* Switch to texture0 as 2D. We'll restore it later. */
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_id);
gsk_gl_command_queue_do_upload_texture (self,
- data + x_offset * bpp + y_offset * data_stride,
+ data,
width, height, data_stride,
data_format);
diff --git a/gsk/gl/gskglcommandqueueprivate.h b/gsk/gl/gskglcommandqueueprivate.h
index c4da7231c9..4147283e6d 100644
--- a/gsk/gl/gskglcommandqueueprivate.h
+++ b/gsk/gl/gskglcommandqueueprivate.h
@@ -281,10 +281,6 @@ void gsk_gl_command_queue_execute (GskGLCommandQueue
const cairo_region_t *scissor);
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
GdkTexture *texture,
- guint x_offset,
- guint y_offset,
- guint width,
- guint height,
int min_filter,
int mag_filter);
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
index 33fcf380b3..327dea93ff 100644
--- a/gsk/gl/gskgldriver.c
+++ b/gsk/gl/gskgldriver.c
@@ -798,10 +798,6 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
height = gdk_texture_get_height (texture);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
GDK_TEXTURE (downloaded_texture),
- 0,
- 0,
- width,
- height,
min_filter,
mag_filter);
@@ -1230,6 +1226,7 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
int tex_width;
int tex_height;
int x = 0, y = 0;
+ GdkMemoryTexture *memtex;
g_assert (GSK_IS_GL_DRIVER (self));
g_assert (GDK_IS_TEXTURE (texture));
@@ -1253,6 +1250,8 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
n_slices = cols * rows;
slices = g_new0 (GskGLTextureSlice, n_slices);
+ memtex = gdk_memory_texture_from_texture (texture,
+ gdk_texture_get_format (texture));
for (guint col = 0; col < cols; col ++)
{
@@ -1262,13 +1261,16 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
{
int slice_height = MIN (max_texture_size, texture->height - y);
int slice_index = (col * rows) + row;
+ GdkTexture *subtex;
guint texture_id;
+ subtex = gdk_memory_texture_new_subtexture (memtex,
+ x, y,
+ slice_width, slice_height);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
- texture,
- x, y,
- slice_width, slice_height,
+ subtex,
GL_NEAREST, GL_NEAREST);
+ g_object_unref (subtex);
slices[slice_index].rect.x = x;
slices[slice_index].rect.y = y;
@@ -1283,6 +1285,8 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
x += slice_width;
}
+ g_object_unref (memtex);
+
/* Allocate one Texture for the entire thing. */
t = gsk_gl_texture_new (0,
tex_width, tex_height,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]