[gtk/wip/chergert/glproto: 337/526] port over texture slicing
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 337/526] port over texture slicing
- Date: Tue, 16 Feb 2021 01:14:33 +0000 (UTC)
commit 06846bc5dbc6df136c63a495353a0be403bb41bf
Author: Christian Hergert <chergert redhat com>
Date: Wed Jan 27 21:30:59 2021 -0800
port over texture slicing
gsk/next/gskgldriver.c | 84 ++++++++++++++++++++++++++++++++++++++
gsk/next/gskgldriverprivate.h | 4 ++
gsk/next/gskgltexturepool.c | 8 ++++
gsk/next/gskgltexturepoolprivate.h | 40 +++++++++++-------
gsk/next/gskgltypesprivate.h | 1 +
5 files changed, 123 insertions(+), 14 deletions(-)
---
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index a2db9b8855..6f1bada783 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -1162,3 +1162,87 @@ gsk_next_driver_create_command_queue (GskNextDriver *self,
return gsk_gl_command_queue_new (context, self->shared_command_queue->uniforms);
}
+
+void
+gsk_next_driver_slice_texture (GskNextDriver *self,
+ GdkTexture *texture,
+ GskGLTextureSlice **out_slices,
+ guint *out_n_slices)
+{
+ int max_texture_size;
+ GskGLTextureSlice *slices;
+ GskGLTexture *t;
+ guint n_slices;
+ guint cols;
+ guint rows;
+ int tex_width;
+ int tex_height;
+ int x = 0, y = 0;
+
+ g_return_if_fail (GSK_IS_NEXT_DRIVER (self));
+ g_return_if_fail (GDK_IS_TEXTURE (texture));
+ g_return_if_fail (out_slices != NULL);
+ g_return_if_fail (out_n_slices != NULL);
+
+ /* XXX: Too much? */
+ max_texture_size = self->command_queue->max_texture_size / 4;
+
+ tex_width = texture->width;
+ tex_height = texture->height;
+ cols = (texture->width / max_texture_size) + 1;
+ rows = (texture->height / max_texture_size) + 1;
+
+ if ((t = gdk_texture_get_render_data (texture, self)))
+ {
+ *out_slices = t->slices;
+ *out_n_slices = t->n_slices;
+ return;
+ }
+
+ n_slices = cols * rows;
+ slices = g_new0 (GskGLTextureSlice, n_slices);
+
+ for (guint col = 0; col < cols; col ++)
+ {
+ int slice_width = MIN (max_texture_size, texture->width - x);
+
+ for (guint row = 0; row < rows; row ++)
+ {
+ int slice_height = MIN (max_texture_size, texture->height - y);
+ int slice_index = (col * rows) + row;
+ guint texture_id;
+
+ texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
+ texture,
+ x, y,
+ slice_width, slice_height,
+ GL_NEAREST, GL_NEAREST);
+
+ slices[slice_index].rect.x = x;
+ slices[slice_index].rect.y = y;
+ slices[slice_index].rect.width = slice_width;
+ slices[slice_index].rect.height = slice_height;
+ slices[slice_index].texture_id = texture_id;
+
+ y += slice_height;
+ }
+
+ y = 0;
+ x += slice_width;
+ }
+
+ /* Allocate one Texture for the entire thing. */
+ t = gsk_gl_texture_new (0,
+ tex_width, tex_height,
+ GL_NEAREST, GL_NEAREST,
+ self->current_frame_id);
+
+ /* Use gsk_gl_texture_free() as destroy notify here since we are
+ * not inserting this GskGLTexture into self->textures!
+ */
+ gdk_texture_set_render_data (texture, self, t,
+ (GDestroyNotify)gsk_gl_texture_free);
+
+ t->slices = *out_slices = slices;
+ t->n_slices = *out_n_slices = n_slices;
+}
diff --git a/gsk/next/gskgldriverprivate.h b/gsk/next/gskgldriverprivate.h
index b23cbdd649..b56310ba8b 100644
--- a/gsk/next/gskgldriverprivate.h
+++ b/gsk/next/gskgldriverprivate.h
@@ -156,6 +156,10 @@ GskGLTexture *gsk_next_driver_acquire_texture (GskNextDriver *
int mag_filter);
void gsk_next_driver_release_texture (GskNextDriver *self,
GskGLTexture *texture);
+void gsk_next_driver_slice_texture (GskNextDriver *self,
+ GdkTexture *texture,
+ GskGLTextureSlice **out_slices,
+ guint *out_n_slices);
GskGLProgram *gsk_next_driver_lookup_shader (GskNextDriver *self,
GskGLShader *shader,
GError **error);
diff --git a/gsk/next/gskgltexturepool.c b/gsk/next/gskgltexturepool.c
index 3df7856a05..49bc7c19e4 100644
--- a/gsk/next/gskgltexturepool.c
+++ b/gsk/next/gskgltexturepool.c
@@ -40,6 +40,14 @@ gsk_gl_texture_free (GskGLTexture *texture)
texture->texture_id = 0;
}
+ for (guint i = 0; i < texture->n_slices; i++)
+ {
+ glDeleteTextures (1, &texture->slices[i].texture_id);
+ texture->slices[i].texture_id = 0;
+ }
+
+ g_clear_pointer (&texture->slices, g_free);
+
g_slice_free (GskGLTexture, texture);
}
}
diff --git a/gsk/next/gskgltexturepoolprivate.h b/gsk/next/gskgltexturepoolprivate.h
index 0215db90c8..8c000b5ee8 100644
--- a/gsk/next/gskgltexturepoolprivate.h
+++ b/gsk/next/gskgltexturepoolprivate.h
@@ -25,32 +25,44 @@
G_BEGIN_DECLS
-typedef struct _GskGLTexture GskGLTexture;
-typedef struct _GskGLTexturePool GskGLTexturePool;
-
-struct _GskGLTexturePool
+typedef struct _GskGLTexturePool
{
GQueue by_width;
GQueue by_height;
+} GskGLTexturePool;
+
+struct _GskGLTextureSlice
+{
+ cairo_rectangle_int_t rect;
+ guint texture_id;
};
struct _GskGLTexture
{
- GList width_link; /* Used to sort textures by width */
- GList height_link; /* Used to sort textures by height */
+ /* Used to sort by width/height in pool */
+ GList width_link;
+ GList height_link;
+
+ /* Identifier of the frame that created it */
+ gint64 last_used_in_frame;
- gint64 last_used_in_frame;
+ /* Backpointer to texture (can be cleared asynchronously) */
+ GdkTexture *user;
- GdkTexture *user;
+ /* Only used by sliced textures */
+ GskGLTextureSlice *slices;
+ guint n_slices;
- guint texture_id;
+ /* The actual GL texture identifier in some shared context */
+ guint texture_id;
- float width;
- float height;
- int min_filter;
- int mag_filter;
+ float width;
+ float height;
+ int min_filter;
+ int mag_filter;
- guint permanent : 1;
+ /* Set when used by an atlas so we don't drop the texture */
+ guint permanent : 1;
};
void gsk_gl_texture_pool_init (GskGLTexturePool *self);
diff --git a/gsk/next/gskgltypesprivate.h b/gsk/next/gskgltypesprivate.h
index efb2c4c500..5927d780fc 100644
--- a/gsk/next/gskgltypesprivate.h
+++ b/gsk/next/gskgltypesprivate.h
@@ -42,6 +42,7 @@ typedef struct _GskGLProgram GskGLProgram;
typedef struct _GskGLRenderJob GskGLRenderJob;
typedef struct _GskGLShadowLibrary GskGLShadowLibrary;
typedef struct _GskGLTexture GskGLTexture;
+typedef struct _GskGLTextureSlice GskGLTextureSlice;
typedef struct _GskGLTextureAtlas GskGLTextureAtlas;
typedef struct _GskGLTextureLibrary GskGLTextureLibrary;
typedef struct _GskGLUniformState GskGLUniformState;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]