diff options
author | Timm Bäder <mail@baedert.org> | 2019-01-06 15:35:54 +0100 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2019-01-10 16:49:19 +0100 |
commit | e72d0a9118de996ccdf1250c61c9bc6febf51b52 (patch) | |
tree | 3d0b6315de50299913537d09d99e043ae5ad24ee /gsk | |
parent | 8b14c8d0a820e6617bd72a39a53d2ae6fa7b242b (diff) | |
download | gtk+-e72d0a9118de996ccdf1250c61c9bc6febf51b52.tar.gz |
gl glyphcache: Only support one dirty glyph per atlas
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/gl/gskglglyphcache.c | 67 | ||||
-rw-r--r-- | gsk/gl/gskglglyphcacheprivate.h | 25 |
2 files changed, 38 insertions, 54 deletions
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c index 842a899427..dd0a3a5143 100644 --- a/gsk/gl/gskglglyphcache.c +++ b/gsk/gl/gskglglyphcache.c @@ -24,21 +24,6 @@ #define ATLAS_SIZE 512 -typedef struct -{ - PangoFont *font; - PangoGlyph glyph; - guint scale; /* times 1024 */ -} GlyphCacheKey; - -typedef struct -{ - GlyphCacheKey *key; - GskGLCachedGlyph *value; - cairo_surface_t *surface; -} DirtyGlyph; - - static guint glyph_cache_hash (gconstpointer v); static gboolean glyph_cache_equal (gconstpointer v1, gconstpointer v2); @@ -58,8 +43,6 @@ create_atlas (GskGLGlyphCache *cache) atlas->y = 1; atlas->x = 1; atlas->image = NULL; - atlas->num_glyphs = 0; - atlas->dirty_glyphs = NULL; return atlas; } @@ -74,7 +57,7 @@ free_atlas (gpointer v) g_assert (atlas->image->texture_id == 0); g_free (atlas->image); } - g_list_free_full (atlas->dirty_glyphs, dirty_glyph_free); + g_free (atlas); } @@ -153,17 +136,15 @@ dirty_glyph_free (gpointer v) if (glyph->surface) cairo_surface_destroy (glyph->surface); - g_free (glyph); } static void add_to_cache (GskGLGlyphCache *cache, - GlyphCacheKey *key, + GlyphCacheKey *key, GskGLCachedGlyph *value) { GskGLGlyphAtlas *atlas; int i; - DirtyGlyph *dirty; int width = value->draw_width * key->scale / 1024; int height = value->draw_height * key->scale / 1024; @@ -205,16 +186,12 @@ add_to_cache (GskGLGlyphCache *cache, value->atlas = atlas; - dirty = g_new0 (DirtyGlyph, 1); - dirty->key = key; - dirty->value = value; - atlas->dirty_glyphs = g_list_prepend (atlas->dirty_glyphs, dirty); + atlas->pending_glyph.key = key; + atlas->pending_glyph.value = value; atlas->x = atlas->x + width + 1; atlas->y = MAX (atlas->y, atlas->y0 + height + 1); - atlas->num_glyphs++; - #ifdef G_ENABLE_DEBUG if (GSK_RENDERER_DEBUG_CHECK (cache->renderer, GLYPH_CACHE)) { @@ -222,9 +199,8 @@ add_to_cache (GskGLGlyphCache *cache, for (i = 0; i < cache->atlases->len; i++) { atlas = g_ptr_array_index (cache->atlases, i); - g_print ("\tGskGLGlyphAtlas %d (%dx%d): %d glyphs (%d dirty), %.2g%% old pixels, filled to %d, %d / %d\n", + g_print ("\tGskGLGlyphAtlas %d (%dx%d): %.2g%% old pixels, filled to %d, %d / %d\n", i, atlas->width, atlas->height, - atlas->num_glyphs, g_list_length (atlas->dirty_glyphs), 100.0 * (double)atlas->old_pixels / (double)(atlas->width * atlas->height), atlas->x, atlas->y0, atlas->y); } @@ -284,28 +260,20 @@ render_glyph (const GskGLGlyphAtlas *atlas, } static void -upload_dirty_glyphs (GskGLGlyphCache *self, - GskGLGlyphAtlas *atlas) +upload_dirty_glyph (GskGLGlyphCache *self, + GskGLGlyphAtlas *atlas) { - GList *l; - guint num_regions; - GskImageRegion *regions; - int i; + GskImageRegion region; - num_regions = g_list_length (atlas->dirty_glyphs); - regions = alloca (sizeof (GskImageRegion) * num_regions); + g_assert (atlas->pending_glyph.key != NULL); - for (l = atlas->dirty_glyphs, i = 0; l; l = l->next, i++) - render_glyph (atlas, (DirtyGlyph *)l->data, ®ions[i]); + render_glyph (atlas, &atlas->pending_glyph, ®ion); - GSK_RENDERER_NOTE (self->renderer, GLYPH_CACHE, - g_message ("uploading %d glyphs to cache", num_regions)); + gsk_gl_image_upload_regions (atlas->image, self->gl_driver, 1, ®ion); - - gsk_gl_image_upload_regions (atlas->image, self->gl_driver, num_regions, regions); - - g_list_free_full (atlas->dirty_glyphs, dirty_glyph_free); - atlas->dirty_glyphs = NULL; + dirty_glyph_free (&atlas->pending_glyph); + atlas->pending_glyph.key = NULL; + atlas->pending_glyph.value = NULL; } const GskGLCachedGlyph * @@ -369,22 +337,21 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache, } GskGLImage * -gsk_gl_glyph_cache_get_glyph_image (GskGLGlyphCache *self, +gsk_gl_glyph_cache_get_glyph_image (GskGLGlyphCache *self, const GskGLCachedGlyph *glyph) { GskGLGlyphAtlas *atlas = glyph->atlas; g_assert (atlas != NULL); - if (atlas->image == NULL) { atlas->image = g_new0 (GskGLImage, 1); gsk_gl_image_create (atlas->image, self->gl_driver, atlas->width, atlas->height); } - if (atlas->dirty_glyphs) - upload_dirty_glyphs (self, atlas); + if (atlas->pending_glyph.key != NULL) + upload_dirty_glyph (self, atlas); return atlas->image; } diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h index 122a82398b..4f162c4e38 100644 --- a/gsk/gl/gskglglyphcacheprivate.h +++ b/gsk/gl/gskglglyphcacheprivate.h @@ -18,18 +18,34 @@ typedef struct guint64 timestamp; } GskGLGlyphCache; +typedef struct +{ + PangoFont *font; + PangoGlyph glyph; + guint scale; /* times 1024 */ +} GlyphCacheKey; + +typedef struct _DirtyGlyph DirtyGlyph; +typedef struct _GskGLCachedGlyph GskGLCachedGlyph; + +struct _DirtyGlyph +{ + GlyphCacheKey *key; + GskGLCachedGlyph *value; + cairo_surface_t *surface; +}; typedef struct { GskGLImage *image; int width, height; int x, y, y0; - int num_glyphs; - GList *dirty_glyphs; guint old_pixels; + + DirtyGlyph pending_glyph; } GskGLGlyphAtlas; -typedef struct +struct _GskGLCachedGlyph { GskGLGlyphAtlas *atlas; @@ -44,7 +60,8 @@ typedef struct int draw_height; guint64 timestamp; -} GskGLCachedGlyph; +}; + void gsk_gl_glyph_cache_init (GskGLGlyphCache *self, GskRenderer *renderer, |