[cairo] cairo_draw_with_xlib API

Robert O'Callahan rocallahan at novell.com
Thu Mar 9 12:40:31 PST 2006

[I just realized that I sent this to Carl only and not to the list.]

On Mon, 2006-02-27 at 10:06 -0800, Carl Worth wrote:
> On Mon, 27 Feb 2006 10:17:01 +1300, Robert O'Callahan wrote:
> > It's useful to distinguish "drawing will be clipped to the surface
> > extents" from other kinds of clipping: in that case, when I pass an xlib
> > surface through for direct drawing, I don't have to ask my native
> > drawing code to clip.
> Is there really any savings to making this distinction? If you do set
> an entire-surface clip region to your native code that doesn't
> actually slow anything down does it? (I've always assumed that cairo
> is the only API so messed up that asking for clipping can actually
> make things a lot slower.)

The issue is whether the native drawing code exposes a reliable clipping
interface, and what form that interface has. GTK themes take a rectangle
parameter that they're supposed to clip to, but in some cases (including
stuff like scrollbars in the default themes shipped by Red Hat and
Novell) they draw slightly outside that area. With some amount of code
restructuring we could set a clip rectangle list on the Gdk GCs that are
used, but there would probably be a performance penalty for doing that
(we've had performance problems in the past with rapidly changing Gdk GC
clipping). So we pretend that in those cases, the native drawing code
can't clip. Then, if the only clip is the entire-surface clip and the
area to be drawn intersects the surface edge (fairly common, when we're
repainting an area inside a widget), knowing that it's an entire-surface
clip lets us take the fast path instead of using a temporary surface.

Having said all that, it does sound like a litany of "ifs" and "maybes",
so maybe we shouldn't worry about it too much. Yet if we expose just
xlib surface width and height, I can still get these optimizations and
draw_with_xlib can handle really broken native drawing code. So how
about that? :-)

> The expected use for this stuff is when the user has only passed in a
> list-of-pixel-aligned-rectangle (a "region" let's say) clip anyway,
> right? So we could define the clip_as_rectangles operation in a way
> that would only be guaranteed to give useful results in such a
> case. For example, it could convert each path to its bounding region
> and then perform the intersection on those.
> Then again, this is the same criteria that determines mask-based
> clipping or not. So maybe there would be no point in storing the paths
> just to be able to return a result here that would not be accurate nor
> likely ever to be desired.


> So maybe we do just let the clip_as_rectangles stuff fail in these
> cases, (though we'll have to document that in terms of what the user
> must do---we can't just say "fails if we happen to be using a mask
> internally).

The simple implementation will always fail for PDF and similar surface
types that clip with paths instead of rectangles. I'm not sure how to
document this in a more precise way than "may fail".

> It probably was a mistake to not make a more clear API distinction
> between the two uses of cairo_clip, (clip-to-pixel-region
> vs. use-path-as-mask-for-subsequent-operations). That causes a nasty
> performance trap and also the complications we're facing here.

I don't think it was a mistake. Clip-to-pixel-region only works for
device pixel regions. The clipping API should respect the current

I think that the performance problems should be addressed by making mask
clipping work more like surface groups; drawing should be batched to a
temporary surface and composited back under the clip mask just once.


More information about the cairo mailing list