From 79fad9f221b7d730729f86a6ddcbc5bca8f554db Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 18 Mar 2022 00:59:57 -0400 Subject: [PATCH 01/11] gtk-demo: Don't hardcode a title font We want a large font size, but we don't have to hardcode Sans. --- demos/gtk-demo/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/gtk-demo/main.c b/demos/gtk-demo/main.c index a31ce36790..a7ea646244 100644 --- a/demos/gtk-demo/main.c +++ b/demos/gtk-demo/main.c @@ -512,7 +512,7 @@ load_file (const char *demoname, info_buffer = gtk_text_buffer_new (NULL); gtk_text_buffer_create_tag (info_buffer, "title", - "font", "Sans 18", + "size", 18 * 1024, "pixels-below-lines", 10, NULL); From 9dbd137ec8f0aab41b6cd1f55fe8d4d8f68712d8 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 15 Mar 2022 15:52:44 -0700 Subject: [PATCH 02/11] gsk/gl: make max-frame-age configurable This is nice for some texture libraries that we might want to keep around for longer than say 60 frames such as a glyph cache. --- gsk/gl/gskgltexturelibrary.c | 5 +++-- gsk/gl/gskgltexturelibraryprivate.h | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gsk/gl/gskgltexturelibrary.c b/gsk/gl/gskgltexturelibrary.c index 3d32c95945..414190ea7d 100644 --- a/gsk/gl/gskgltexturelibrary.c +++ b/gsk/gl/gskgltexturelibrary.c @@ -27,7 +27,7 @@ #include "gskgldriverprivate.h" #include "gskgltexturelibraryprivate.h" -#define MAX_FRAME_AGE 60 +#define DEFAULT_MAX_FRAME_AGE 60 G_DEFINE_ABSTRACT_TYPE (GskGLTextureLibrary, gsk_gl_texture_library, G_TYPE_OBJECT) @@ -118,6 +118,7 @@ gsk_gl_texture_library_class_init (GskGLTextureLibraryClass *klass) static void gsk_gl_texture_library_init (GskGLTextureLibrary *self) { + self->max_frame_age = DEFAULT_MAX_FRAME_AGE; } void @@ -176,7 +177,7 @@ gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, G_OBJECT_TYPE_NAME (self), dropped)); } - if (frame_id % MAX_FRAME_AGE == 0) + if (frame_id % self->max_frame_age == 0) { GskGLTextureAtlasEntry *entry; int atlased = 0; diff --git a/gsk/gl/gskgltexturelibraryprivate.h b/gsk/gl/gskgltexturelibraryprivate.h index a784449889..bb1db12172 100644 --- a/gsk/gl/gskgltexturelibraryprivate.h +++ b/gsk/gl/gskgltexturelibraryprivate.h @@ -89,10 +89,11 @@ typedef struct _GskGLTextureAtlasEntry typedef struct _GskGLTextureLibrary { - GObject parent_instance; + GObject parent_instance; GskGLDriver *driver; - GHashTable *hash_table; - guint max_entry_size; + GHashTable *hash_table; + guint max_entry_size; + guint max_frame_age; } GskGLTextureLibrary; typedef struct _GskGLTextureLibraryClass From 7062411bad6e04311d0486d747ebba58643986e3 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 15 Mar 2022 15:53:47 -0700 Subject: [PATCH 03/11] gsk/gl: ignore max_entry_size when zero If the max_entry_size is zero, then assume we can add anything to the atlas. This allows for situations where we might be uploading an arc list to the atlas instead of pixel data for GPU font rendering. --- gsk/gl/gskgltexturelibrary.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gsk/gl/gskgltexturelibrary.c b/gsk/gl/gskgltexturelibrary.c index 414190ea7d..fadec60a0c 100644 --- a/gsk/gl/gskgltexturelibrary.c +++ b/gsk/gl/gskgltexturelibrary.c @@ -381,7 +381,9 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self, *out_packed_x = 0; *out_packed_y = 0; } - else if (width <= self->max_entry_size && height <= self->max_entry_size) + else if (self->max_entry_size == 0 || + (width <= self->max_entry_size && + height <= self->max_entry_size)) { int packed_x; int packed_y; From a66a0dde812a4544f3ef2579a6639d699b48cf9e Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 15 Mar 2022 15:55:30 -0700 Subject: [PATCH 04/11] gsk/gl: only clear glyph cache durign reclaimation We don't need to clear the front cache on every frame as we can clear it specifically when we do reclaimation to avoid unnecessary memset() calls. --- gsk/gl/gskglglyphlibrary.c | 8 ++++---- gsk/gl/gskgltexturelibrary.c | 8 ++++++++ gsk/gl/gskgltexturelibraryprivate.h | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/gsk/gl/gskglglyphlibrary.c b/gsk/gl/gskglglyphlibrary.c index b749384674..ee13198921 100644 --- a/gsk/gl/gskglglyphlibrary.c +++ b/gsk/gl/gskglglyphlibrary.c @@ -84,12 +84,12 @@ gsk_gl_glyph_value_free (gpointer data) } static void -gsk_gl_glyph_library_begin_frame (GskGLTextureLibrary *library, - gint64 frame_id, - GPtrArray *removed_atlases) +gsk_gl_glyph_library_clear_cache (GskGLTextureLibrary *library) { GskGLGlyphLibrary *self = (GskGLGlyphLibrary *)library; + g_assert (GSK_IS_GL_GLYPH_LIBRARY (self)); + memset (self->front, 0, sizeof self->front); } @@ -111,7 +111,7 @@ gsk_gl_glyph_library_class_init (GskGLGlyphLibraryClass *klass) object_class->finalize = gsk_gl_glyph_library_finalize; - library_class->begin_frame = gsk_gl_glyph_library_begin_frame; + library_class->clear_cache = gsk_gl_glyph_library_clear_cache; } static void diff --git a/gsk/gl/gskgltexturelibrary.c b/gsk/gl/gskgltexturelibrary.c index fadec60a0c..b0694e7afb 100644 --- a/gsk/gl/gskgltexturelibrary.c +++ b/gsk/gl/gskgltexturelibrary.c @@ -141,6 +141,7 @@ gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, GPtrArray *removed_atlases) { GHashTableIter iter; + gboolean drop_caches = FALSE; g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self)); @@ -175,6 +176,8 @@ gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, if (dropped > 0) g_message ("%s: Dropped %d items", G_OBJECT_TYPE_NAME (self), dropped)); + + drop_caches |= dropped > 0; } if (frame_id % self->max_frame_age == 0) @@ -208,7 +211,12 @@ gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, g_hash_table_size (self->hash_table), atlased, g_hash_table_size (self->hash_table) - atlased)); + + drop_caches |= dropped > 0; } + + if (drop_caches && GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache) + GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache (self); } static GskGLTexture * diff --git a/gsk/gl/gskgltexturelibraryprivate.h b/gsk/gl/gskgltexturelibraryprivate.h index bb1db12172..39276ff69d 100644 --- a/gsk/gl/gskgltexturelibraryprivate.h +++ b/gsk/gl/gskgltexturelibraryprivate.h @@ -103,6 +103,7 @@ typedef struct _GskGLTextureLibraryClass void (*begin_frame) (GskGLTextureLibrary *library, gint64 frame_id, GPtrArray *removed_atlases); + void (*clear_cache) (GskGLTextureLibrary *library); } GskGLTextureLibraryClass; G_DEFINE_AUTOPTR_CLEANUP_FUNC (GskGLTextureLibrary, g_object_unref) From 2efc1729e20c014ebcd0184da148dbbf999731e4 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 14 Mar 2022 16:22:52 -0700 Subject: [PATCH 05/11] gsk/gl: check for format as well This could potentially happen if a uniform had never been set. --- gsk/gl/gskglcommandqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c index b7640edf87..4d7ef4b3d3 100644 --- a/gsk/gl/gskglcommandqueue.c +++ b/gsk/gl/gskglcommandqueue.c @@ -282,7 +282,7 @@ snapshot_uniforms (GskGLUniformState *state, { const GskGLUniformMapping *mapping = &program->mappings[i]; - if (!mapping->info.initial && mapping->location > -1) + if (!mapping->info.initial && mapping->info.format && mapping->location > -1) { uniform[count].location = mapping->location; uniform[count].info = mapping->info; From 1b9da2bb17136d74a11bde95f386ae218249a5ef Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 17 Mar 2022 16:43:58 -0700 Subject: [PATCH 06/11] gsk/gl: allow configuring atlas size --- gsk/gl/gskgldriver.c | 11 +++++++---- gsk/gl/gskgldriverprivate.h | 4 +++- gsk/gl/gskgltexturelibrary.c | 21 +++++++++++++-------- gsk/gl/gskgltexturelibraryprivate.h | 3 ++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 327dea93ff..ddd5bed5e9 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -44,7 +44,6 @@ #include #include -#define ATLAS_SIZE 512 #define MAX_OLD_RATIO 0.5 G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT) @@ -170,15 +169,19 @@ gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas) } GskGLTextureAtlas * -gsk_gl_driver_create_atlas (GskGLDriver *self) +gsk_gl_driver_create_atlas (GskGLDriver *self, + guint width, + guint height) { GskGLTextureAtlas *atlas; g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); atlas = g_slice_new0 (GskGLTextureAtlas); - atlas->width = ATLAS_SIZE; - atlas->height = ATLAS_SIZE; + atlas->width = width; + atlas->height = height; /* TODO: We might want to change the strategy about the amount of * nodes here? stb_rect_pack.h says width is optimal. */ atlas->nodes = g_malloc0_n (atlas->width, sizeof (struct stbrp_node)); diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h index 4500962ed8..37c4cbb77a 100644 --- a/gsk/gl/gskgldriverprivate.h +++ b/gsk/gl/gskgldriverprivate.h @@ -184,7 +184,9 @@ void gsk_gl_driver_add_texture_slices (GskGLDriver *s GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *self, GskGLShader *shader, GError **error); -GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self); +GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self, + guint width, + guint height); #ifdef G_ENABLE_DEBUG void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self, diff --git a/gsk/gl/gskgltexturelibrary.c b/gsk/gl/gskgltexturelibrary.c index b0694e7afb..8951f78829 100644 --- a/gsk/gl/gskgltexturelibrary.c +++ b/gsk/gl/gskgltexturelibrary.c @@ -28,6 +28,8 @@ #include "gskgltexturelibraryprivate.h" #define DEFAULT_MAX_FRAME_AGE 60 +#define DEFAULT_ATLAS_WIDTH 512 +#define DEFAULT_ATLAS_HEIGHT 512 G_DEFINE_ABSTRACT_TYPE (GskGLTextureLibrary, gsk_gl_texture_library, G_TYPE_OBJECT) @@ -119,6 +121,8 @@ static void gsk_gl_texture_library_init (GskGLTextureLibrary *self) { self->max_frame_age = DEFAULT_MAX_FRAME_AGE; + self->atlas_width = DEFAULT_ATLAS_WIDTH; + self->atlas_height = DEFAULT_ATLAS_HEIGHT; } void @@ -312,13 +316,14 @@ gsk_gl_texture_atlas_initialize (GskGLDriver *driver, } static void -gsk_gl_texture_atlases_pack (GskGLDriver *driver, - int width, - int height, - GskGLTextureAtlas **out_atlas, - int *out_x, - int *out_y) +gsk_gl_texture_atlases_pack (GskGLTextureLibrary *self, + int width, + int height, + GskGLTextureAtlas **out_atlas, + int *out_x, + int *out_y) { + GskGLDriver *driver = self->driver; GskGLTextureAtlas *atlas = NULL; int x, y; @@ -335,7 +340,7 @@ gsk_gl_texture_atlases_pack (GskGLDriver *driver, if (atlas == NULL) { /* No atlas has enough space, so create a new one... */ - atlas = gsk_gl_driver_create_atlas (driver); + atlas = gsk_gl_driver_create_atlas (driver, self->atlas_width, self->atlas_height); gsk_gl_texture_atlas_initialize (driver, atlas); @@ -396,7 +401,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 39276ff69d..26a35bd4af 100644 --- a/gsk/gl/gskgltexturelibraryprivate.h +++ b/gsk/gl/gskgltexturelibraryprivate.h @@ -50,7 +50,6 @@ typedef struct _GskGLTextureAtlas */ int unused_pixels; - void *user_data; } GskGLTextureAtlas; typedef struct _GskGLTextureAtlasEntry @@ -94,6 +93,8 @@ typedef struct _GskGLTextureLibrary GHashTable *hash_table; guint max_entry_size; guint max_frame_age; + guint atlas_width; + guint atlas_height; } GskGLTextureLibrary; typedef struct _GskGLTextureLibraryClass From 9d56f44cdf54fc36c902db56231ce3c41c1b4b84 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 17 Mar 2022 16:48:54 -0700 Subject: [PATCH 07/11] gsk/gl: rename glyphs to glyphs_library This naming style is less likely to collide with shader naming and makes it clear where it is consumed what it is. --- gsk/gl/gskgldriver.c | 14 +++++++------- gsk/gl/gskgldriverprivate.h | 2 +- gsk/gl/gskglrenderjob.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index ddd5bed5e9..5154aeabb2 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -292,7 +292,7 @@ gsk_gl_driver_dispose (GObject *object) g_assert (!self->texture_id_to_key || g_hash_table_size (self->texture_id_to_key) == 0); g_assert (!self->key_to_texture_id|| g_hash_table_size (self->key_to_texture_id) == 0); - g_clear_object (&self->glyphs); + g_clear_object (&self->glyphs_library); g_clear_object (&self->icons); g_clear_object (&self->shadows); @@ -459,7 +459,7 @@ gsk_gl_driver_new (GskGLCommandQueue *command_queue, return NULL; } - self->glyphs = gsk_gl_glyph_library_new (self); + self->glyphs_library = gsk_gl_glyph_library_new (self); self->icons = gsk_gl_icon_library_new (self); self->shadows = gsk_gl_shadow_library_new (self); @@ -588,11 +588,11 @@ gsk_gl_driver_begin_frame (GskGLDriver *self, /* Mark unused pixel regions of the atlases */ gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->icons), - self->current_frame_id, - removed); - gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs), - self->current_frame_id, - removed); + self->current_frame_id, + removed); + gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs_library), + self->current_frame_id, + removed); /* Cleanup old shadows */ gsk_gl_shadow_library_begin_frame (self->shadows); diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h index 37c4cbb77a..b1c100f6f7 100644 --- a/gsk/gl/gskgldriverprivate.h +++ b/gsk/gl/gskgldriverprivate.h @@ -100,7 +100,7 @@ struct _GskGLDriver GskGLCommandQueue *shared_command_queue; GskGLCommandQueue *command_queue; - GskGLGlyphLibrary *glyphs; + GskGLGlyphLibrary *glyphs_library; GskGLIconLibrary *icons; GskGLShadowLibrary *shadows; diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c index afefe7a018..3371bab826 100644 --- a/gsk/gl/gskglrenderjob.c +++ b/gsk/gl/gskglrenderjob.c @@ -2996,7 +2996,7 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job, guint num_glyphs = gsk_text_node_get_num_glyphs (node); float x = offset->x + job->offset_x; float y = offset->y + job->offset_y; - GskGLGlyphLibrary *library = job->driver->glyphs; + GskGLGlyphLibrary *library = job->driver->glyphs_library; GskGLCommandBatch *batch; int x_position = 0; GskGLGlyphKey lookup; From 9defc7fc6473da76112d21df6586d35d80d4bb4c Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 17 Mar 2022 16:50:51 -0700 Subject: [PATCH 08/11] gsk/gl: add more control over shader generation This allows the gskglprograms.defs a bit more control over how a shader will get generated and if it needs to combine sources. Currently, none of the built-in shaders do that, but upcoming shaders which come from external libraries will need the ability to inject additional sources in-between layers. --- gsk/gl/gskgldriver.c | 70 ++++++++++++++++++++++++++++++++++----- gsk/gl/gskglprograms.defs | 32 +++++++++--------- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 5154aeabb2..0980eba0ae 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -229,6 +229,29 @@ gsk_gl_driver_shader_weak_cb (gpointer data, g_hash_table_remove (self->shader_cache, where_object_was); } +G_GNUC_NULL_TERMINATED static inline GBytes * +join_sources (GBytes *first_bytes, + ...) +{ + GByteArray *byte_array = g_byte_array_new (); + GBytes *bytes = first_bytes; + va_list args; + + va_start (args, first_bytes); + while (bytes != NULL) + { + gsize len; + const guint8 *data = g_bytes_get_data (bytes, &len); + if (len > 0) + g_byte_array_append (byte_array, data, len); + g_bytes_unref (bytes); + bytes = va_arg (args, GBytes *); + } + va_end (args); + + return g_byte_array_free_to_bytes (byte_array); +} + static void gsk_gl_driver_dispose (GObject *object) { @@ -238,6 +261,10 @@ gsk_gl_driver_dispose (GObject *object) g_assert (self->in_frame == FALSE); #define GSK_GL_NO_UNIFORMS +#define GSK_GL_SHADER_RESOURCE(name) +#define GSK_GL_SHADER_STRING(str) +#define GSK_GL_SHADER_SINGLE(name) +#define GSK_GL_SHADER_JOINED(kind, ...) #define GSK_GL_ADD_UNIFORM(pos, KEY, name) #define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \ GSK_GL_DELETE_PROGRAM(name); \ @@ -251,6 +278,10 @@ gsk_gl_driver_dispose (GObject *object) } G_STMT_END; # include "gskglprograms.defs" #undef GSK_GL_NO_UNIFORMS +#undef GSK_GL_SHADER_RESOURCE +#undef GSK_GL_SHADER_STRING +#undef GSK_GL_SHADER_SINGLE +#undef GSK_GL_SHADER_JOINED #undef GSK_GL_ADD_UNIFORM #undef GSK_GL_DEFINE_PROGRAM @@ -351,14 +382,14 @@ gsk_gl_driver_load_programs (GskGLDriver *self, /* Setup preambles that are shared by all shaders */ gsk_gl_compiler_set_preamble_from_resource (compiler, - GSK_GL_COMPILER_ALL, - "/org/gtk/libgsk/gl/preamble.glsl"); + GSK_GL_COMPILER_ALL, + "/org/gtk/libgsk/gl/preamble.glsl"); gsk_gl_compiler_set_preamble_from_resource (compiler, - GSK_GL_COMPILER_VERTEX, - "/org/gtk/libgsk/gl/preamble.vs.glsl"); + GSK_GL_COMPILER_VERTEX, + "/org/gtk/libgsk/gl/preamble.vs.glsl"); gsk_gl_compiler_set_preamble_from_resource (compiler, - GSK_GL_COMPILER_FRAGMENT, - "/org/gtk/libgsk/gl/preamble.fs.glsl"); + GSK_GL_COMPILER_FRAGMENT, + "/org/gtk/libgsk/gl/preamble.fs.glsl"); /* Setup attributes that are provided via VBO */ gsk_gl_compiler_bind_attribute (compiler, "aPosition", 0); @@ -368,10 +399,28 @@ gsk_gl_driver_load_programs (GskGLDriver *self, /* Use XMacros to register all of our programs and their uniforms */ #define GSK_GL_NO_UNIFORMS +#define GSK_GL_SHADER_RESOURCE(name) \ + g_bytes_ref(g_resources_lookup_data("/org/gtk/libgsk/gl/" name, 0, NULL)) +#define GSK_GL_SHADER_STRING(str) \ + g_bytes_new_static(str, strlen(str)) +#define GSK_GL_SHADER_SINGLE(bytes) \ + G_STMT_START { \ + GBytes *b = bytes; \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_ALL, b); \ + g_bytes_unref (b); \ + } G_STMT_END; +#define GSK_GL_SHADER_JOINED(kind, ...) \ + G_STMT_START { \ + GBytes *bytes = join_sources(__VA_ARGS__); \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_##kind, bytes); \ + g_bytes_unref (bytes); \ + } G_STMT_END; #define GSK_GL_ADD_UNIFORM(pos, KEY, name) \ gsk_gl_program_add_uniform (program, #name, UNIFORM_##KEY); -#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \ - gsk_gl_compiler_set_source_from_resource (compiler, GSK_GL_COMPILER_ALL, resource); \ +#define GSK_GL_DEFINE_PROGRAM(name, sources, uniforms) \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_VERTEX, NULL); \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_FRAGMENT, NULL); \ + sources \ GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \ GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \ GSK_GL_COMPILE_PROGRAM(name, uniforms, ""); @@ -404,6 +453,11 @@ gsk_gl_driver_load_programs (GskGLDriver *self, #undef GSK_GL_DEFINE_PROGRAM_CLIP #undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_ADD_UNIFORM +#undef GSK_GL_SHADER_SINGLE +#undef GSK_GL_SHADER_JOINED +#undef GSK_GL_SHADER_RESOURCE +#undef GSK_GL_SHADER_STRING +#undef GSK_GL_NO_UNIFORMS ret = TRUE; diff --git a/gsk/gl/gskglprograms.defs b/gsk/gl/gskglprograms.defs index a6d9515a78..1ff99fab89 100644 --- a/gsk/gl/gskglprograms.defs +++ b/gsk/gl/gskglprograms.defs @@ -1,71 +1,71 @@ GSK_GL_DEFINE_PROGRAM (blend, - "/org/gtk/libgsk/gl/blend.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blend.glsl")), GSK_GL_ADD_UNIFORM (1, BLEND_SOURCE2, u_source2) GSK_GL_ADD_UNIFORM (2, BLEND_MODE, u_mode)) GSK_GL_DEFINE_PROGRAM (blit, - "/org/gtk/libgsk/gl/blit.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blit.glsl")), GSK_GL_NO_UNIFORMS) GSK_GL_DEFINE_PROGRAM (blur, - "/org/gtk/libgsk/gl/blur.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blur.glsl")), GSK_GL_ADD_UNIFORM (1, BLUR_RADIUS, u_blur_radius) GSK_GL_ADD_UNIFORM (2, BLUR_SIZE, u_blur_size) GSK_GL_ADD_UNIFORM (3, BLUR_DIR, u_blur_dir)) GSK_GL_DEFINE_PROGRAM (border, - "/org/gtk/libgsk/gl/border.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("border.glsl")), GSK_GL_ADD_UNIFORM (1, BORDER_WIDTHS, u_widths) GSK_GL_ADD_UNIFORM (2, BORDER_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (color, - "/org/gtk/libgsk/gl/color.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("color.glsl")), GSK_GL_NO_UNIFORMS) GSK_GL_DEFINE_PROGRAM (coloring, - "/org/gtk/libgsk/gl/coloring.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("coloring.glsl")), GSK_GL_NO_UNIFORMS) GSK_GL_DEFINE_PROGRAM (color_matrix, - "/org/gtk/libgsk/gl/color_matrix.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("color_matrix.glsl")), GSK_GL_ADD_UNIFORM (1, COLOR_MATRIX_COLOR_MATRIX, u_color_matrix) GSK_GL_ADD_UNIFORM (2, COLOR_MATRIX_COLOR_OFFSET, u_color_offset)) GSK_GL_DEFINE_PROGRAM (conic_gradient, - "/org/gtk/libgsk/gl/conic_gradient.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("conic_gradient.glsl")), GSK_GL_ADD_UNIFORM (1, CONIC_GRADIENT_COLOR_STOPS, u_color_stops) GSK_GL_ADD_UNIFORM (2, CONIC_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops) GSK_GL_ADD_UNIFORM (3, CONIC_GRADIENT_GEOMETRY, u_geometry)) GSK_GL_DEFINE_PROGRAM (cross_fade, - "/org/gtk/libgsk/gl/cross_fade.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("cross_fade.glsl")), GSK_GL_ADD_UNIFORM (1, CROSS_FADE_PROGRESS, u_progress) GSK_GL_ADD_UNIFORM (2, CROSS_FADE_SOURCE2, u_source2)) GSK_GL_DEFINE_PROGRAM (filled_border, - "/org/gtk/libgsk/gl/filled_border.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("filled_border.glsl")), GSK_GL_ADD_UNIFORM (1, FILLED_BORDER_WIDTHS, u_widths) GSK_GL_ADD_UNIFORM (2, FILLED_BORDER_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (inset_shadow, - "/org/gtk/libgsk/gl/inset_shadow.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("inset_shadow.glsl")), GSK_GL_ADD_UNIFORM (1, INSET_SHADOW_SPREAD, u_spread) GSK_GL_ADD_UNIFORM (2, INSET_SHADOW_OFFSET, u_offset) GSK_GL_ADD_UNIFORM (3, INSET_SHADOW_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (linear_gradient, - "/org/gtk/libgsk/gl/linear_gradient.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("linear_gradient.glsl")), GSK_GL_ADD_UNIFORM (1, LINEAR_GRADIENT_COLOR_STOPS, u_color_stops) GSK_GL_ADD_UNIFORM (2, LINEAR_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops) GSK_GL_ADD_UNIFORM (3, LINEAR_GRADIENT_POINTS, u_points) GSK_GL_ADD_UNIFORM (4, LINEAR_GRADIENT_REPEAT, u_repeat)) GSK_GL_DEFINE_PROGRAM (outset_shadow, - "/org/gtk/libgsk/gl/outset_shadow.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("outset_shadow.glsl")), GSK_GL_ADD_UNIFORM (1, OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (radial_gradient, - "/org/gtk/libgsk/gl/radial_gradient.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("radial_gradient.glsl")), GSK_GL_ADD_UNIFORM (1, RADIAL_GRADIENT_COLOR_STOPS, u_color_stops) GSK_GL_ADD_UNIFORM (2, RADIAL_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops) GSK_GL_ADD_UNIFORM (3, RADIAL_GRADIENT_REPEAT, u_repeat) @@ -73,12 +73,12 @@ GSK_GL_DEFINE_PROGRAM (radial_gradient, GSK_GL_ADD_UNIFORM (5, RADIAL_GRADIENT_GEOMETRY, u_geometry)) GSK_GL_DEFINE_PROGRAM (repeat, - "/org/gtk/libgsk/gl/repeat.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("repeat.glsl")), GSK_GL_ADD_UNIFORM (1, REPEAT_CHILD_BOUNDS, u_child_bounds) GSK_GL_ADD_UNIFORM (2, REPEAT_TEXTURE_RECT, u_texture_rect)) GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow, - "/org/gtk/libgsk/gl/unblurred_outset_shadow.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("unblurred_outset_shadow.glsl")), GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread) GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset) GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect)) From 6b23fe3aa7efb0b58afa846ae7217df4ac24cb9d Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 18 Mar 2022 12:48:43 -0700 Subject: [PATCH 09/11] gsk/gl: pin atlases to single texture library This removes the sharing of atlases across various texture libraries. Doing so is necessary so that atlases can have different semantics for how they allocate within the texture as well as potentially allowing for different formats of texture data. For example, in the future we might store non-pixel data in the textures such as Glyphy or even keep glyphs with color content separate from glyphs which do not and can use alpha channel only. --- gsk/gl/gskgltexturelibrary.c | 24 +++++++++++++++--------- gsk/gl/gskgltexturelibraryprivate.h | 1 + 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/gsk/gl/gskgltexturelibrary.c b/gsk/gl/gskgltexturelibrary.c index 8951f78829..649f422b0d 100644 --- a/gsk/gl/gskgltexturelibrary.c +++ b/gsk/gl/gskgltexturelibrary.c @@ -54,6 +54,7 @@ gsk_gl_texture_library_dispose (GObject *object) { GskGLTextureLibrary *self = (GskGLTextureLibrary *)object; + g_clear_pointer (&self->atlases, g_ptr_array_unref); g_clear_object (&self->driver); G_OBJECT_CLASS (gsk_gl_texture_library_parent_class)->dispose (object); @@ -123,6 +124,7 @@ gsk_gl_texture_library_init (GskGLTextureLibrary *self) self->max_frame_age = DEFAULT_MAX_FRAME_AGE; self->atlas_width = DEFAULT_ATLAS_WIDTH; self->atlas_height = DEFAULT_ATLAS_HEIGHT; + self->atlases = g_ptr_array_new (); } void @@ -157,6 +159,10 @@ gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, GskGLTextureAtlasEntry *entry; guint dropped = 0; + /* Remove cached copy of purged atlases */ + for (guint i = 0; i < removed_atlases->len; i++) + g_ptr_array_remove (self->atlases, g_ptr_array_index (removed_atlases, i)); + g_hash_table_iter_init (&iter, self->hash_table); while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry)) { @@ -271,8 +277,8 @@ gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self, } static void -gsk_gl_texture_atlas_initialize (GskGLDriver *driver, - GskGLTextureAtlas *atlas) +gsk_gl_texture_library_init_atlas (GskGLTextureLibrary *self, + GskGLTextureAtlas *atlas) { /* Insert a single pixel at 0,0 for use in coloring */ @@ -282,6 +288,8 @@ gsk_gl_texture_atlas_initialize (GskGLDriver *driver, guint gl_type; guint8 pixel_data[4 * 3 * 3]; + g_ptr_array_add (self->atlases, atlas); + gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (), "Initializing Atlas"); @@ -312,7 +320,7 @@ gsk_gl_texture_atlas_initialize (GskGLDriver *driver, gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ()); - driver->command_queue->n_uploads++; + self->driver->command_queue->n_uploads++; } static void @@ -323,13 +331,12 @@ gsk_gl_texture_atlases_pack (GskGLTextureLibrary *self, int *out_x, int *out_y) { - GskGLDriver *driver = self->driver; GskGLTextureAtlas *atlas = NULL; int x, y; - for (guint i = 0; i < driver->atlases->len; i++) + for (guint i = 0; i < self->atlases->len; i++) { - atlas = g_ptr_array_index (driver->atlases, i); + atlas = g_ptr_array_index (self->atlases, i); if (gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y)) break; @@ -340,9 +347,8 @@ gsk_gl_texture_atlases_pack (GskGLTextureLibrary *self, if (atlas == NULL) { /* 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); + atlas = gsk_gl_driver_create_atlas (self->driver, self->atlas_width, self->atlas_height); + gsk_gl_texture_library_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)) diff --git a/gsk/gl/gskgltexturelibraryprivate.h b/gsk/gl/gskgltexturelibraryprivate.h index 26a35bd4af..167b00923b 100644 --- a/gsk/gl/gskgltexturelibraryprivate.h +++ b/gsk/gl/gskgltexturelibraryprivate.h @@ -90,6 +90,7 @@ typedef struct _GskGLTextureLibrary { GObject parent_instance; GskGLDriver *driver; + GPtrArray *atlases; GHashTable *hash_table; guint max_entry_size; guint max_frame_age; From c64836e1c99e830007d0e646314beb08aef00deb Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 18 Mar 2022 14:51:41 -0700 Subject: [PATCH 10/11] gsk/gl: make texture libraries more autonomous This moves a lot of the texture atlas control out of the driver and into the various texture libraries through their base GskGLTextureLibrary class. Additionally, this gives more control to libraries on allocating which can be necessary for some tooling such as future Glyphy integration. As part of this, the 1x1 pixel initialization is moved to the Glyph library which is the only place where it is actually needed. The compact vfunc now is responsible for compaction and it allows for us to iterate the atlas hashtable a single time instead of twice as we were doing previously. The init_atlas vfunc is used to do per-library initialization such as adding a 1x1 pixel in the Glyph cache used for coloring lines. The allocate vfunc purely allocates but does no upload. This can be useful for situations where a library wants to reuse the allocator from the base class but does not want to actually insert a key/value entry. The glyph library uses this for it's 1x1 pixel. In the future, we will also likely want to decouple the rectangle packing implementation from the atlas structure, or at least move it into a union so that we do not allocate unused memory for alternate allocators. --- gsk/gl/gskgldriver.c | 111 +------ gsk/gl/gskgldriverprivate.h | 5 - gsk/gl/gskglglyphlibrary.c | 50 +++ gsk/gl/gskgltexturelibrary.c | 466 ++++++++++++++++++---------- gsk/gl/gskgltexturelibraryprivate.h | 64 ++-- 5 files changed, 407 insertions(+), 289 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 0980eba0ae..68311b7238 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -44,8 +44,6 @@ #include #include -#define MAX_OLD_RATIO 0.5 - G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT) static guint @@ -155,54 +153,6 @@ gsk_gl_driver_collect_unused_textures (GskGLDriver *self, return collected; } -static void -gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas) -{ - if (atlas->texture_id != 0) - { - glDeleteTextures (1, &atlas->texture_id); - atlas->texture_id = 0; - } - - g_clear_pointer (&atlas->nodes, g_free); - g_slice_free (GskGLTextureAtlas, atlas); -} - -GskGLTextureAtlas * -gsk_gl_driver_create_atlas (GskGLDriver *self, - guint width, - guint height) -{ - GskGLTextureAtlas *atlas; - - g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL); - g_return_val_if_fail (width > 0, NULL); - g_return_val_if_fail (height > 0, NULL); - - atlas = g_slice_new0 (GskGLTextureAtlas); - atlas->width = width; - atlas->height = height; - /* TODO: We might want to change the strategy about the amount of - * nodes here? stb_rect_pack.h says width is optimal. */ - atlas->nodes = g_malloc0_n (atlas->width, sizeof (struct stbrp_node)); - stbrp_init_target (&atlas->context, atlas->width, atlas->height, atlas->nodes, atlas->width); - atlas->texture_id = gsk_gl_command_queue_create_texture (self->command_queue, - atlas->width, - atlas->height, - GL_RGBA8, - GL_LINEAR, - GL_LINEAR); - - gdk_gl_context_label_object_printf (gdk_gl_context_get_current (), - GL_TEXTURE, atlas->texture_id, - "Texture atlas %d", - atlas->texture_id); - - g_ptr_array_add (self->atlases, atlas); - - return atlas; -} - static void remove_program (gpointer data) { @@ -327,7 +277,6 @@ gsk_gl_driver_dispose (GObject *object) g_clear_object (&self->icons); g_clear_object (&self->shadows); - g_clear_pointer (&self->atlases, g_ptr_array_unref); g_clear_pointer (&self->autorelease_framebuffers, g_array_unref); g_clear_pointer (&self->key_to_texture_id, g_hash_table_unref); g_clear_pointer (&self->textures, g_hash_table_unref); @@ -364,7 +313,6 @@ gsk_gl_driver_init (GskGLDriver *self) self->shader_cache = g_hash_table_new_full (NULL, NULL, NULL, remove_program); self->texture_pool = g_array_new (FALSE, FALSE, sizeof (guint)); self->render_targets = g_ptr_array_new (); - self->atlases = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free); } static gboolean @@ -575,37 +523,6 @@ failure: return g_steal_pointer (&driver); } -static GPtrArray * -gsk_gl_driver_compact_atlases (GskGLDriver *self) -{ - GPtrArray *removed = NULL; - - g_assert (GSK_IS_GL_DRIVER (self)); - - for (guint i = self->atlases->len; i > 0; i--) - { - GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i - 1); - - if (gsk_gl_texture_atlas_get_unused_ratio (atlas) > MAX_OLD_RATIO) - { - GSK_NOTE (GLYPH_CACHE, - g_message ("Dropping atlas %d (%g.2%% old)", i, - 100.0 * gsk_gl_texture_atlas_get_unused_ratio (atlas))); - if (removed == NULL) - removed = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free); - g_ptr_array_add (removed, g_ptr_array_steal_index (self->atlases, i - 1)); - } - } - - GSK_NOTE (GLYPH_CACHE, { - static guint timestamp; - if (timestamp++ % 60 == 0) - g_message ("%d atlases", self->atlases->len); - }); - - return removed; -} - /** * gsk_gl_driver_begin_frame: * @self: a `GskGLDriver` @@ -622,7 +539,6 @@ gsk_gl_driver_begin_frame (GskGLDriver *self, GskGLCommandQueue *command_queue) { gint64 last_frame_id; - GPtrArray *removed; g_return_if_fail (GSK_IS_GL_DRIVER (self)); g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (command_queue)); @@ -637,16 +553,11 @@ gsk_gl_driver_begin_frame (GskGLDriver *self, gsk_gl_command_queue_begin_frame (self->command_queue); - /* Compact atlases with too many freed pixels */ - removed = gsk_gl_driver_compact_atlases (self); - /* Mark unused pixel regions of the atlases */ gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->icons), - self->current_frame_id, - removed); + self->current_frame_id); gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs_library), - self->current_frame_id, - removed); + self->current_frame_id); /* Cleanup old shadows */ gsk_gl_shadow_library_begin_frame (self->shadows); @@ -657,9 +568,6 @@ gsk_gl_driver_begin_frame (GskGLDriver *self, * we block on any resources while delivering our frames. */ gsk_gl_driver_collect_unused_textures (self, last_frame_id - 1); - - /* Now free atlas textures */ - g_clear_pointer (&removed, g_ptr_array_unref); } /** @@ -1239,14 +1147,23 @@ void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self, const char *directory) { + GPtrArray *atlases; + g_return_if_fail (GSK_IS_GL_DRIVER (self)); if (directory == NULL) directory = "."; - for (guint i = 0; i < self->atlases->len; i++) +#define copy_atlases(dst, library) \ + g_ptr_array_extend(dst, GSK_GL_TEXTURE_LIBRARY(library)->atlases, NULL, NULL) + atlases = g_ptr_array_new (); + copy_atlases (atlases, self->glyphs_library); + copy_atlases (atlases, self->icons); +#undef copy_atlases + + for (guint i = 0; i < atlases->len; i++) { - GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i); + GskGLTextureAtlas *atlas = g_ptr_array_index (atlases, i); char *filename = g_strdup_printf ("%s%sframe-%d-atlas-%d.png", directory, G_DIR_SEPARATOR_S, @@ -1255,6 +1172,8 @@ gsk_gl_driver_save_atlases_to_png (GskGLDriver *self, write_atlas_to_png (self, atlas, filename); g_free (filename); } + + g_ptr_array_unref (atlases); } #endif diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h index b1c100f6f7..863240fc3e 100644 --- a/gsk/gl/gskgldriverprivate.h +++ b/gsk/gl/gskgldriverprivate.h @@ -109,8 +109,6 @@ struct _GskGLDriver GHashTable *key_to_texture_id; GHashTable *texture_id_to_key; - GPtrArray *atlases; - GHashTable *shader_cache; GArray *autorelease_framebuffers; @@ -184,9 +182,6 @@ void gsk_gl_driver_add_texture_slices (GskGLDriver *s GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *self, GskGLShader *shader, GError **error); -GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self, - guint width, - guint height); #ifdef G_ENABLE_DEBUG void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self, diff --git a/gsk/gl/gskglglyphlibrary.c b/gsk/gl/gskglglyphlibrary.c index ee13198921..58e34bc938 100644 --- a/gsk/gl/gskglglyphlibrary.c +++ b/gsk/gl/gskglglyphlibrary.c @@ -93,6 +93,55 @@ gsk_gl_glyph_library_clear_cache (GskGLTextureLibrary *library) memset (self->front, 0, sizeof self->front); } +static void +gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self, + 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 (self)); + 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 Atlas"); + + packed = gsk_gl_texture_library_allocate (self, 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 ()); + + self->driver->command_queue->n_uploads++; +} + + static void gsk_gl_glyph_library_finalize (GObject *object) { @@ -112,6 +161,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 649f422b0d..3e6463a848 100644 --- a/gsk/gl/gskgltexturelibrary.c +++ b/gsk/gl/gskgltexturelibrary.c @@ -30,6 +30,7 @@ #define DEFAULT_MAX_FRAME_AGE 60 #define DEFAULT_ATLAS_WIDTH 512 #define DEFAULT_ATLAS_HEIGHT 512 +#define MAX_OLD_RATIO 0.5 G_DEFINE_ABSTRACT_TYPE (GskGLTextureLibrary, gsk_gl_texture_library, G_TYPE_OBJECT) @@ -41,6 +42,143 @@ enum { static GParamSpec *properties [N_PROPS]; +static void +gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas) +{ + if (atlas->texture_id != 0) + { + glDeleteTextures (1, &atlas->texture_id); + atlas->texture_id = 0; + } + + g_clear_pointer (&atlas->nodes, g_free); + g_slice_free (GskGLTextureAtlas, atlas); +} + +static gboolean +gsk_gl_texture_library_real_compact (GskGLTextureLibrary *self, + gint64 frame_id) +{ + GPtrArray *removed = NULL; + gboolean ret = FALSE; + gboolean periodic_scan; + + g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self)); + + periodic_scan = (self->max_frame_age > 0 && + (frame_id % self->max_frame_age) == 0); + + for (guint i = self->atlases->len; i > 0; i--) + { + GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i - 1); + + if (gsk_gl_texture_atlas_get_unused_ratio (atlas) > MAX_OLD_RATIO) + { + GSK_NOTE (GLYPH_CACHE, + g_message ("Dropping atlas %d (%g.2%% old)", i, + 100.0 * gsk_gl_texture_atlas_get_unused_ratio (atlas))); + if (removed == NULL) + removed = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free); + g_ptr_array_add (removed, g_ptr_array_steal_index (self->atlases, i - 1)); + } + } + + if (periodic_scan || removed != NULL) + { + GskGLTextureAtlasEntry *entry; + GHashTableIter iter; + guint dropped = 0; + guint atlased = 0; + + g_hash_table_iter_init (&iter, self->hash_table); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry)) + { + if (entry->is_atlased) + { + if (removed && g_ptr_array_find (removed, entry->atlas, NULL)) + { + g_hash_table_iter_remove (&iter); + dropped++; + } + else if (periodic_scan) + { + gsk_gl_texture_atlas_entry_mark_unused (entry); + entry->accessed = FALSE; + if (entry->is_atlased) + atlased++; + } + } + else if (!entry->accessed) + { + gsk_gl_driver_release_texture (self->driver, entry->texture); + g_hash_table_iter_remove (&iter); + dropped++; + } + } + + GSK_NOTE (GLYPH_CACHE, g_message ("%s: Dropped %d individual items", + G_OBJECT_TYPE_NAME (self), + dropped); + g_message ("%s: %d items cached (%d atlased, %d individually)", + G_OBJECT_TYPE_NAME (self), + g_hash_table_size (self->hash_table), + atlased, + g_hash_table_size (self->hash_table) - atlased)); + + if (dropped > 0) + gsk_gl_texture_library_clear_cache (self); + + ret = TRUE; + + g_clear_pointer (&removed, g_ptr_array_unref); + } + + GSK_NOTE (GLYPH_CACHE, { + static gint64 last_message; + gint64 now = g_get_monotonic_time (); + if (now - last_message > G_USEC_PER_SEC) + { + last_message = now; + g_message ("%s contains %d atlases", + G_OBJECT_TYPE_NAME (self), + self->atlases->len); + } + }); + + return ret; +} + +static gboolean +gsk_gl_texture_library_real_allocate (GskGLTextureLibrary *self, + GskGLTextureAtlas *atlas, + int width, + int height, + int *out_x, + int *out_y) +{ + stbrp_rect rect; + + 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); + + rect.w = width; + rect.h = height; + + stbrp_pack_rects (&atlas->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_constructed (GObject *object) { @@ -108,6 +246,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->compact = gsk_gl_texture_library_real_compact; + klass->allocate = gsk_gl_texture_library_real_allocate; + properties [PROP_DRIVER] = g_param_spec_object ("driver", "Driver", @@ -124,7 +265,7 @@ gsk_gl_texture_library_init (GskGLTextureLibrary *self) self->max_frame_age = DEFAULT_MAX_FRAME_AGE; self->atlas_width = DEFAULT_ATLAS_WIDTH; self->atlas_height = DEFAULT_ATLAS_HEIGHT; - self->atlases = g_ptr_array_new (); + self->atlases = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free); } void @@ -143,90 +284,14 @@ gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self, void gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, - gint64 frame_id, - GPtrArray *removed_atlases) + gint64 frame_id) { - GHashTableIter iter; - gboolean drop_caches = FALSE; - g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self)); + gsk_gl_texture_library_compact (self, frame_id); + if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame) - GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame (self, frame_id, removed_atlases); - - if (removed_atlases != NULL) - { - GskGLTextureAtlasEntry *entry; - guint dropped = 0; - - /* Remove cached copy of purged atlases */ - for (guint i = 0; i < removed_atlases->len; i++) - g_ptr_array_remove (self->atlases, g_ptr_array_index (removed_atlases, i)); - - g_hash_table_iter_init (&iter, self->hash_table); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry)) - { - if (entry->is_atlased) - { - for (guint i = 0; i < removed_atlases->len; i++) - { - GskGLTextureAtlas *atlas = g_ptr_array_index (removed_atlases, i); - - if (atlas == entry->atlas) - { - g_hash_table_iter_remove (&iter); - dropped++; - break; - } - } - } - } - - GSK_NOTE (GLYPH_CACHE, - if (dropped > 0) - g_message ("%s: Dropped %d items", - G_OBJECT_TYPE_NAME (self), dropped)); - - drop_caches |= dropped > 0; - } - - if (frame_id % self->max_frame_age == 0) - { - GskGLTextureAtlasEntry *entry; - int atlased = 0; - int dropped = 0; - - g_hash_table_iter_init (&iter, self->hash_table); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry)) - { - if (!entry->is_atlased && !entry->accessed) - { - gsk_gl_driver_release_texture (self->driver, entry->texture); - g_hash_table_iter_remove (&iter); - dropped++; - continue; - } - - gsk_gl_texture_atlas_entry_mark_unused (entry); - entry->accessed = FALSE; - if (entry->is_atlased) - atlased++; - } - - GSK_NOTE (GLYPH_CACHE, g_message ("%s: Dropped %d individual items", - G_OBJECT_TYPE_NAME (self), - dropped); - g_message ("%s: %d items cached (%d atlased, %d individually)", - G_OBJECT_TYPE_NAME (self), - g_hash_table_size (self->hash_table), - atlased, - g_hash_table_size (self->hash_table) - atlased)); - - drop_caches |= dropped > 0; - } - - if (drop_caches && GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache) - GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache (self); + GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame (self, frame_id); } static GskGLTexture * @@ -253,92 +318,29 @@ 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_library_init_atlas (GskGLTextureLibrary *self, - GskGLTextureAtlas *atlas) -{ - /* Insert a single pixel at 0,0 for use in coloring */ - - gboolean packed G_GNUC_UNUSED; - int x, y; - guint gl_format; - guint gl_type; - guint8 pixel_data[4 * 3 * 3]; - - g_ptr_array_add (self->atlases, atlas); - - 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 ()); - - self->driver->command_queue->n_uploads++; -} - -static void -gsk_gl_texture_atlases_pack (GskGLTextureLibrary *self, - int width, - int height, - GskGLTextureAtlas **out_atlas, - int *out_x, - int *out_y) +gsk_gl_texture_library_pack_any_atlas (GskGLTextureLibrary *self, + int width, + int height, + GskGLTextureAtlas **out_atlas, + int *out_x, + int *out_y) { GskGLTextureAtlas *atlas = NULL; int x, y; + g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self)); + g_assert (width > 0); + g_assert (height > 0); + g_assert (out_atlas != NULL); + g_assert (out_x != NULL); + g_assert (out_y != NULL); + for (guint i = 0; i < self->atlases->len; i++) { atlas = g_ptr_array_index (self->atlases, i); - if (gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y)) + if (gsk_gl_texture_library_allocate (self, atlas, width, height, &x, &y)) break; atlas = NULL; @@ -347,11 +349,10 @@ gsk_gl_texture_atlases_pack (GskGLTextureLibrary *self, if (atlas == NULL) { /* No atlas has enough space, so create a new one... */ - atlas = gsk_gl_driver_create_atlas (self->driver, self->atlas_width, self->atlas_height); - gsk_gl_texture_library_init_atlas (self, atlas); + atlas = gsk_gl_texture_library_acquire_atlas (self); /* Pack it onto that one, which surely has enough space... */ - if (!gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y)) + if (!gsk_gl_texture_library_allocate (self, atlas, width, height, &x, &y)) g_assert_not_reached (); } @@ -407,12 +408,12 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self, int packed_x; int packed_y; - gsk_gl_texture_atlases_pack (self, - padding + width + padding, - padding + height + padding, - &atlas, - &packed_x, - &packed_y); + gsk_gl_texture_library_pack_any_atlas (self, + padding + width + padding, + padding + height + padding, + &atlas, + &packed_x, + &packed_y); entry->atlas = atlas; entry->is_atlased = TRUE; @@ -446,3 +447,134 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self, return entry; } + +/* + * gsk_gl_texture_library_clear_cache: + * + * Clear the front cache if the texture library is using one. For + * example the glyph cache would drop it's front cache to force + * next lookups to fall through to the GHashTable key lookup. + */ +void +gsk_gl_texture_library_clear_cache (GskGLTextureLibrary *self) +{ + g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self)); + + if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache) + GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache (self); +} + +/* + * gsk_gl_texture_library_compact: + * + * Requests that the texture library compact it's altases. That + * generally means to traverse them to look for unused pixels over + * a certain threshold and release them if necessary. + * + * Returns: %TRUE if any compaction occurred. + */ +gboolean +gsk_gl_texture_library_compact (GskGLTextureLibrary *self, + gint64 frame_id) +{ + g_return_val_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self), FALSE); + + if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->compact) + return GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->compact (self, frame_id); + + return FALSE; +} + +void +gsk_gl_texture_library_reset (GskGLTextureLibrary *self) +{ + g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self)); + + gsk_gl_texture_library_clear_cache (self); + + g_hash_table_remove_all (self->hash_table); + + if (self->atlases->len) + g_ptr_array_remove_range (self->atlases, 0, self->atlases->len); +} + +void +gsk_gl_texture_library_set_atlas_size (GskGLTextureLibrary *self, + int width, + int height) +{ + g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self)); + + if (width <= 0) + width = DEFAULT_ATLAS_WIDTH; + + if (height <= 0) + height = DEFAULT_ATLAS_HEIGHT; + + self->atlas_height = height; + self->atlas_width = width; + + gsk_gl_texture_library_reset (self); +} + +/* + * gsk_gl_texture_library_acquire_atlas: + * + * Allocates a new texture atlas based on the current size + * and format requirements. + */ +GskGLTextureAtlas * +gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self) +{ + GskGLTextureAtlas *atlas; + + g_return_val_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self), NULL); + g_return_val_if_fail (GSK_IS_GL_DRIVER (self->driver), NULL); + g_return_val_if_fail (GSK_IS_GL_COMMAND_QUEUE (self->driver->command_queue), NULL); + g_return_val_if_fail (self->atlas_width > 0, NULL); + g_return_val_if_fail (self->atlas_height > 0, NULL); + + atlas = g_slice_new0 (GskGLTextureAtlas); + atlas->width = self->atlas_width; + atlas->height = self->atlas_height; + /* TODO: We might want to change the strategy about the amount of + * nodes here? stb_rect_pack.h says width is optimal. */ + atlas->nodes = g_malloc0_n (atlas->width, sizeof (struct stbrp_node)); + stbrp_init_target (&atlas->context, atlas->width, atlas->height, atlas->nodes, atlas->width); + atlas->texture_id = gsk_gl_command_queue_create_texture (self->driver->command_queue, + atlas->width, + atlas->height, + GL_RGBA8, + GL_LINEAR, + GL_LINEAR); + + gdk_gl_context_label_object_printf (gdk_gl_context_get_current (), + GL_TEXTURE, atlas->texture_id, + "Texture atlas %d", + atlas->texture_id); + + g_ptr_array_add (self->atlases, atlas); + + if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->init_atlas) + GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->init_atlas (self, atlas); + + return atlas; +} + +gboolean +gsk_gl_texture_library_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_LIBRARY_GET_CLASS (self)->allocate (self, atlas, width, height, out_x, out_y); +} diff --git a/gsk/gl/gskgltexturelibraryprivate.h b/gsk/gl/gskgltexturelibraryprivate.h index 167b00923b..a0292c497b 100644 --- a/gsk/gl/gskgltexturelibraryprivate.h +++ b/gsk/gl/gskgltexturelibraryprivate.h @@ -102,31 +102,53 @@ 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); + gboolean (*compact) (GskGLTextureLibrary *library, + gint64 frame_id); + void (*clear_cache) (GskGLTextureLibrary *library); + void (*init_atlas) (GskGLTextureLibrary *library, + GskGLTextureAtlas *atlas); + gboolean (*allocate) (GskGLTextureLibrary *library, + GskGLTextureAtlas *atlas, + int width, + int height, + int *out_x, + int *out_y); } GskGLTextureLibraryClass; G_DEFINE_AUTOPTR_CLEANUP_FUNC (GskGLTextureLibrary, g_object_unref) -GType gsk_gl_texture_library_get_type (void) G_GNUC_CONST; -void gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self, - GHashFunc hash_func, - GEqualFunc equal_func, - GDestroyNotify key_destroy, - GDestroyNotify value_destroy); -void gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, - gint64 frame_id, - GPtrArray *removed_atlases); -gpointer gsk_gl_texture_library_pack (GskGLTextureLibrary *self, - gpointer key, - gsize valuelen, - guint width, - guint height, - int padding, - guint *out_packed_x, - guint *out_packed_y); +GType gsk_gl_texture_library_get_type (void) G_GNUC_CONST; +gboolean gsk_gl_texture_library_compact (GskGLTextureLibrary *self, + gint64 frame_id); +void gsk_gl_texture_library_clear_cache (GskGLTextureLibrary *self); +void gsk_gl_texture_library_reset (GskGLTextureLibrary *self); +void gsk_gl_texture_library_set_atlas_size (GskGLTextureLibrary *self, + int width, + int height); +GskGLTextureAtlas *gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self); +void gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self, + GHashFunc hash_func, + GEqualFunc equal_func, + GDestroyNotify key_destroy, + GDestroyNotify value_destroy); +void gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self, + gint64 frame_id); +gboolean gsk_gl_texture_library_allocate (GskGLTextureLibrary *self, + GskGLTextureAtlas *atlas, + int width, + int height, + int *out_x, + int *out_y); +gpointer gsk_gl_texture_library_pack (GskGLTextureLibrary *self, + gpointer key, + gsize valuelen, + guint width, + guint height, + int padding, + guint *out_packed_x, + guint *out_packed_y); static inline void gsk_gl_texture_atlas_mark_unused (GskGLTextureAtlas *self, From cbbca38d88dad71327d36693c089ffda6cb80ba4 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 18 Mar 2022 14:55:13 -0700 Subject: [PATCH 11/11] gsk/gl: use consistent library naming --- gsk/gl/gskgldriver.c | 14 +++++++------- gsk/gl/gskgldriverprivate.h | 4 ++-- gsk/gl/gskglrenderjob.c | 10 ++++++---- gsk/gl/gskglshadowlibrary.c | 4 ++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 68311b7238..0390f97702 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -274,8 +274,8 @@ gsk_gl_driver_dispose (GObject *object) g_assert (!self->key_to_texture_id|| g_hash_table_size (self->key_to_texture_id) == 0); g_clear_object (&self->glyphs_library); - g_clear_object (&self->icons); - g_clear_object (&self->shadows); + g_clear_object (&self->icons_library); + g_clear_object (&self->shadows_library); g_clear_pointer (&self->autorelease_framebuffers, g_array_unref); g_clear_pointer (&self->key_to_texture_id, g_hash_table_unref); @@ -462,8 +462,8 @@ gsk_gl_driver_new (GskGLCommandQueue *command_queue, } self->glyphs_library = gsk_gl_glyph_library_new (self); - self->icons = gsk_gl_icon_library_new (self); - self->shadows = gsk_gl_shadow_library_new (self); + self->icons_library = gsk_gl_icon_library_new (self); + self->shadows_library = gsk_gl_shadow_library_new (self); gdk_profiler_end_mark (before, "create GskGLDriver", NULL); @@ -554,13 +554,13 @@ gsk_gl_driver_begin_frame (GskGLDriver *self, gsk_gl_command_queue_begin_frame (self->command_queue); /* Mark unused pixel regions of the atlases */ - gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->icons), + gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->icons_library), self->current_frame_id); gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs_library), self->current_frame_id); /* Cleanup old shadows */ - gsk_gl_shadow_library_begin_frame (self->shadows); + gsk_gl_shadow_library_begin_frame (self->shadows_library); /* Remove all textures that are from a previous frame or are no * longer used by linked GdkTexture. We do this at the beginning @@ -1158,7 +1158,7 @@ gsk_gl_driver_save_atlases_to_png (GskGLDriver *self, g_ptr_array_extend(dst, GSK_GL_TEXTURE_LIBRARY(library)->atlases, NULL, NULL) atlases = g_ptr_array_new (); copy_atlases (atlases, self->glyphs_library); - copy_atlases (atlases, self->icons); + copy_atlases (atlases, self->icons_library); #undef copy_atlases for (guint i = 0; i < atlases->len; i++) diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h index 863240fc3e..accae5b3bb 100644 --- a/gsk/gl/gskgldriverprivate.h +++ b/gsk/gl/gskgldriverprivate.h @@ -101,8 +101,8 @@ struct _GskGLDriver GskGLCommandQueue *command_queue; GskGLGlyphLibrary *glyphs_library; - GskGLIconLibrary *icons; - GskGLShadowLibrary *shadows; + GskGLIconLibrary *icons_library; + GskGLShadowLibrary *shadows_library; GArray *texture_pool; GHashTable *textures; diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c index 3371bab826..30c6cd7a41 100644 --- a/gsk/gl/gskglrenderjob.c +++ b/gsk/gl/gskglrenderjob.c @@ -2512,7 +2512,9 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job, scaled_outline.corner[i].height *= scale_y; } - cached_tid = gsk_gl_shadow_library_lookup (job->driver->shadows, &scaled_outline, blur_radius); + cached_tid = gsk_gl_shadow_library_lookup (job->driver->shadows_library, + &scaled_outline, + blur_radius); if (cached_tid == 0) { @@ -2574,7 +2576,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job, blur_radius * scale_x, blur_radius * scale_y); - gsk_gl_shadow_library_insert (job->driver->shadows, + gsk_gl_shadow_library_insert (job->driver->shadows_library, &scaled_outline, blur_radius, blurred_texture_id); @@ -3499,14 +3501,14 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job, GdkTexture *texture, GskGLRenderOffscreen *offscreen) { - if (gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons, + if (gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library, texture->width, texture->height) && !GDK_IS_GL_TEXTURE (texture)) { const GskGLIconData *icon_data; - gsk_gl_icon_library_lookup_or_add (job->driver->icons, texture, &icon_data); + gsk_gl_icon_library_lookup_or_add (job->driver->icons_library, texture, &icon_data); offscreen->texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data); memcpy (&offscreen->area, &icon_data->entry.area, sizeof offscreen->area); } diff --git a/gsk/gl/gskglshadowlibrary.c b/gsk/gl/gskglshadowlibrary.c index 86e4e5a476..119ba8145b 100644 --- a/gsk/gl/gskglshadowlibrary.c +++ b/gsk/gl/gskglshadowlibrary.c @@ -29,9 +29,9 @@ struct _GskGLShadowLibrary { - GObject parent_instance; + GObject parent_instance; GskGLDriver *driver; - GArray *shadows; + GArray *shadows; }; typedef struct _Shadow