summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2019-01-06 15:35:54 +0100
committerTimm Bäder <mail@baedert.org>2019-01-10 16:49:19 +0100
commite72d0a9118de996ccdf1250c61c9bc6febf51b52 (patch)
tree3d0b6315de50299913537d09d99e043ae5ad24ee
parent8b14c8d0a820e6617bd72a39a53d2ae6fa7b242b (diff)
downloadgtk+-e72d0a9118de996ccdf1250c61c9bc6febf51b52.tar.gz
gl glyphcache: Only support one dirty glyph per atlas
-rw-r--r--gsk/gl/gskglglyphcache.c67
-rw-r--r--gsk/gl/gskglglyphcacheprivate.h25
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, &regions[i]);
+ render_glyph (atlas, &atlas->pending_glyph, &region);
- 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, &region);
-
- 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,