[cairo] I don't see the pattern
Carl Worth
cworth at cworth.org
Thu Dec 6 13:15:30 PST 2007
On Thu, 6 Dec 2007 22:17:01 +0200, Donn wrote:
> Is there any speed difference between your example and the pattern approach?
Not only is there not a speed difference, there aren't even two
different approaches.
In cairo, you only ever paint from a pattern. It *looks* like you
paint from a surface with:
cairo_set_source_surface (cr, surface, x, y);
cairo_paint (cr);
but that's really just a convenience for what is literally happening:
cairo_matrix_t matrix;
cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
cairo_matrix_init_translate (&matrix, -x, -y);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
So there's no performance difference there, (whether "you" create the
pattern or let cairo do it doesn't matter). True you could save a
single malloc by holding onto a pattern, but I doubt will be
significant.
But maybe by "pattern approach" you were asking about the notion of using
cairo_push_group;cairo_pop_group to construct your intermediate
surface and pattern? Let's see which is more convenient.
> As to using C, go for it! I'm far too thick to use it, but I can mangle it
> into Python as I need to.
Thanks. That does help. First, let's first start with a function
shell:
void
draw_cached_object (object_t *obj, cairo_t *cr)
{
cairo_save (cr);
...
cairo_restore (cr);
}
Each of the below examples could be inserted in the place of "..."
above. We assume there's a draw_object function that does the actual
drawing, (and that the object is drawn right up against the (0,0)
origin).
First, my previous example using cairo_surface_create_similar:
if (! obj->cached_surface)
{
cairo_surface_t *target = cairo_get_target (cr);
cairo_t *cr2;
obj->cached_surface = cairo_surface_create_similar (target,
CAIRO_CONTENT_COLOR_ALPHA,
obj->width, obj->height);
cr2 = cairo_create (obj->cached_surface);
draw_object (obj, cr2);
/* XXX: Should check cairo_status here */
cairo_destroy (cr2);
}
cairo_set_source_surface (cr, obj->cached_surface, obj->x, obj->y);
cairo_paint (cr);
Now let's try that again with cairo_push_group:
if (! obj->cached_pattern)
{
cairo_push_group (cr);
draw_object (obj, cr);
obj->cached_pattern = cairo_pop_group (cr);
}
cairo_set_source (cr, obj->cached_pattern);
cairo_paint (cr);
Cool! That's definitely a lot more convenient.
Potential problems though are positioning and size. With the first
approach you can change the object's position each time with the
explicit arguments to cairo_set_source_surface. In the second example,
to achieve the same result you'll have to add something more.
Also, since cairo_push_group is implicitly creating the intermediate
surface for you,you're not directly controlling its size. You can
indirectly influence that with cairo_clip first.
So here's the second example rewritten to address both of those
issues:
if (! obj->cached_pattern)
{
cairo_save (cr);
cairo_rectangle (cr, 0, 0, obj->width, obj->height);
cairo_clip (cr);
cairo_push_group (cr);
draw_object (obj, cr);
obj->cached_pattern = cairo_pop_group (cr);
cairo_restore (cr);
}
cairo_translate (cr, obj->x, obj->y);
cairo_set_source (cr, obj->cached_pattern);
cairo_paint (cr);
At that point this approach looks like a bit more typing. But it is
still simpler in not having to deal with the two intermediate
cairo_surface_t* and cairo_t* variables, (especially that ugly and
potentially confusing cr2). And avoiding an intermediate cairo_t* even
means that any error status isn't lost in the final example, (no need
to check cairo_status like in the first case).
But really none of this should have much performance impact. For the
real work that's happening, it's all the same, (unless you have a tiny
object and a huge surface and don't do the cairo_clip before
cairo_push_group).
I hope that helps, and that you keep having fun with cairo.
-Carl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20071206/0845407c/attachment.pgp
More information about the cairo
mailing list