[cairo] cairo internal design ideas

David Reveman c99drn at cs.umu.se
Thu Sep 23 17:29:19 PDT 2004

On Thu, 2004-09-23 at 20:15 +0200, Maarten Breddels wrote: 
> David Reveman wrote:
> >>>3. Clipping is inflexible and the way it's done right now is not
> >>>efficient for all backends.
> >>>      
> >>>
> >>This is clearly a problem, but I think it should be pretty easy to fix
> >>without a major re-working of the whole interface. For example, just
> >>switching to a trapezoid-based interface rather than surface-based would
> >>help a lot, right?
> >>    
> >>
> >
> >hmm, not much. SVG and PDF backends wouldn't like it very much.
> >
> >When it comes glitz and what we can do with graphics hardware, this is
> >what I think:
> >
> >No hardware I've seen can do much more than clipping to a simple
> >rectangle. Hardware rasterization of polygons can of course be used for
> >clipping but that only works when we don't use polygon rasterization for
> >the primitives we're rendering. This means that, if we both have a set
> >of path trapezoids and a set of clip trapezoids, one of them needs to be
> >converted into a pixel mask and that's not very efficient.
> >  
> >
> Isn't glitz using the stencil buffer for clipping? If so, why not? I 
> guess it would as fast as it can possibly get.

There's no explicit clipping interface in glitz any longer. Glitz will
of course clip composite operations to the rectangle specified with
x_dst, y_dst, width and height but that's really all the clipping glitz
will do.

However, the glitz API provides something called geometry buffers that
can be thought of as a way to do clipping but it's really polygon
rasterization (this is currently used for compositing trapezoids in
cairo's glitz backend). 

A geometry buffer is a set of memory (possibly video memory) containing
OpenGL primitives, which can be assigned to a target drawable to have
all composite operations to that drawable constrained by the primitives
in the geometry buffers.

Normally geometry is done in "direct" mode, which means that geometry
primitives are used to composite the source directly to the drawable
without an intermediate buffer. This is without question the most
efficient way to render geometry with todays graphics hardware but it
requires that primitives are non-overlapping and anti-aliasing needs to
be done in hardware.

Glitz can also do geometry in "indirect" mode, which means that geometry
is rendered to an intermediate buffer and this buffer is then used as a
mask when compositing the source to the drawable. The drawable's stencil
bits are used as intermediate mask. This works with overlapping
primitives and glitz can do anti-aliasing without hardware support but
it's a lot slower. How much slower depends on the geometry we're
rendering, with a simple rectangle as geometry and using nvidia hardware
it seems to be at least 5 times slower but with geometry used by a
typical cairo application it's more like 10-50 times slower.

This is why it's so much slower:

"direct" mode have to do this:
1. one composite operation that only rasterize the pixels defined by the

"indirect" mode have to do this:
1. clear the stencil bits of the rectangular area defined by x_dst,
y_dst, width, height.
2. turn off color component writing and rasterize the primitives to
modify the stencil bits.
3. turn on color component writing and rasterize the rectangular area
defined by x_dst, y_dst, width, height and use stencil testing to only
modify pixels with modified stencil bits.

Versions of glitz with the old internal composite model had a special
clipping interface that used stencil bits. This way step 1. and 2. was
done when setting the clip and only step 3. had to be done when
rendering something. A bit more efficient but not as fast as "direct"
mode and there are also some problems with anti-aliasing when using this
solution and it of course requires stencil bits, which we might not

More information about the cairo mailing list