From accdbd23676d812d2345f86d8e3ee62f108841ff Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 29 May 2009 15:34:20 -0700 Subject: [PATCH] UXA: Rasterize trapezoids to system memory, not a pixmap Since we're only doing software rasterization right now, anyway, it makes more sense to just rasterize to system memory and then upload to a pixmap once complete. This avoids expensive read-modify-write cycles. This results in a 2.4x speedup for a real-world test case that's heavy on trapezoids, which is swfdec running on the following file: http://michalevy.com/wp-content/uploads/Giant%20Steps%202007.swf Many thanks to Chris Wilson for his cairo-traces repository and cairo-perf-trace tool which makes it so easy to measure things like this. --- uxa/uxa-render.c | 53 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c index b377bf53..2d81ac44 100644 --- a/uxa/uxa-render.c +++ b/uxa/uxa-render.c @@ -897,23 +897,62 @@ uxa_trapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, PicturePtr pPicture; INT16 xDst, yDst; INT16 xRel, yRel; + int width, height, stride; + PixmapPtr pPixmap; + GCPtr pGC; + pixman_image_t *image; xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; + width = bounds.x2 - bounds.x1; + height = bounds.y2 - bounds.y1; + stride = (width * BitsPerPixel (maskFormat->depth) + 7) / 8; + pPicture = uxa_create_alpha_picture (pScreen, pDst, maskFormat, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); + width, height); if (!pPicture) return; - if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) { - for (; ntrap; ntrap--, traps++) - (*ps->RasterizeTrapezoid) (pPicture, traps, - -bounds.x1, -bounds.y1); - uxa_finish_access(pPicture->pDrawable); + image = pixman_image_create_bits (pPicture->format, + width, height, + NULL, stride); + if (!image) { + FreePicture (pPicture, 0); + return; } + for (; ntrap; ntrap--, traps++) + pixman_rasterize_trapezoid (image, (pixman_trapezoid_t *) traps, + -bounds.x1, -bounds.y1); + + pPixmap = GetScratchPixmapHeader(pScreen, width, height, + maskFormat->depth, + BitsPerPixel (maskFormat->depth), + PixmapBytePad (width, maskFormat->depth), + pixman_image_get_data (image)); + if (!pPixmap) { + FreePicture (pPicture, 0); + pixman_image_unref (image); + return; + } + + pGC = GetScratchGC (pPicture->pDrawable->depth, pScreen); + if (!pGC) + { + FreeScratchPixmapHeader (pPixmap); + pixman_image_unref (image); + FreePicture (pPicture, 0); + return; + } + + (*pGC->ops->CopyArea) (&pPixmap->drawable, pPicture->pDrawable, + pGC, 0, 0, width, height, 0, 0); + + FreeScratchGC (pGC); + FreeScratchPixmapHeader (pPixmap); + pixman_image_unref (image); + xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; CompositePicture (op, pSrc, pPicture, pDst,