diff options
author | Carl Worth <cworth@cworth.org> | 2009-05-29 15:34:20 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2009-06-09 19:06:12 -0700 |
commit | accdbd23676d812d2345f86d8e3ee62f108841ff (patch) | |
tree | ee84363fe6b7bfef181425def153b08916da301f /uxa | |
parent | b5e32c9cf896a0b93d193d797a8e83b4aa4691fb (diff) |
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.
Diffstat (limited to 'uxa')
-rw-r--r-- | uxa/uxa-render.c | 53 |
1 files 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, |