[cairo] newbie clipping question

Owen Taylor otaylor at redhat.com
Mon Oct 16 05:01:44 PDT 2006

On Mon, 2006-10-16 at 07:29 -0400, Owen Taylor wrote:
> On Mon, 2006-10-16 at 07:54 +0200, Emmanuel Pacaud wrote:
> > Le dimanche 15 octobre 2006 à 20:52 -0400, Owen Taylor a écrit :
> > > Hmm, what sort of X server are you using? If it's older than a year
> > > or two, then the X server may be creating temporary mask the size
> > > of the primitive that you are drawing.
> > 
> > It happens on a quite recent x server (xorg 7.1.1 here).
> > It looks like most of the time is spent in the x server. On each render
> > of long line, it tries to allocate a big temporary chunk of memory.
> If you are interested in doing some code experiments, in 
> _cairo_xlib_surface_composite_trapezoids there is:
>     if (!_cairo_operator_bounded_by_mask (op)) {
>         /* XRenderCompositeTrapezoids() creates a mask only large enough for the
>          * trapezoids themselves, but if the operator is unbounded, then we need
>          * to actually composite all the way out to the bounds, so we create
>          * the mask and composite ourselves. There actually would
>          * be benefit to doing this in all cases, since RENDER implementations
>          * will frequently create a too temporary big mask, ignoring destination
>          * bounds and clip. (XRenderAddTraps() could be used to make creating
>          * the mask somewhat cheaper.)
>          */
>         Picture mask_picture = _create_trapezoid_mask (dst, traps, num_traps,
>                                                        dst_x, dst_y, width, height,
>                                                        pict_format);
> You could try taking that comment's suggestion and turning that to 'if (TRUE)'

I should mention that that change isn't the right one long-term, even if
it fixes the problem, since on older X servers it will cause two
intermediate surfaces to be created for every path drawn. Instead you'd
want something like:

 if (dst->has_add_traps || !_cairo_operator_bounded_by_mask (op)) {

And then probably change _create_trapezoid_mask() to actually use 
XRenderAddTraps() when dst->has_add_traps is set to avoid confusing
comments about the cases when the X server will optimize
XRenderCompositeTrapezoids to XRenderAddTraps internally  :-)

						- Owen

More information about the cairo mailing list