summaryrefslogtreecommitdiff
path: root/uxa
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-10 09:39:44 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-10 10:36:14 +0100
commitf52b6e832292c02c0010b19882e38e1097beeda0 (patch)
tree9da0d96b7d8a1917f0506095928bf5158d9e5e2f /uxa
parent848ab66384508c3ad3e5fb4884e4527f3ebd3bde (diff)
uxa: Rearrange checking and preparing of composite textures.
x11perf regression caused by 2D driver https://bugs.freedesktop.org/show_bug.cgi?id=28047 caused by commit a7b800513fcc94e063dfd68d2f63b6bab7fae47d uxa: Extract sub-region from in-memory buffers. The issue is that as we extract the region prior to checking whether the composite can in fact be accelerated, we perform expensive surplus operations. This is particularly noticeable for ComponentAlpha text, such as rgb10text. The solution here is to rearrange the check_composite() prior to acquiring the sources, and only extracting the subregion if the render path can not actually handle the texture. Performance (on PineView): a7b800513^: aa=68600 glyphs/s, rgb=29900 glyphs/s a7b800513: aa=65700 glyphs/s, rgb=13200 glyphs/s now: aa=66800 glyph/s, rgb=28800 glyphs/s The residual lossage seems to be from the extra function call and dixPrivate lookups. Hmm. More warning is the extremely low performance, however the results are consistent so the improvement looks real... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'uxa')
-rw-r--r--uxa/uxa-render.c130
-rw-r--r--uxa/uxa.h13
2 files changed, 68 insertions, 75 deletions
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 31126770..ddee1725 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -642,8 +642,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
PicturePtr pSrc,
INT16 x, INT16 y,
CARD16 width, CARD16 height,
- INT16 * out_x, INT16 * out_y,
- Bool force)
+ INT16 * out_x, INT16 * out_y)
{
PixmapPtr pPixmap;
PicturePtr pDst;
@@ -651,17 +650,17 @@ uxa_acquire_drawable(ScreenPtr pScreen,
int depth, error;
int tx, ty;
- if (!force && uxa_drawable_is_offscreen(pSrc->pDrawable)) {
- *out_x = x + pSrc->pDrawable->x;
- *out_y = y + pSrc->pDrawable->y;
- return pSrc;
- }
-
depth = pSrc->pDrawable->depth;
if (depth == 1 || !transform_is_integer_translation(pSrc->transform, &tx, &ty)) {
/* XXX extract the sample extents and do the transformation on the GPU */
pDst = uxa_render_picture(pScreen, pSrc, x, y, width, height);
goto done;
+ } else {
+ if (width == pSrc->pDrawable->width && height == pSrc->pDrawable->depth) {
+ *out_x = x + pSrc->pDrawable->x;
+ *out_y = y + pSrc->pDrawable->y;
+ return pSrc;
+ }
}
pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, 0);
@@ -671,9 +670,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
/* Skip the copy if the result remains in memory and not a bo */
if (!uxa_drawable_is_offscreen(&pPixmap->drawable)) {
pScreen->DestroyPixmap(pPixmap);
- *out_x = x + pSrc->pDrawable->x;
- *out_y = y + pSrc->pDrawable->y;
- return pSrc;
+ return 0;
}
pGC = GetScratchGC(depth, pScreen);
@@ -705,14 +702,21 @@ uxa_acquire_source(ScreenPtr pScreen,
PicturePtr pPict,
INT16 x, INT16 y,
CARD16 width, CARD16 height,
- INT16 * out_x, INT16 * out_y,
- Bool force)
+ INT16 * out_x, INT16 * out_y)
{
+ uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+ if (uxa_screen->info->check_composite_texture &&
+ uxa_screen->info->check_composite_texture(pScreen, pPict)) {
+ *out_x = x + pPict->pDrawable->x;
+ *out_y = y + pPict->pDrawable->y;
+ return pPict;
+ }
+
if (pPict->pDrawable)
return uxa_acquire_drawable(pScreen, pPict,
x, y, width, height,
- out_x, out_y,
- force);
+ out_x, out_y);
*out_x = 0;
*out_y = 0;
@@ -725,14 +729,21 @@ uxa_acquire_mask(ScreenPtr pScreen,
PicturePtr pPict,
INT16 x, INT16 y,
INT16 width, INT16 height,
- INT16 * out_x, INT16 * out_y,
- Bool force)
+ INT16 * out_x, INT16 * out_y)
{
+ uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+ if (uxa_screen->info->check_composite_texture &&
+ uxa_screen->info->check_composite_texture(pScreen, pPict)) {
+ *out_x = x + pPict->pDrawable->x;
+ *out_y = y + pPict->pDrawable->y;
+ return pPict;
+ }
+
if (pPict->pDrawable)
return uxa_acquire_drawable(pScreen, pPict,
x, y, width, height,
- out_x, out_y,
- force);
+ out_x, out_y);
*out_x = 0;
*out_y = 0;
@@ -872,12 +883,14 @@ uxa_try_driver_composite(CARD8 op,
RegionRec region;
BoxPtr pbox;
int nbox;
- INT16 _xSrc = xSrc, _ySrc = ySrc;
- INT16 _xMask = xMask, _yMask = yMask;
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
PicturePtr localSrc, localMask = NULL;
+ if (uxa_screen->info->check_composite &&
+ !(*uxa_screen->info->check_composite) (op, pSrc, pMask, pDst))
+ return -1;
+
pDstPix =
uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix)
@@ -886,18 +899,18 @@ uxa_try_driver_composite(CARD8 op,
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
- localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
- pSrc, xSrc, ySrc, width, height,
- &xSrc, &ySrc,
- FALSE);
+ localSrc = uxa_acquire_source(pDst->pDrawable->pScreen, pSrc,
+ xSrc, ySrc,
+ width, height,
+ &xSrc, &ySrc);
if (!localSrc)
return 0;
if (pMask) {
- localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
- pMask, xMask, yMask, width, height,
- &xMask, &yMask,
- FALSE);
+ localMask = uxa_acquire_mask(pDst->pDrawable->pScreen, pMask,
+ xMask, yMask,
+ width, height,
+ &xMask, &yMask);
if (!localMask) {
if (localSrc != pSrc)
FreePicture(localSrc, 0);
@@ -906,45 +919,6 @@ uxa_try_driver_composite(CARD8 op,
}
}
-recheck:
- if (uxa_screen->info->check_composite &&
- !(*uxa_screen->info->check_composite) (op, localSrc, localMask,
- pDst)) {
- if (localSrc == pSrc || (localMask && localMask == pMask)) {
- if (localSrc == pSrc) {
- localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
- pSrc, _xSrc, _ySrc, width, height,
- &xSrc, &ySrc, TRUE);
- if (!localSrc || localSrc == pSrc) {
- if (localMask && localMask != pMask)
- FreePicture(localMask, 0);
- return -(localSrc == pSrc);
- }
- }
-
- if (localMask && localMask == pMask) {
- localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
- pMask, _xMask, _yMask, width, height,
- &xMask, &yMask, TRUE);
- if (!localMask || localMask == pMask) {
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
-
- return -(localMask == pMask);
- }
- }
-
- goto recheck;
- }
-
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
- if (localMask && localMask != pMask)
- FreePicture(localMask, 0);
-
- return -1;
- }
-
if (!miComputeCompositeRegion(&region, localSrc, localMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height)) {
@@ -1306,9 +1280,15 @@ uxa_composite(CARD8 op,
/* For generic masks and solid src pictures, mach64 can do
* Over in two passes, similar to the component-alpha case.
*/
- isSrcSolid = pSrc->pDrawable &&
- pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1 && pSrc->repeat;
+
+ isSrcSolid =
+ pSrc->pDrawable ?
+ pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1 &&
+ pSrc->repeat :
+ pSrc->pSourcePict ?
+ pSrc->pSourcePict->type == SourcePictTypeSolidFill :
+ 0;
/* If we couldn't do the Composite in a single pass, and it
* was a component-alpha Over, see if we can do it in two
@@ -1320,13 +1300,13 @@ uxa_composite(CARD8 op,
uxa_try_magic_two_pass_composite_helper(op, pSrc,
pMask, pDst,
xSrc, ySrc,
- xMask,
- yMask, xDst,
- yDst, width,
- height);
+ xMask, yMask,
+ xDst, yDst,
+ width, height);
if (ret == 1)
goto done;
}
+
}
fallback:
diff --git a/uxa/uxa.h b/uxa/uxa.h
index c7e5566a..32a86a96 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -252,6 +252,19 @@ typedef struct _UxaDriver {
PicturePtr pDstPicture);
/**
+ * check_composite_texture() checks to see if a source to the composite
+ * operation can be used without midification.
+ *
+ * @param pScreen Screen
+ * @param pPicture Picture
+ *
+ * The check_composite_texture() call is recommended if prepare_composite() is
+ * implemented, but is not required.
+ */
+ Bool(*check_composite_texture) (ScreenPtr pScreen,
+ PicturePtr pPicture);
+
+ /**
* prepare_composite() sets up the driver for doing a composite
* operation described in the Render extension protocol spec.
*