summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2009-05-29 15:34:20 -0700
committerCarl Worth <cworth@cworth.org>2009-06-09 19:06:12 -0700
commitaccdbd23676d812d2345f86d8e3ee62f108841ff (patch)
treeee84363fe6b7bfef181425def153b08916da301f
parentb5e32c9cf896a0b93d193d797a8e83b4aa4691fb (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.
-rw-r--r--uxa/uxa-render.c53
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,