[PATCH] EXA: Stop hiding solid or gradient pictures from the driver.
Michel Dänzer
michel at daenzer.net
Fri Sep 4 01:24:05 PDT 2009
On Fri, 2009-09-04 at 12:59 +1000, Peter Hutterer wrote:
> On Thu, Sep 03, 2009 at 02:30:11PM +0200, Michel Dänzer wrote:
> > From: Michel Dänzer <daenzer at vmware.com>
> >
> > Add support for solid pictures in exaTryDriverSolidFill(), but otherwise just
> > pass solid and gradient pictures to the driver Composite hook.
> >
> > While we're at it, clean up the logic to detect Composite operations which are
> > effectively solid fills or copies. This should also fix some false negatives
> > and positives.
> > ---
> >
> > Daniel / Peter, is it okay if I push this for 1.7? E.g. the Gallium Xorg state
> > tracker will be able to accelerate solid and gradient pictures soon, and it
> > would be too bad if xserver 1.7 still prevented that.
> >
> > There's some potential for regressions (though I haven't found any with a
> > hacked rendercheck -t fill), but I'm confident that those could be fixed for
> > the release.
> >
> > exa/exa_render.c | 349 ++++++++++++++++++++++++++++++++----------------------
> > 1 files changed, 206 insertions(+), 143 deletions(-)
> >
> > diff --git a/exa/exa_render.c b/exa/exa_render.c
> > index 1ac29f2..1468c5c 100644
> > --- a/exa/exa_render.c
> > +++ b/exa/exa_render.c
> > @@ -77,11 +77,17 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
> > break;
> > }
> >
> > - loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
> > + if (pict->pDrawable)
> > + loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
> >
> > - snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
> > - pict->pDrawable->height, pict->repeat ?
> > - " R" : "");
> > + snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
> > + pict->pDrawable->height, pict->repeat ?
> > + " R" : "");
>
> there are { } missing from this bit, it doesn't compile. Please make sure
> that you've tested the correct version.
I did test the version I sent, but I failed to notice that
exaCompositeFallbackPictDesc is guarded by DEBUG_TRACE_FALL. Thanks for
pointing this out.
> other than that, airlied acked it, that's good enough for me.
Thanks. The updated patch below fixes the above and simplifies
exaGetRGBAFromPixel / exaGetPixelFromRGBA and their usage a bit. Unless
there are any new objections, I'm planning to push this tonight.
>From d6c2531282cba8fb6aa257674c523ab757eec5ae Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Michel=20D=C3=A4nzer?= <daenzer at vmware.com>
Date: Fri, 4 Sep 2009 10:17:42 +0200
Subject: [PATCH] EXA: Stop hiding solid or gradient pictures from the driver.
Add support for solid pictures in exaTryDriverSolidFill(), but otherwise just
pass solid and gradient pictures to the driver Composite hook.
While we're at it, clean up the logic to detect Composite operations which are
effectively solid fills or copies. This should also fix some false negatives
and positives.
---
exa/exa_render.c | 387 ++++++++++++++++++++++++++++--------------------------
1 files changed, 202 insertions(+), 185 deletions(-)
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 1ac29f2..d469301 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -77,11 +77,17 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
break;
}
- loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
+ if (pict->pDrawable) {
+ loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
- snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
- pict->pDrawable->height, pict->repeat ?
- " R" : "");
+ snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
+ pict->pDrawable->height, pict->repeat ?
+ " R" : "");
+ } else {
+ loc = '-';
+
+ snprintf(size, 20, "%s", pict->repeat ? " R" : "");
+ }
snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, size);
}
@@ -144,38 +150,26 @@ exaGetPixelFromRGBA(CARD32 *pixel,
CARD16 green,
CARD16 blue,
CARD16 alpha,
- CARD32 format)
+ PictFormatPtr pFormat)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
*pixel = 0;
- if (!PICT_FORMAT_COLOR(format))
+ if (!PICT_FORMAT_COLOR(pFormat->format) &&
+ PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
return FALSE;
- rbits = PICT_FORMAT_R(format);
- gbits = PICT_FORMAT_G(format);
- bbits = PICT_FORMAT_B(format);
- abits = PICT_FORMAT_A(format);
-
- if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
- bshift = 0;
- gshift = bbits;
- rshift = gshift + gbits;
- ashift = rshift + rbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
- rshift = 0;
- gshift = rbits;
- bshift = gshift + gbits;
- ashift = bshift + bbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
- bshift = PICT_FORMAT_BPP(format) - bbits;
- gshift = bshift - gbits;
- rshift = gshift - rbits;
- ashift = 0;
- } else
- return FALSE;
+ rbits = PICT_FORMAT_R(pFormat->format);
+ gbits = PICT_FORMAT_G(pFormat->format);
+ bbits = PICT_FORMAT_B(pFormat->format);
+ abits = PICT_FORMAT_A(pFormat->format);
+
+ rshift = pFormat->direct.red;
+ gshift = pFormat->direct.green;
+ bshift = pFormat->direct.blue;
+ ashift = pFormat->direct.alpha;
*pixel |= ( blue >> (16 - bbits)) << bshift;
*pixel |= ( red >> (16 - rbits)) << rshift;
@@ -191,36 +185,24 @@ exaGetRGBAFromPixel(CARD32 pixel,
CARD16 *green,
CARD16 *blue,
CARD16 *alpha,
- CARD32 format)
+ PictFormatPtr pFormat)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
- if (!PICT_FORMAT_COLOR(format))
+ if (!PICT_FORMAT_COLOR(pFormat->format) &&
+ PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
return FALSE;
- rbits = PICT_FORMAT_R(format);
- gbits = PICT_FORMAT_G(format);
- bbits = PICT_FORMAT_B(format);
- abits = PICT_FORMAT_A(format);
-
- if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
- bshift = 0;
- gshift = bbits;
- rshift = gshift + gbits;
- ashift = rshift + rbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
- rshift = 0;
- gshift = rbits;
- bshift = gshift + gbits;
- ashift = bshift + bbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
- bshift = PICT_FORMAT_BPP(format) - bbits;
- gshift = bshift - gbits;
- rshift = gshift - rbits;
- ashift = 0;
- } else
- return FALSE;
+ rbits = PICT_FORMAT_R(pFormat->format);
+ gbits = PICT_FORMAT_G(pFormat->format);
+ bbits = PICT_FORMAT_B(pFormat->format);
+ abits = PICT_FORMAT_A(pFormat->format);
+
+ rshift = pFormat->direct.red;
+ gshift = pFormat->direct.green;
+ bshift = pFormat->direct.blue;
+ ashift = pFormat->direct.alpha;
*red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
while (rbits < 16) {
@@ -268,27 +250,22 @@ exaTryDriverSolidFill(PicturePtr pSrc,
int nbox;
int dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pDstPix;
- ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
+ ExaPixmapPrivPtr pDstExaPix;
CARD32 pixel;
CARD16 red, green, blue, alpha;
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
-
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
pDstExaPix = ExaGetPixmapPriv(pDstPix);
- /* Check whether the accelerator can use these pixmaps.
+ /* Check whether the accelerator can use the destination pixmap.
*/
- if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked)
+ if (pDstExaPix->accel_blocked)
{
return -1;
}
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst,
xSrc, ySrc, 0, 0, xDst, yDst,
@@ -299,7 +276,23 @@ exaTryDriverSolidFill(PicturePtr pSrc,
REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y);
- pixel = exaGetPixmapFirstPixel (pSrcPix);
+ if (pSrc->pDrawable) {
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
+ pixel = exaGetPixmapFirstPixel (pSrcPix);
+ } else
+ pixel = pSrc->pSourcePict->solidFill.color;
+
+ if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
+ pSrc->pFormat) ||
+ !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
+ pDst->pFormat))
+ {
+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
+ return -1;
+ }
if (pExaScr->do_migration) {
ExaMigrationRec pixmaps[1];
@@ -316,20 +309,6 @@ exaTryDriverSolidFill(PicturePtr pSrc,
return 0;
}
- if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
- pSrc->format))
- {
- REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
- return -1;
- }
-
- if (!exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
- pDst->format))
- {
- REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
- return -1;
- }
-
if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
{
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
@@ -362,16 +341,18 @@ exaTryDriverCompositeRects(CARD8 op,
{
ExaScreenPriv (pDst->pDrawable->pScreen);
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
- PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
- ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
+ PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
+ ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
if (!pExaScr->info->PrepareComposite)
return -1;
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ if (pSrc->pDrawable) {
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ }
- if (pMask) {
+ if (pMask && pMask->pDrawable) {
pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
}
@@ -383,8 +364,9 @@ exaTryDriverCompositeRects(CARD8 op,
* FIXME: If it cannot, use temporary pixmaps so that the drawing
* happens within limits.
*/
- if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked ||
- (pMask && pMaskExaPix->accel_blocked))
+ if (pDstExaPix->accel_blocked ||
+ (pSrcExaPix && pSrcExaPix->accel_blocked) ||
+ (pMaskExaPix && pMaskExaPix->accel_blocked))
{
return -1;
}
@@ -397,37 +379,45 @@ exaTryDriverCompositeRects(CARD8 op,
if (pExaScr->do_migration) {
ExaMigrationRec pixmaps[3];
+ int i = 0;
+
+ pixmaps[i].as_dst = TRUE;
+ pixmaps[i].as_src = exaOpReadsDestination(op);
+ pixmaps[i].pPix = pDstPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+
+ if (pSrcPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pSrcPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = exaOpReadsDestination(op);
- pixmaps[0].pPix = pDstPix;
- pixmaps[0].pReg = NULL;
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pSrcPix;
- pixmaps[1].pReg = NULL;
- if (pMask) {
- pixmaps[2].as_dst = FALSE;
- pixmaps[2].as_src = TRUE;
- pixmaps[2].pPix = pMaskPix;
- pixmaps[2].pReg = NULL;
- exaDoMigration(pixmaps, 3, TRUE);
- } else
- exaDoMigration(pixmaps, 2, TRUE);
+ if (pMaskPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pMaskPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
+
+ exaDoMigration(pixmaps, i, TRUE);
}
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix)
return 0;
-
- pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
- if (!pSrcPix)
- return 0;
+ if (pSrcPix) {
+ pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+ if (!pSrcPix)
+ return 0;
+ }
- if (pMask) {
+ if (pMaskPix) {
pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y);
-
if (!pMaskPix)
return 0;
}
@@ -440,15 +430,24 @@ exaTryDriverCompositeRects(CARD8 op,
{
INT16 xDst = rects->xDst + pDst->pDrawable->x;
INT16 yDst = rects->yDst + pDst->pDrawable->y;
- INT16 xMask = pMask ? rects->xMask + pMask->pDrawable->x : 0;
- INT16 yMask = pMask ? rects->yMask + pMask->pDrawable->y : 0;
- INT16 xSrc = rects->xSrc + pSrc->pDrawable->x;
- INT16 ySrc = rects->ySrc + pSrc->pDrawable->y;
-
+ INT16 xMask = rects->xMask;
+ INT16 yMask = rects->yMask;
+ INT16 xSrc = rects->xSrc;
+ INT16 ySrc = rects->ySrc;
RegionRec region;
BoxPtr pbox;
int nbox;
-
+
+ if (pMaskPix) {
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+ }
+
+ if (pSrcPix) {
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+ }
+
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
rects->width, rects->height))
@@ -635,16 +634,18 @@ exaTryDriverComposite(CARD8 op,
BoxPtr pbox;
int nbox;
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
- PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
- ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
+ PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
+ ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ if (pSrc->pDrawable) {
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ }
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
pDstExaPix = ExaGetPixmapPriv(pDstPix);
- if (pMask) {
+ if (pMask && pMask->pDrawable) {
pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
}
@@ -653,8 +654,8 @@ exaTryDriverComposite(CARD8 op,
* FIXME: If it cannot, use temporary pixmaps so that the drawing
* happens within limits.
*/
- if (pSrcExaPix->accel_blocked ||
- pDstExaPix->accel_blocked ||
+ if (pDstExaPix->accel_blocked ||
+ (pSrcExaPix && pSrcExaPix->accel_blocked) ||
(pMask && (pMaskExaPix->accel_blocked)))
{
return -1;
@@ -663,13 +664,15 @@ exaTryDriverComposite(CARD8 op,
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
- if (pMask) {
+ if (pMaskPix) {
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
}
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
+ if (pSrcPix) {
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+ }
if (pExaScr->info->CheckComposite &&
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
@@ -688,36 +691,51 @@ exaTryDriverComposite(CARD8 op,
if (pExaScr->do_migration) {
ExaMigrationRec pixmaps[3];
+ int i = 0;
+
+ pixmaps[i].as_dst = TRUE;
+ pixmaps[i].as_src = exaOpReadsDestination(op);
+ pixmaps[i].pPix = pDstPix;
+ pixmaps[i].pReg = pixmaps[0].as_src ? NULL : ®ion;
+ i++;
+
+ if (pSrcPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pSrcPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = exaOpReadsDestination(op);
- pixmaps[0].pPix = pDstPix;
- pixmaps[0].pReg = pixmaps[0].as_src ? NULL : ®ion;
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pSrcPix;
- pixmaps[1].pReg = NULL;
- if (pMask) {
- pixmaps[2].as_dst = FALSE;
- pixmaps[2].as_src = TRUE;
- pixmaps[2].pPix = pMaskPix;
- pixmaps[2].pReg = NULL;
- exaDoMigration(pixmaps, 3, TRUE);
- } else
- exaDoMigration(pixmaps, 2, TRUE);
+ if (pMaskPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pMaskPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
+
+ exaDoMigration(pixmaps, i, TRUE);
}
- pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
- if (pMask)
+ if (pSrcPix) {
+ pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+ if (!pSrcPix) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
+ return 0;
+ }
+ }
+
+ if (pMaskPix) {
pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
&mask_off_y);
-
- if (!exaPixmapIsOffscreen(pDstPix)) {
- REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
- return 0;
+ if (!pMaskPix) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
+ return 0;
+ }
}
- if (!pSrcPix || (pMask && !pMaskPix)) {
+ if (!exaPixmapIsOffscreen(pDstPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
return 0;
}
@@ -868,45 +886,44 @@ exaComposite(CARD8 op,
Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
RegionRec region;
- /* We currently don't support acceleration of gradients, or other pictures
- * with a NULL pDrawable.
- */
- if (pExaScr->swappedOut ||
- pSrc->pDrawable == NULL || (pMask != NULL && pMask->pDrawable == NULL))
- {
+ if (pExaScr->swappedOut)
goto fallback;
- }
/* Remove repeat in source if useless */
- if (pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
+ if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
(xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
(ySrc + height) <= pSrc->pDrawable->height)
pSrc->repeat = 0;
- if (!pMask)
+ if (!pMask && !pSrc->alphaMap && !pDst->alphaMap &&
+ (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format))))
{
- if ((op == PictOpSrc &&
- ((pSrc->format == pDst->format) ||
- (pSrc->format==PICT_b8g8r8a8 && pDst->format==PICT_b8g8r8x8) ||
- (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
- (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
- (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
- pSrc->format == pDst->format &&
- (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8 ||
- pSrc->format==PICT_b8g8r8x8)))
+ if (pSrc->pDrawable ?
+ (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+ pSrc->repeat) :
+ (pSrc->pSourcePict->type == SourcePictTypeSolidFill))
{
- if (pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1 &&
- pSrc->repeat)
- {
- ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- }
- else if (pSrc->pDrawable != NULL &&
- !pSrc->repeat &&
- !pSrc->transform)
+ ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ } else if (pSrc->pDrawable && !pSrc->transform &&
+ ((op == PictOpSrc &&
+ (pSrc->format == pDst->format ||
+ (PICT_FORMAT_COLOR(pDst->format) &&
+ PICT_FORMAT_COLOR(pSrc->format) &&
+ pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format),
+ PICT_FORMAT_TYPE(pSrc->format),
+ 0,
+ PICT_FORMAT_R(pSrc->format),
+ PICT_FORMAT_G(pSrc->format),
+ PICT_FORMAT_B(pSrc->format))))) ||
+ (op == PictOpOver && pSrc->format == pDst->format &&
+ !PICT_FORMAT_A(pSrc->format))))
+ {
+ if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 &&
+ (xSrc + width <= pSrc->pDrawable->width) &&
+ (ySrc + height <= pSrc->pDrawable->height))
{
Bool ret;
xDst += pDst->pDrawable->x;
@@ -935,10 +952,9 @@ exaComposite(CARD8 op,
goto done;
}
- else if (pSrc->pDrawable != NULL &&
- pSrc->pDrawable->type == DRAWABLE_PIXMAP &&
- !pSrc->transform &&
- pSrc->repeatType == RepeatNormal)
+
+ if (pSrc->repeat && pSrc->repeatType == RepeatNormal &&
+ pSrc->pDrawable->type == DRAWABLE_PIXMAP)
{
DDXPointRec patOrg;
@@ -988,9 +1004,9 @@ exaComposite(CARD8 op,
}
/* Remove repeat in mask if useless */
- if (pMask && pMask->repeat && !pMask->transform && xMask >= 0 &&
- (xMask + width) <= pMask->pDrawable->width && yMask >= 0 &&
- (yMask + height) <= pMask->pDrawable->height)
+ if (pMask && pMask->pDrawable && pMask->repeat && !pMask->transform &&
+ xMask >= 0 && (xMask + width) <= pMask->pDrawable->width &&
+ yMask >= 0 && (yMask + height) <= pMask->pDrawable->height)
pMask->repeat = 0;
if (pExaScr->info->PrepareComposite &&
@@ -1006,9 +1022,10 @@ exaComposite(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->width == 1 &&
- pSrc->pDrawable->height == 1 &&
- pSrc->repeat;
+ isSrcSolid = pSrc->pDrawable ?
+ (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+ pSrc->repeat) :
+ (pSrc->pSourcePict->type == SourcePictTypeSolidFill);
/* 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 passes with
--
1.6.3.3
--
Earthling Michel Dänzer | http://www.vmware.com
Libre software enthusiast | Debian, X and DRI developer
More information about the xorg-devel
mailing list