[gtk/glyphy2: 25/34] glyphy: Make glyphy cache size-independent
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/glyphy2: 25/34] glyphy: Make glyphy cache size-independent
- Date: Thu, 7 Apr 2022 03:26:18 +0000 (UTC)
commit ae0ca8784259586e538b90b01b2a531a19c7cf83
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Mar 19 14:32:03 2022 -0400
glyphy: Make glyphy cache size-independent
Use a hb font at nominal size when generating sdf
contours, and use a cache key that is independent
of the size.
gsk/gl/gskglglyphylibrary.c | 46 ++++++++++++++++++++++++++++----------
gsk/gl/gskglglyphylibraryprivate.h | 42 +++++++++++++++++++++++++++++++---
gsk/gl/gskglrenderjob.c | 19 +++++++++-------
3 files changed, 84 insertions(+), 23 deletions(-)
---
diff --git a/gsk/gl/gskglglyphylibrary.c b/gsk/gl/gskglglyphylibrary.c
index 9411081534..d4d7e7abbd 100644
--- a/gsk/gl/gskglglyphylibrary.c
+++ b/gsk/gl/gskglglyphylibrary.c
@@ -79,11 +79,7 @@ gsk_gl_glyphy_key_hash (gconstpointer data)
* for us.
*/
-#if GLIB_SIZEOF_VOID_P == 4
- return (guint)(GPOINTER_TO_SIZE (key->font) << 6) ^ key->glyph;
-#else
- return (guint)(GPOINTER_TO_SIZE (key->font) << 5) ^ key->glyph;
-#endif
+ return (key->font << 8) ^ key->glyph;
}
static gboolean
@@ -98,7 +94,6 @@ gsk_gl_glyphy_key_free (gpointer data)
{
GskGLGlyphyKey *key = data;
- g_clear_object (&key->font);
g_slice_free (GskGLGlyphyKey, key);
}
@@ -187,12 +182,16 @@ gsk_gl_glyphy_library_finalize (GObject *object)
G_OBJECT_CLASS (gsk_gl_glyphy_library_parent_class)->finalize (object);
}
+GQuark quark_glyphy_font_key;
+
static void
gsk_gl_glyphy_library_class_init (GskGLGlyphyLibraryClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GskGLTextureLibraryClass *library_class = GSK_GL_TEXTURE_LIBRARY_CLASS (klass);
+ quark_glyphy_font_key = g_quark_from_static_string ("glyphy-font-key");
+
object_class->finalize = gsk_gl_glyphy_library_finalize;
library_class->allocate = gsk_gl_glyphy_library_allocate;
@@ -284,16 +283,39 @@ encode_glyph (GskGLGlyphyLibrary *self,
return TRUE;
}
+static inline hb_font_t *
+get_nominal_size_hb_font (PangoFont *font)
+{
+ hb_font_t *hbfont;
+ const float *coords;
+ unsigned int length;
+
+ hbfont = (hb_font_t *) g_object_get_data ((GObject *)font, "glyph-nominal-size-font");
+ if (hbfont == NULL)
+ {
+ hbfont = hb_font_create (hb_font_get_face (pango_font_get_hb_font (font)));
+ coords = hb_font_get_var_coords_design (pango_font_get_hb_font (font), &length);
+ if (length > 0)
+ hb_font_set_var_coords_design (hbfont, coords, length);
+
+ g_object_set_data_full ((GObject *)font, "glyphy-nominal-size-font",
+ hbfont, (GDestroyNotify)hb_font_destroy);
+ }
+
+ return hbfont;
+}
+
gboolean
gsk_gl_glyphy_library_add (GskGLGlyphyLibrary *self,
GskGLGlyphyKey *key,
+ PangoFont *font,
const GskGLGlyphyValue **out_value)
{
static glyphy_rgba_t buffer[4096 * 16];
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
GskGLGlyphyValue *value;
glyphy_extents_t extents;
- hb_font_t *font;
+ hb_font_t *hbfont;
guint packed_x;
guint packed_y;
guint nominal_w, nominal_h;
@@ -303,15 +325,15 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary *self,
g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
g_assert (key != NULL);
- g_assert (key->font != NULL);
+ g_assert (font != NULL);
g_assert (out_value != NULL);
+ hbfont = get_nominal_size_hb_font (font);
+
/* Convert the glyph to a list of arcs */
- font = pango_font_get_hb_font (key->font);
- if (!encode_glyph (self, font, key->glyph, TOLERANCE,
+ if (!encode_glyph (self, hbfont, key->glyph, TOLERANCE,
buffer, sizeof buffer, &output_len,
- &nominal_w, &nominal_h,
- &extents))
+ &nominal_w, &nominal_h, &extents))
return FALSE;
/* Allocate space for list within atlas */
diff --git a/gsk/gl/gskglglyphylibraryprivate.h b/gsk/gl/gskglglyphylibraryprivate.h
index 7bd83a5640..fece808bcd 100644
--- a/gsk/gl/gskglglyphylibraryprivate.h
+++ b/gsk/gl/gskglglyphylibraryprivate.h
@@ -30,9 +30,44 @@ G_BEGIN_DECLS
#define GSK_TYPE_GL_GLYPHY_LIBRARY (gsk_gl_glyphy_library_get_type())
+typedef guint FontKey;
+
+extern GQuark quark_glyphy_font_key;
+
+static inline FontKey
+gsk_gl_glyphy_library_get_font_key (PangoFont *font)
+{
+ FontKey key;
+
+ key = (FontKey) GPOINTER_TO_UINT (g_object_get_qdata ((GObject *)font, quark_glyphy_font_key));
+ if (key == 0)
+ {
+ PangoFontDescription *desc = pango_font_describe (font);
+ pango_font_description_set_size (desc, 10 * PANGO_SCALE);
+ key = (FontKey) pango_font_description_hash (desc);
+ pango_font_description_free (desc);
+ g_object_set_qdata ((GObject *)font, quark_glyphy_font_key, GUINT_TO_POINTER (key));
+ }
+
+ return key;
+}
+
+static inline float
+gsk_gl_glyphy_library_get_font_scale (PangoFont *font)
+{
+ hb_font_t *hbfont;
+ int x_scale, y_scale;
+
+ hbfont = pango_font_get_hb_font (font);
+ hb_font_get_scale (hbfont, &x_scale, &y_scale);
+
+ return MAX (x_scale, y_scale) / 1000.0;
+}
+
+
typedef struct _GskGLGlyphyKey
{
- PangoFont *font;
+ FontKey font;
PangoGlyph glyph;
} GskGLGlyphyKey;
@@ -69,11 +104,13 @@ struct _GskGLGlyphyLibrary
GskGLGlyphyLibrary *gsk_gl_glyphy_library_new (GskGLDriver *driver);
gboolean gsk_gl_glyphy_library_add (GskGLGlyphyLibrary *self,
GskGLGlyphyKey *key,
+ PangoFont *font,
const GskGLGlyphyValue **out_value);
static inline guint
gsk_gl_glyphy_library_lookup_or_add (GskGLGlyphyLibrary *self,
const GskGLGlyphyKey *key,
+ PangoFont *font,
const GskGLGlyphyValue **out_value)
{
GskGLTextureAtlasEntry *entry;
@@ -92,8 +129,7 @@ gsk_gl_glyphy_library_lookup_or_add (GskGLGlyphyLibrary *self,
else
{
GskGLGlyphyKey *k = g_slice_copy (sizeof *key, key);
- g_object_ref (k->font);
- gsk_gl_glyphy_library_add (self, k, out_value);
+ gsk_gl_glyphy_library_add (self, k, font, out_value);
self->front[front_index].key = *key;
self->front[front_index].value = *out_value;
}
diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c
index 7cdfd815db..cff6ac0260 100644
--- a/gsk/gl/gskglrenderjob.c
+++ b/gsk/gl/gskglrenderjob.c
@@ -3076,7 +3076,7 @@ typedef struct
float g16lo;
} EncodedGlyph;
-static unsigned int
+static inline unsigned int
glyph_encode (guint atlas_x , /* 7 bits */
guint atlas_y, /* 7 bits */
guint corner_x, /* 1 bit */
@@ -3099,7 +3099,7 @@ glyph_encode (guint atlas_x , /* 7 bits */
return (x << 16) | y;
}
-static void
+static inline void
encoded_glyph_init (EncodedGlyph *eg,
float x,
float y,
@@ -3133,7 +3133,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
const PangoGlyphInfo *gi;
GskGLGlyphyLibrary *library;
GskGLCommandBatch *batch;
- const PangoFont *font;
+ PangoFont *font;
GskGLDrawVertex *vertices;
const guint16 *c;
GskGLGlyphyKey lookup;
@@ -3145,6 +3145,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
guint used = 0;
guint i;
int x_position = 0;
+ float font_scale;
g_assert (!gsk_text_node_has_color_glyphs (node));
@@ -3154,7 +3155,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
if (RGBA_IS_CLEAR (color))
return;
- font = gsk_text_node_get_font (node);
+ font = (PangoFont *)gsk_text_node_get_font (node);
glyphs = gsk_text_node_get_glyphs (node, NULL);
library = job->driver->glyphy_library;
offset = gsk_text_node_get_offset (node);
@@ -3169,7 +3170,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
batch = gsk_gl_command_queue_get_batch (job->command_queue);
vertices = gsk_gl_command_queue_add_n_vertices (job->command_queue, num_glyphs);
- lookup.font = (PangoFont *)font;
+ lookup.font = gsk_gl_glyphy_library_get_font_key (font);
+ font_scale = gsk_gl_glyphy_library_get_font_scale (font);
for (i = 0, gi = glyphs; i < num_glyphs; i++, gi++)
{
@@ -3178,7 +3180,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
guint texture_id;
lookup.glyph = gi->glyph;
- texture_id = gsk_gl_glyphy_library_lookup_or_add (library, &lookup, &glyph);
+ texture_id = gsk_gl_glyphy_library_lookup_or_add (library, &lookup, font, &glyph);
+
if G_UNLIKELY (texture_id == 0)
continue;
@@ -3228,8 +3231,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job,
EncodedGlyph encoded[4];
#define ENCODE_CORNER(_cx, _cy) \
G_STMT_START { \
- float _vx = x + cx + ((1-_cx) * glyph->extents.min_x + _cx * glyph->extents.max_x); \
- float _vy = y + cy - ((1-_cy) * glyph->extents.min_y + _cy * glyph->extents.max_y); \
+ float _vx = x + cx + font_scale * ((1-_cx) * glyph->extents.min_x + _cx * glyph->extents.max_x); \
+ float _vy = y + cy - font_scale * ((1-_cy) * glyph->extents.min_y + _cy * glyph->extents.max_y); \
encoded_glyph_init (&encoded[_cx * 2 + _cy], _vx, _vy, _cx, _cy, glyph); \
} G_STMT_END
ENCODE_CORNER (0, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]