[gtk/wip/chergert/glyphy: 3/7] gsk/gl: allow texture libraries more allocation control
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glyphy: 3/7] gsk/gl: allow texture libraries more allocation control
- Date: Thu, 17 Mar 2022 23:55:39 +0000 (UTC)
commit edf9695ff8b7e4124cb79af207fb450de2a694f6
Author: Christian Hergert <chergert redhat com>
Date: Thu Mar 17 16:45:42 2022 -0700
gsk/gl: allow texture libraries more allocation control
Some texture libraries may want to be in control of where things are
allocated and not even use the stbrp_pack_rects() implementation. This is
a first step at abstracting those so that we can potentially even abstract
those into an allocator structure.
With this in place, the glyph library can control it's use of a 1x1 pixel
for line drawing from within the subclass without causing extraneous
allocations in unrelated atlases.
gsk/gl/gskglglyphlibrary.c | 49 ++++++++++++
gsk/gl/gskgltexturelibrary.c | 148 +++++++++++++++++-------------------
gsk/gl/gskgltexturelibraryprivate.h | 19 ++++-
3 files changed, 135 insertions(+), 81 deletions(-)
---
diff --git a/gsk/gl/gskglglyphlibrary.c b/gsk/gl/gskglglyphlibrary.c
index ee13198921..5afebb0577 100644
--- a/gsk/gl/gskglglyphlibrary.c
+++ b/gsk/gl/gskglglyphlibrary.c
@@ -93,6 +93,54 @@ gsk_gl_glyph_library_clear_cache (GskGLTextureLibrary *library)
memset (self->front, 0, sizeof self->front);
}
+static void
+gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *library,
+ GskGLTextureAtlas *atlas)
+{
+ gboolean packed G_GNUC_UNUSED;
+ int x, y;
+ guint gl_format;
+ guint gl_type;
+ guint8 pixel_data[4 * 3 * 3];
+
+ g_assert (GSK_IS_GL_GLYPH_LIBRARY (library));
+ g_assert (atlas != NULL);
+
+ /* Insert a single pixel at 0,0 for use in coloring */
+
+ gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
+ "Initializing Glyph Atlas");
+
+ packed = GSK_GL_TEXTURE_LIBRARY_GET_CLASS (library)->allocate (library, atlas, 3, 3, &x, &y);
+ g_assert (packed);
+ g_assert (x == 0 && y == 0);
+
+ memset (pixel_data, 255, sizeof pixel_data);
+
+ if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
+ {
+ gl_format = GL_RGBA;
+ gl_type = GL_UNSIGNED_BYTE;
+ }
+ else
+ {
+ gl_format = GL_BGRA;
+ gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
+
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ 0, 0,
+ 3, 3,
+ gl_format, gl_type,
+ pixel_data);
+
+ gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
+
+ library->driver->command_queue->n_uploads++;
+}
+
static void
gsk_gl_glyph_library_finalize (GObject *object)
{
@@ -112,6 +160,7 @@ gsk_gl_glyph_library_class_init (GskGLGlyphLibraryClass *klass)
object_class->finalize = gsk_gl_glyph_library_finalize;
library_class->clear_cache = gsk_gl_glyph_library_clear_cache;
+ library_class->init_atlas = gsk_gl_glyph_library_init_atlas;
}
static void
diff --git a/gsk/gl/gskgltexturelibrary.c b/gsk/gl/gskgltexturelibrary.c
index da99ea9500..fd5f172923 100644
--- a/gsk/gl/gskgltexturelibrary.c
+++ b/gsk/gl/gskgltexturelibrary.c
@@ -41,6 +41,53 @@ enum {
static GParamSpec *properties [N_PROPS];
+static inline gboolean
+gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self,
+ int width,
+ int height,
+ int *out_x,
+ int *out_y)
+{
+ stbrp_rect rect;
+
+ rect.w = width;
+ rect.h = height;
+
+ stbrp_pack_rects (&self->context, &rect, 1);
+
+ if (rect.was_packed)
+ {
+ *out_x = rect.x;
+ *out_y = rect.y;
+ }
+
+ return rect.was_packed;
+}
+
+static void
+gsk_gl_texture_library_real_init_atlas (GskGLTextureLibrary *self,
+ GskGLTextureAtlas *atlas)
+{
+}
+
+static gboolean
+gsk_gl_texture_library_real_allocate (GskGLTextureLibrary *self,
+ GskGLTextureAtlas *atlas,
+ int width,
+ int height,
+ int *out_x,
+ int *out_y)
+{
+ g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
+ g_assert (atlas != NULL);
+ g_assert (width > 0);
+ g_assert (height > 0);
+ g_assert (out_x != NULL);
+ g_assert (out_y != NULL);
+
+ return gsk_gl_texture_atlas_pack (atlas, width, height, out_x, out_y);
+}
+
static void
gsk_gl_texture_library_constructed (GObject *object)
{
@@ -107,6 +154,9 @@ gsk_gl_texture_library_class_init (GskGLTextureLibraryClass *klass)
object_class->get_property = gsk_gl_texture_library_get_property;
object_class->set_property = gsk_gl_texture_library_set_property;
+ klass->init_atlas = gsk_gl_texture_library_real_init_atlas;
+ klass->allocate = gsk_gl_texture_library_real_allocate;
+
properties [PROP_DRIVER] =
g_param_spec_object ("driver",
"Driver",
@@ -247,90 +297,33 @@ gsk_gl_texture_library_pack_one (GskGLTextureLibrary *self,
return texture;
}
-static inline gboolean
-gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self,
- int width,
- int height,
- int *out_x,
- int *out_y)
-{
- stbrp_rect rect;
-
- rect.w = width;
- rect.h = height;
-
- stbrp_pack_rects (&self->context, &rect, 1);
-
- if (rect.was_packed)
- {
- *out_x = rect.x;
- *out_y = rect.y;
- }
-
- return rect.was_packed;
-}
-
static void
-gsk_gl_texture_atlas_initialize (GskGLDriver *driver,
- GskGLTextureAtlas *atlas)
+gsk_gl_texture_atlases_pack (GskGLTextureLibrary *self,
+ int width,
+ int height,
+ GskGLTextureAtlas **out_atlas,
+ int *out_x,
+ int *out_y)
{
- /* Insert a single pixel at 0,0 for use in coloring */
-
- gboolean packed G_GNUC_UNUSED;
+ GskGLTextureAtlas *atlas = NULL;
+ GskGLTextureLibraryClass *klass;
+ GskGLDriver *driver;
int x, y;
- guint gl_format;
- guint gl_type;
- guint8 pixel_data[4 * 3 * 3];
-
- gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
- "Initializing Atlas");
-
- packed = gsk_gl_texture_atlas_pack (atlas, 3, 3, &x, &y);
- g_assert (packed);
- g_assert (x == 0 && y == 0);
-
- memset (pixel_data, 255, sizeof pixel_data);
-
- if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
- {
- gl_format = GL_RGBA;
- gl_type = GL_UNSIGNED_BYTE;
- }
- else
- {
- gl_format = GL_BGRA;
- gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
- }
- glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
-
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- 0, 0,
- 3, 3,
- gl_format, gl_type,
- pixel_data);
-
- gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
-
- driver->command_queue->n_uploads++;
-}
+ g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
+ g_assert (GSK_IS_GL_DRIVER (self->driver));
+ g_assert (out_atlas != NULL);
+ g_assert (out_x != NULL);
+ g_assert (out_y != NULL);
-static void
-gsk_gl_texture_atlases_pack (GskGLDriver *driver,
- int width,
- int height,
- GskGLTextureAtlas **out_atlas,
- int *out_x,
- int *out_y)
-{
- GskGLTextureAtlas *atlas = NULL;
- int x, y;
+ driver = self->driver;
+ klass = GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self);
for (guint i = 0; i < driver->atlases->len; i++)
{
atlas = g_ptr_array_index (driver->atlases, i);
- if (gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
+ if (klass->allocate (self, atlas, width, height, &x, &y))
break;
atlas = NULL;
@@ -341,10 +334,11 @@ gsk_gl_texture_atlases_pack (GskGLDriver *driver,
/* No atlas has enough space, so create a new one... */
atlas = gsk_gl_driver_create_atlas (driver, self->atlas_width, self->atlas_height);
- gsk_gl_texture_atlas_initialize (driver, atlas);
+ /* Allow subclass to initialize the atlas */
+ GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->init_atlas (self, atlas);
/* Pack it onto that one, which surely has enough space... */
- if (!gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
+ if (!klass->allocate (self, atlas, width, height, &x, &y))
g_assert_not_reached ();
}
@@ -400,7 +394,7 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
int packed_x;
int packed_y;
- gsk_gl_texture_atlases_pack (self->driver,
+ gsk_gl_texture_atlases_pack (self,
padding + width + padding,
padding + height + padding,
&atlas,
diff --git a/gsk/gl/gskgltexturelibraryprivate.h b/gsk/gl/gskgltexturelibraryprivate.h
index 26a35bd4af..8fd1d6d11a 100644
--- a/gsk/gl/gskgltexturelibraryprivate.h
+++ b/gsk/gl/gskgltexturelibraryprivate.h
@@ -50,6 +50,9 @@ typedef struct _GskGLTextureAtlas
*/
int unused_pixels;
+ /* Used by library subclasses */
+ int cursor_x;
+ int cursor_y;
} GskGLTextureAtlas;
typedef struct _GskGLTextureAtlasEntry
@@ -101,10 +104,18 @@ typedef struct _GskGLTextureLibraryClass
{
GObjectClass parent_class;
- void (*begin_frame) (GskGLTextureLibrary *library,
- gint64 frame_id,
- GPtrArray *removed_atlases);
- void (*clear_cache) (GskGLTextureLibrary *library);
+ void (*begin_frame) (GskGLTextureLibrary *library,
+ gint64 frame_id,
+ GPtrArray *removed_atlases);
+ void (*clear_cache) (GskGLTextureLibrary *library);
+ void (*init_atlas) (GskGLTextureLibrary *library,
+ GskGLTextureAtlas *atlas);
+ gboolean (*allocate) (GskGLTextureLibrary *library,
+ GskGLTextureAtlas *atlas,
+ int width,
+ int height,
+ int *packed_x,
+ int *packed_y);
} GskGLTextureLibraryClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GskGLTextureLibrary, g_object_unref)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]