summaryrefslogtreecommitdiff
path: root/uxa/uxa-render.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-12 10:53:14 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-12 12:50:31 +0100
commitd5383c2073e181b9ec352461c05d6202ad37f9d6 (patch)
treea11dbd00966f19a21334496ad344a14d17a49789 /uxa/uxa-render.c
parent00664b8f9d3da8d0d6aa53471ed3a8a8f6391660 (diff)
uxa: Avoid ping-pong with !offscreen destination and traps
If we are destined to target an !offscreen drawable, then uploading the trapezoid mask to a bo is the last thing we actually want to do... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'uxa/uxa-render.c')
-rw-r--r--uxa/uxa-render.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 16657aa2..4958dd82 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -1553,15 +1553,15 @@ uxa_create_alpha_picture(ScreenPtr pScreen,
* uxa_check_poly_fill_rect to initialize the contents.
*/
void
-uxa_trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int ntrap, xTrapezoid * traps)
{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
+ ScreenPtr screen = dst->pDrawable->pScreen;
BoxRec bounds;
- Bool direct = op == PictOpAdd && miIsSolidAlpha(pSrc);
+ Bool direct;
+ direct = op == PictOpAdd && miIsSolidAlpha(src);
if (maskFormat || direct) {
miTrapezoidBounds(ntrap, traps, &bounds);
@@ -1573,7 +1573,7 @@ uxa_trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
* Check for solid alpha add
*/
if (direct) {
- DrawablePtr pDraw = pDst->pDrawable;
+ DrawablePtr pDraw = dst->pDrawable;
PixmapPtr pixmap = uxa_get_drawable_pixmap(pDraw);
int xoff, yoff;
@@ -1583,12 +1583,15 @@ uxa_trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
yoff += pDraw->y;
if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
+ PictureScreenPtr ps = GetPictureScreen(screen);
+
for (; ntrap; ntrap--, traps++)
- (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ (*ps->RasterizeTrapezoid) (dst, traps, 0, 0);
uxa_finish_access(pDraw);
}
} else if (maskFormat) {
- PicturePtr pPicture;
+ PixmapPtr scratch = NULL;
+ PicturePtr mask;
INT16 xDst, yDst;
INT16 xRel, yRel;
int width, height;
@@ -1612,28 +1615,48 @@ uxa_trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
pixman_rasterize_trapezoid(image,
(pixman_trapezoid_t *) traps,
-bounds.x1, -bounds.y1);
-
- pPicture =
- uxa_picture_from_pixman_image(pScreen, image, format);
- pixman_image_unref(image);
- if (!pPicture)
+ if (uxa_drawable_is_offscreen(dst->pDrawable)) {
+ mask = uxa_picture_from_pixman_image(screen, image, format);
+ } else {
+ int error;
+
+ scratch = GetScratchPixmapHeader(screen, width, height,
+ PIXMAN_FORMAT_DEPTH(format),
+ PIXMAN_FORMAT_BPP(format),
+ pixman_image_get_stride(image),
+ pixman_image_get_data(image));
+ mask = CreatePicture(0, &scratch->drawable,
+ PictureMatchFormat(screen,
+ PIXMAN_FORMAT_DEPTH(format),
+ format),
+ 0, 0, serverClient, &error);
+ }
+ if (!mask) {
+ if (scratch)
+ FreeScratchPixmapHeader(scratch);
+ pixman_image_unref(image);
return;
+ }
xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst;
- CompositePicture(op, pSrc, pPicture, pDst,
+ CompositePicture(op, src, mask, dst,
xRel, yRel,
0, 0,
bounds.x1, bounds.y1,
width, height);
- FreePicture(pPicture, 0);
+ FreePicture(mask, 0);
+
+ if (scratch)
+ FreeScratchPixmapHeader(scratch);
+ pixman_image_unref(image);
} else {
- if (pDst->polyEdge == PolyEdgeSharp)
- maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
+ if (dst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat(screen, 1, PICT_a1);
else
- maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
+ maskFormat = PictureMatchFormat(screen, 8, PICT_a8);
for (; ntrap; ntrap--, traps++)
- uxa_trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ uxa_trapezoids(op, src, dst, maskFormat, xSrc, ySrc,
1, traps);
}
}