[Pixman] Shapes, etc.

Soeren Sandmann sandmann at cs.au.dk
Wed Aug 24 06:37:33 PDT 2011


Hi,


Here are some ideas on how to improve the support in pixman for cairo's
compositing operation.  There are several separate questions related to
that:

   1. Can we support cairo's compositing operation better?

   2. Can we pass shape information to pixman more efficiently?

and a tangential third one:

   3. Should the pixman API be based on something other than images?

The TL;DR is a strawman proposal to add:

   - pixman_image_set_clip_image() 
   - support for <op>_LERP operators
   - either a polygon or a spans image


1. Can we support cairo's compositing operation better?

The first question pertains to the fact that cairo's operation is more
complex than what pixman and X Render provides. This leads to extra work
in cairo to construct the desired compositing operation.

One aspect of this is that cairo supports clipping to arbitrary shapes,
whereas pixman only supports axis aligned regions. A straightforward fix
for this is just add support for clip images:

        pixman_image_set_clip_image (pixman_image_t *image,
                                     pixman_image_t *clip);

which means that when @image is used as a destination, all rendering is
clipped to the alpha channel of @clip in addition to being clipped to
the clip region. (We need both the region and the clip image because the
X server will want to set a clip region based on the window hierarchy in
any case).

The simplest way to implement this is to have the general implementation
run an iterator for the clip image, and then pass a clip buffer to the
combiners. In addition to computing the regular operator, the combiners
would then also do LERP_clip onto the destination buffer.

        pixman_image_composite_with_clip (src, mask, dest, clip, ...)

It may also be that it would more useful to instead add a new function
that takes a clip image in addition to src, mask, and dest.

Another aspect is that cairo uses a different rendering equation in some
cases. The two equations used are:

        unbounded:   [(src IN shape) OP dest          ] LERP_clip dest

        bounded:     [(src OP dest) LERP_shape dest   ] LERP_clip dest

With shaped clips, the LERP_clip part is taken care of, and the first
equation is already directly supported by pixman. The second one could
be supported by adding new <op>_LERP operators that would use the

     (src OP dest) LERP_shape dest

equation. For cairo's purposes, all we need is CLEAR_LERP and SRC_LERP,
but I think it could be useful to have the full set of LERP operators.


2. Can we pass shape information to pixman more efficiently?

The second question is whether there is a more efficient way to pass
shape information to pixman than passing them as 8 bit alpha masks.

A polygon image is a possibility, and the one that I prefer as it allows
more processing to happen in one pass, and because it is a more compact
representation which is useful for the X protocol. There could be a
method on such an image to generate a list of spans, so that cairo
wouldn't need to maintain its own polygon rasterizer.

But passing the information as spans is another possibility. If we add
support for clip images, the obvious way to add spans support would be
through a spans image:

     pixman_image_create_spans (const pixman_span_t *spans, 
                                int                  n_spans);

that could be used both as the shape and as the clip. The initial
implementation of such an image would be very simple: just implement an
iterator that walks the list of spans, generating argb scanline buffers.

An appealing prospect here is a fast path that processes both shape and
clip in one pass. If both span lists are known to be sorted in YX order,
then they could be processed in one linear pass through both.


3. Should the pixman API be based on something other than images?

Finally, the more tangential question is whether pixman's API should be
based on image objects in the future. They tend to be a little clumsy to
use in both cairo and X. I wrote down some halfbaked ideas here:

     http://cgit.freedesktop.org/~sandmann/pixman/tree/docs/new-api?h=docs

inspired by Chris' old suggestion that pixman should behave more like a
GPU.

The gist of it is that instead of operating on image objects, there is
just one pixman_context_t that has a bunch of properties that can be
set. Once all the properties are set, the user is expected to call
pixman_context_composite().

There is also an api that allows bulk setting of properties so that an
application can submit a list of commands and pixman would then carry
them out, pretty much like a GPU would.

It could be considered a generalization of the pixman_compositor_t idea
from Chris' patch.


Comments on all three questions welcome.


Thanks,
Soren


More information about the Pixman mailing list