mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-24 08:40:31 +01:00
scaled-font: fine-tune caching
This patch implements the ideas outlined by Behdad Esfahbod in the following mailing list message: http://lists.cairographics.org/archives/cairo/2010-June/020065.html Specifically, two things have been adjusted. First, the size of the look-up table was reduced to 64. Second, cache codepath is now bypassed for strings that are shorter than 16, not only for one-character strings. This allowed us to reduce the LUT initialization overhead while still retaining the advantage of caching for common-case string sizes. We have experimented with different LUT sizes, and it came out that the size of 64 is the best one in view of speed, at least for our language-neutral benchmark, which generated random strings of printable ASCII characters. Below is a table presenting benchmark results for different values of LUT size: =============================================================================== Benchmark | [1] | [2] | [3] | [4] | [5] | [6] | [7] =============================================================================== 8px text, 1 chars | 0.41 | 0.41 | 0 | 0.41 | 0 | 0.41 | 0 8px text, 10 chars | 2.13 | 2.21 | 3.76 | 2.19 | 2.82 | 2.09 | -1.88 8px text, 20 chars | 2.97 | 3.04 | 2.36 | 3.01 | 1.35 | 2.98 | 0.34 12px text, 1 chars | 0.94 | 0.94 | 0 | 0.95 | 1.06 | 0.94 | 0 12px text, 10 chars | 4.73 | 4.89 | 3.38 | 4.9 | 3.59 | 4.82 | 1.9 12px text, 20 chars | 6.32 | 6.42 | 1.58 | 6.46 | 2.22 | 6.32 | 0 16px text, 1 chars | 1.75 | 1.76 | 0.57 | 1.77 | 1.14 | 1.76 | 0.57 16px text, 10 chars | 8.13 | 8.45 | 3.94 | 8.43 | 3.69 | 8.44 | 3.81 16px text, 20 chars | 10.41 | 10.69 | 2.69 | 10.64 | 2.21 | 10.65 | 2.31 24px text, 1 chars | 3.3 | 3.3 | 0 | 3.32 | 0.61 | 3.3 | 0 24px text, 10 chars | 14.68 | 14.97 | 1.98 | 14.97 | 1.98 | 14.87 | 1.29 24px text, 20 chars | 17.93 | 18.01 | 0.45 | 18.06 | 0.73 | 17.81 | -0.67 96px text, 1 chars | 23.65 | 23.38 | -1.14 | 23.74 | 0.38 | 23.65 | 0 96px text, 5 chars | 50.52 | 51.34 | 1.62 | 51.48 | 1.9 | 51.41 | 1.76 96px text, 10 chars | 57.5 | 58.11 | 1.06 | 58.27 | 1.34 | 58.04 | 0.94 =============================================================================== [1]: Git head, Mpix/s [2]: {GLYPH_LUT_SIZE = 32, CACHING_THRESHOLD = 16} [3]: Gain of {32, 16} w.r.t. Git head [4]: {GLYPH_LUT_SIZE = 64, CACHING_THRESHOLD = 16} [5]: Gain of {64, 16} w.r.t. Git head [6]: {GLYPH_LUT_SIZE = 128, CACHING_THRESHOLD = 16} [7]: Gain of {128, 16} w.r.t. Git head The benchmark itself can be found from this mailing list message: http://lists.cairographics.org/archives/cairo/2010-June/020064.html
This commit is contained in:
parent
505a0456d2
commit
4a0bd91ff7
1 changed files with 45 additions and 16 deletions
|
|
@ -1570,9 +1570,9 @@ ZERO_EXTENTS:
|
|||
}
|
||||
slim_hidden_def (cairo_scaled_font_glyph_extents);
|
||||
|
||||
#define GLYPH_LUT_SIZE 256
|
||||
#define GLYPH_LUT_SIZE 64
|
||||
static cairo_status_t
|
||||
cairo_scaled_font_text_to_glyphs_internal_multiple (cairo_scaled_font_t *scaled_font,
|
||||
cairo_scaled_font_text_to_glyphs_internal_cached (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
|
|
@ -1644,7 +1644,7 @@ cairo_scaled_font_text_to_glyphs_internal_multiple (cairo_scaled_font_t *scale
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_scaled_font_text_to_glyphs_internal_single (cairo_scaled_font_t *scaled_font,
|
||||
cairo_scaled_font_text_to_glyphs_internal_uncached (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
|
|
@ -1652,19 +1652,47 @@ cairo_scaled_font_text_to_glyphs_internal_single (cairo_scaled_font_t *scaled_f
|
|||
cairo_text_cluster_t **clusters,
|
||||
int num_chars)
|
||||
{
|
||||
uint32_t unicode;
|
||||
int num_bytes;
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
glyphs[0].x = x;
|
||||
glyphs[0].y = y;
|
||||
p = utf8;
|
||||
for (i = 0; i < num_chars; i++) {
|
||||
unsigned long g;
|
||||
int num_bytes;
|
||||
uint32_t unicode;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
cairo_status_t status;
|
||||
|
||||
num_bytes = _cairo_utf8_get_char_validated (utf8, &unicode);
|
||||
glyphs[0].index =
|
||||
scaled_font->backend->ucs4_to_index (scaled_font, unicode);
|
||||
num_bytes = _cairo_utf8_get_char_validated (p, &unicode);
|
||||
p += num_bytes;
|
||||
|
||||
if (clusters) {
|
||||
(*clusters)[0].num_bytes = num_bytes;
|
||||
(*clusters)[0].num_glyphs = 1;
|
||||
glyphs[i].x = x;
|
||||
glyphs[i].y = y;
|
||||
|
||||
g = scaled_font->backend->ucs4_to_index (scaled_font, unicode);
|
||||
|
||||
/*
|
||||
* No advance needed for a single character string. So, let's speed up
|
||||
* one-character strings by skipping glyph lookup.
|
||||
*/
|
||||
if (num_chars > 1) {
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
g,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
x += scaled_glyph->metrics.x_advance;
|
||||
y += scaled_glyph->metrics.y_advance;
|
||||
}
|
||||
|
||||
glyphs[i].index = g;
|
||||
|
||||
if (clusters) {
|
||||
(*clusters)[i].num_bytes = num_bytes;
|
||||
(*clusters)[i].num_glyphs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -1805,6 +1833,7 @@ cairo_scaled_font_text_to_glyphs_internal_single (cairo_scaled_font_t *scaled_f
|
|||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
#define CACHING_THRESHOLD 16
|
||||
cairo_status_t
|
||||
cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
|
|
@ -1958,15 +1987,15 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
*num_clusters = num_chars;
|
||||
}
|
||||
|
||||
if (num_chars > 1)
|
||||
status = cairo_scaled_font_text_to_glyphs_internal_multiple (scaled_font,
|
||||
if (num_chars > CACHING_THRESHOLD)
|
||||
status = cairo_scaled_font_text_to_glyphs_internal_cached (scaled_font,
|
||||
x, y,
|
||||
utf8,
|
||||
*glyphs,
|
||||
clusters,
|
||||
num_chars);
|
||||
else
|
||||
status = cairo_scaled_font_text_to_glyphs_internal_single (scaled_font,
|
||||
status = cairo_scaled_font_text_to_glyphs_internal_uncached (scaled_font,
|
||||
x, y,
|
||||
utf8,
|
||||
*glyphs,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue