[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