[Pixman] Source clipping: how-to and tests
ppaalanen at gmail.com
Mon Mar 2 23:49:32 PST 2015
On Mon, 2 Mar 2015 17:33:16 +0200
Siarhei Siamashka <siarhei.siamashka at gmail.com> wrote:
> On Mon, 2 Mar 2015 14:47:01 +0200
> Pekka Paalanen <ppaalanen at gmail.com> wrote:
> > Hi,
> > I've been trying to use source clipping in Weston's Pixman-renderer,
> > and I found something that seems strange.
> > The scenario is that I have:
> > - source clip in source image coordinates
> > - transformation (matrix)
> > - destination clip in destination coordinates
> > - potentially a mask (to apply global alpha
> > Then call pixman_image_composite32() to render.
> > Apart from the source clip everything works fine. Some special cases
> > really need a source clip, so I'm looking into that. I finally realized
> > I need all three to actually get any effect:
> > pixman_image_set_clip_region32(ps->image, &buffer_region);
> > pixman_image_set_source_clipping(ps->image, 1);
> > pixman_image_set_has_client_clip(ps->image, 1);
> > It seems that is as designed, that's ok.
> > The strange thing is that the source clip seems to be done in
> > the destination, not in the source. Is this expected?
> Yes, this is expected. Søren can probably provide better explanations
> about the rationale. But here are some old links:
thank you for the fast response. I did suspect the Pixman API behaviour
to be intricately tied to something in X11, and those pointers confirm
it. Now I know what the API intends.
> > Using source clip looks like it replaces the destination clip, instead
> > of clipping in the source image coordinate space. I'm testing with
> > Pixman 0.32.4.
> > I would really need clipping both before and after the transformation.
> > Is there a way to achieve that, or do I have to start looking into
> > trapezoids or something? (I suppose I will next look into creating a
> > mask image.)
> Can you provide a bit more details about your exact use case?
Ok, this is the simplified case from Weston. There is a pixel buffer
from a client (the window), a transformation that maps it to the output,
and the output framebuffer. The transformation can be an arbitrary 3x3
matrix, but the most complicated thing we use so far is rotating the
window on the xy-plane by an arbitrary amount.
We use the destination clipping on the framebuffer to avoid too much
useless compositing outside the source image (window). The clip
(pixman_region32_t) is essentially the intersection of the window's
boundingbox on the output and output damage we want to repaint. IOW, it
is an approximation. Currently we rely on sampling outside the source
image to produce (0,0,0,0) or skip compositing those pixels.
This works fine as long as the whole pixel buffer from the client is to
However, the client can use wl_viewport protocol interface to say, that
the compositor needs to use only a sub-rectangle of the pixel buffer.
If we don't have a complex transformation, we can transform the
rectangle to output space correctly and do all the clipping in output
If the transformation is complex, the rectangle in the client buffer
space is no longer axis-aligned in the output space, so we cannot
correctly transform it to output space. As we currently cannot do
clipping in source space, this use case is bugged. We composite areas of
the client buffer that should not be visible.
So, we need to have axis-aligned rectangles (pixman_region32_t) in the
source image space doing clipping to cut away the unwanted parts.
The underlying the problem is that we need an intersection between
axis-aligned and not-axis-aligned regions to compute the area we
actually want to paint. For instance, Weston's GL-renderer does this by
triangulating the intersection of every box vs. transformed box pair
between the two pixman_region32_t's.
> In some cases, the source image clipping might be simulated by
> just wrapping a rectangular area of an existing image as a new
> pixman_image_t. And then using it as the source image in the
> compositing operation.
That's an excellent idea! I will try that.
Btw. I did already try using a mask image, but it seems the mask image
is also given in the destination space wrt. transformation. Is that
More information about the Pixman