Re: Fixed point cairo.. or no cairo?
- From: Aivars Kalvans <aivars kalvans inbox lv>
- To: Jorn Baayen <jorn openedhand com>
- Cc: performance-list gnome org
- Subject: Re: Fixed point cairo.. or no cairo?
- Date: Wed, 16 Aug 2006 00:19:17 +0000
Jorn Baayen wrote:
> On Fri, 2006-08-11 at 09:42 +0100, Michael Meeks wrote:
>
>> Is the common case of that a multiplication by a unit matrix, [ ie. a
>> no-op ;-] that could be elided if that's detectable / propagate-able ?
>> [ though it seems there is no space in 'matrix' to ram an 'unsigned int
>> is-unit : 1' into ;-) Or is it perhaps a simple scaling [ reduce by 2x
>> the muls ? ].
>>
>
> I'm not so sure. Carl?
>
Matrix with values like { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } does not
require any multiplication, because result is the same as input. Both
gstate->ctm and gstate->target->device_transform had such values when I
run your test program. This often seems to be true for "real"
applications as well (tried gedit). Sometimes x0 and y0 are not 0.0, but
for such cases we could add another workaround (x += x0, y+= y0).
Does this patch make any difference in your tests? I can't measure it
myself because cairo_matrix_transform_point() takes only a tiny fraction
of time on my laptop.
--
Aivars
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 2f9079b..fd9c9bc 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1409,6 +1409,18 @@ _cairo_gstate_glyph_extents (cairo_gstat
return CAIRO_STATUS_SUCCESS;
}
+static int
+_cairo_gstate_must_transform (cairo_matrix_t *matrix)
+{
+ static const cairo_matrix_t no_transformation = {
+ .xx = 1., .yx = 0.,
+ .xy = 0., .yy = 1.,
+ .x0 = 0., .y0 = 0.
+ };
+
+ return memcmp (matrix, &no_transformation, sizeof(no_transformation));
+}
+
cairo_status_t
_cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
cairo_glyph_t *glyphs,
@@ -1418,6 +1430,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_
cairo_pattern_union_t source_pattern;
cairo_glyph_t *transformed_glyphs;
int i;
+ int to_device, to_backend;
if (gstate->source->status)
return gstate->source->status;
@@ -1434,14 +1447,23 @@ _cairo_gstate_show_glyphs (cairo_gstate_
if (transformed_glyphs == NULL)
return CAIRO_STATUS_NO_MEMORY;
+ to_device = _cairo_gstate_must_transform (&gstate->ctm);
+ to_backend = _cairo_gstate_must_transform (&gstate->target->device_transform);
+
for (i = 0; i < num_glyphs; ++i)
{
transformed_glyphs[i].index = glyphs[i].index;
transformed_glyphs[i].x = glyphs[i].x + gstate->font_matrix.x0;
transformed_glyphs[i].y = glyphs[i].y + gstate->font_matrix.y0;
- _cairo_gstate_user_to_backend (gstate,
- &transformed_glyphs[i].x,
- &transformed_glyphs[i].y);
+
+ if (to_device)
+ cairo_matrix_transform_point (&gstate->ctm,
+ &transformed_glyphs[i].x,
+ &transformed_glyphs[i].y);
+ if (to_backend)
+ cairo_matrix_transform_point (&gstate->target->device_transform,
+ &transformed_glyphs[i].x,
+ &transformed_glyphs[i].y);
}
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]