mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 19:18:12 +02:00
[cairo] Track the MRU scaled font
When observing applications two patterns emerge. The first is due to Pango, which wraps each glyph run within a context save/restore. This causes the scaled font to be evicted after every run and reloaded on the next. This is caught by the MRU slot on the cairo_scaled_font_map and prevents a relatively costly traversal of the hash table and holdovers. The second pattern is by applications that directly manage the rendering of their own glyphs. The prime example of this is gnome-terminal/vte. Here the application frequently alternates between a few scaled fonts - which requires a hash table retrieval every time. By introducing a MRU slot on the gstate we are able to directly recover the scaled font around 90% of the time. Of 110,000 set-scaled-fonts: 4,000 were setting the current font 96,000 were setting to the previous font 2,500 were recovered from the MRU on the cairo_scaled_font_map 7,500 needed a hash retrieval which compares to ~106,000 hash lookups without the additional MRU slot on the gstate. This translates to an elapsed time saving of ~5% when replaying a gnome-terminal trace using the drm backend.
This commit is contained in:
parent
fda89c56ff
commit
dc083ab30a
3 changed files with 21 additions and 4 deletions
|
|
@ -50,6 +50,7 @@ struct _cairo_gstate {
|
|||
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_scaled_font_t *scaled_font; /* Specific to the current CTM */
|
||||
cairo_scaled_font_t *previous_scaled_font; /* holdover */
|
||||
cairo_matrix_t font_matrix;
|
||||
cairo_font_options_t font_options;
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
|||
|
||||
gstate->font_face = NULL;
|
||||
gstate->scaled_font = NULL;
|
||||
gstate->previous_scaled_font = NULL;
|
||||
|
||||
cairo_matrix_init_scale (&gstate->font_matrix,
|
||||
CAIRO_GSTATE_DEFAULT_FONT_SIZE,
|
||||
|
|
@ -153,6 +154,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
|||
|
||||
gstate->font_face = cairo_font_face_reference (other->font_face);
|
||||
gstate->scaled_font = cairo_scaled_font_reference (other->scaled_font);
|
||||
gstate->previous_scaled_font = cairo_scaled_font_reference (other->previous_scaled_font);
|
||||
|
||||
gstate->font_matrix = other->font_matrix;
|
||||
|
||||
|
|
@ -163,6 +165,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
|||
_cairo_stroke_style_fini (&gstate->stroke_style);
|
||||
cairo_font_face_destroy (gstate->font_face);
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -190,6 +193,9 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
|
|||
cairo_font_face_destroy (gstate->font_face);
|
||||
gstate->font_face = NULL;
|
||||
|
||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
||||
gstate->previous_scaled_font = NULL;
|
||||
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
gstate->scaled_font = NULL;
|
||||
|
||||
|
|
@ -1293,10 +1299,14 @@ _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
|
|||
static void
|
||||
_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate)
|
||||
{
|
||||
if (gstate->scaled_font) {
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
gstate->scaled_font = NULL;
|
||||
}
|
||||
if (gstate->scaled_font == NULL)
|
||||
return;
|
||||
|
||||
if (gstate->previous_scaled_font != NULL)
|
||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
||||
|
||||
gstate->previous_scaled_font = gstate->scaled_font;
|
||||
gstate->scaled_font = NULL;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
|
|||
|
|
@ -2910,6 +2910,7 @@ cairo_set_scaled_font (cairo_t *cr,
|
|||
const cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_bool_t was_previous;
|
||||
|
||||
if (cr->status)
|
||||
return;
|
||||
|
|
@ -2926,6 +2927,8 @@ cairo_set_scaled_font (cairo_t *cr,
|
|||
if (scaled_font == cr->gstate->scaled_font)
|
||||
return;
|
||||
|
||||
was_previous = scaled_font == cr->gstate->previous_scaled_font;
|
||||
|
||||
status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
|
@ -2936,6 +2939,9 @@ cairo_set_scaled_font (cairo_t *cr,
|
|||
|
||||
_cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
|
||||
|
||||
if (was_previous)
|
||||
cr->gstate->scaled_font = cairo_scaled_font_reference ((cairo_scaled_font_t *) scaled_font);
|
||||
|
||||
return;
|
||||
|
||||
BAIL:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue