[PATCH] Bug #25136: Revert "Fix clipping when windows are used as sources"

Soeren Sandmann sandmann at daimi.au.dk
Fri Nov 27 03:33:24 PST 2009


Aaron Plattner <aplattner at nvidia.com> writes:

> That change causes lib(w)fb to make accelerated driver calls after the driver
> has entered a software fallback.  Most drivers don't expect this, which leads to
> corruption or crashes.  A change to make this code do the copy in software is
> unacceptably slow.
> 
> This reverts commit e9aa61e9f0d663d5b34a397b943b4d1df44e873d.

The issue of using windows as sources in the Render Composite request
is pretty complex:

(a) The window can be partically offscreen and partially covered by
    other windows, which means the set of pixels in it that can be
    legally accessed is a possibly complex region, not just a
    rectangle.

(b) A hardware texture sampler cannot generally clip to a complex
    region. A software texture sampler can do it, but it requires a
    pixman_region_contains_point() per pixel, which complicated the
    software code a lot and is really slow.

(c) Clipping of source pictures can be interpreted in two possible
    ways: as happening before transformation, or as happening after
    transformation. "Before" leads to something that cannot be
    implemented in hardware, and is slow in software. "After" means
    clipping by itself is not sufficient to prevent out of bounds
    access.

(d) We cannot completely ignore source clipping because there are
    applications that make use of it.

So any solution to this problem needs to answer this question:

   Suppose the window is (a) unredirected, (b) transformed, (c)
   partially offscreen, and (d) has a complex clip region.

   How do you use this window as a source, producing correct results
   while not reading outside the screen boundaries?

Copying the window to a temporary pixmap is simple and gets the right
answer in all cases, except that making accelerated callbacks from
within fb doesn't work, and that software copying is too slow for
large windows.

An alternative, if software copying is considered too slow, is to make
the texture sampler/pixman_image point at the screen pixmap, and then
adjust the transformation such that the offset of the window into the
screen pixmap is taken into account.

Reverting the copying will allow out-of-bound reads by creating a
pixman image that points outside the screen.

>      bits = (FbBits*)((CARD8*)bits +
> -		     (drawable->y + yoff) * stride * sizeof(FbBits) +
> -		     (drawable->x + xoff) * (bpp / 8));
> +		     (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
> +		     (pict->pDrawable->x + xoff) * (bpp / 8));
>  
>      image = pixman_image_create_bits (
> -	pict->format, drawable->width, drawable->height,
> +	pict->format,
> +	pict->pDrawable->width, pict->pDrawable->height,
>  	(uint32_t *)bits, stride * sizeof (FbStride));

Here, specifically. The x, y of the drawable can be negative, which
means the image created will point outside the bits, and clipping
can't fix it because it is interpreted in the "After" sense.


There is a test case here:

        http://www.daimi.au.dk/~sandmann/render-clip.c

It uses GTK+, so it should be compiled with

        gcc `pkg-config --cflags --libs gtk+-2.0` render-clip.c

Whatever the fix ends up being, if you drag the gradient window
outside the screen, you shouldn't see garbage or lockups.


Soren


More information about the xorg-devel mailing list