diff --git a/exa/exa_render.c b/exa/exa_render.c index 3974afe..654fd03 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -882,6 +882,54 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op, return 1; } +static int +exaTryDriverCompositeAnyMask(Bool maskRepeatAny, + CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + int ret; + + ret = exaTryDriverComposite(op, + pSrc, pMask, pDst, + xSrc, ySrc, + xMask, yMask, + xDst, yDst, + width, height); + if (ret == 1) + return ret; + + if (maskRepeatAny) { + int repeatType; + + pMask->repeat = 1; + for (repeatType = RepeatNormal; repeatType <= RepeatReflect; repeatType++) + { + pMask->repeatType = repeatType; + ret = exaTryDriverComposite(op, + pSrc, pMask, pDst, + xSrc, ySrc, + xMask, yMask, + xDst, yDst, + width, height); + if (ret == 1) + return ret; + } + pMask->repeat = 0; + } + + return ret; +} + void exaComposite(CARD8 op, PicturePtr pSrc, @@ -898,10 +946,12 @@ exaComposite(CARD8 op, { ExaScreenPriv (pDst->pDrawable->pScreen); int ret = -1; - Bool saveSrcRepeat = pSrc->repeat; - Bool saveMaskRepeat = pMask ? pMask->repeat : 0; + Bool saveSrcRepeat, saveMaskRepeat, srcRepeatAny, maskRepeatAny; + int saveSrcRepeatType, saveMaskRepeat; RegionRec region; + srcRepeatAny = maskRepeatAny = FALSE; + if (pExaScr->swappedOut) goto fallback; @@ -909,7 +959,12 @@ exaComposite(CARD8 op, if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 && (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 && (ySrc + height) <= pSrc->pDrawable->height) - pSrc->repeat = 0; + { + srcRepeatAny = TRUE; + saveSrcRepeat = pSrc->repeat; + saveSrcRepeatType = pSrc->repeatType; + pSrc->repeat = 0; + } if (!pMask && !pSrc->alphaMap && !pDst->alphaMap && (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format)))) @@ -1023,18 +1078,51 @@ exaComposite(CARD8 op, 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; + { + maskRepeatAny = TRUE; + saveMaskRepeat = pMask->repeat; + saveMaskRepeatType = pMask->repeatType; + pMask->repeat = 0; + } if (pExaScr->info->PrepareComposite && !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) { Bool isSrcSolid; - ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, - yMask, xDst, yDst, width, height); + ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, + xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; + ret = exaTryDriverCompositeAnyMask(maskRepeatAny, op, + pSrc, pMask, pDst, + xSrc, ySrc, + xMask, yMask, + xDst, yDst, + width, height); + if (ret == 1) + goto done; + + if (srcRepeatAny) { + int repeatType; + + pSrc->repeat = 1; + for (repeatType = RepeatNormal; repeatType <= RepeatReflect; repeatType++) + { + pSrc->repeatType = repeatType; + ret = exaTryDriverCompositeAnyMask(maskRepeatAny, op, + pSrc, pMask, pDst, + xSrc, ySrc, + xMask, yMask, + xDst, yDst, + width, height); + if (ret == 1) + goto done; + } + pSrc->repeat = 0; + } + /* For generic masks and solid src pictures, mach64 can do Over in two * passes, similar to the component-alpha case. */ @@ -1067,9 +1155,15 @@ fallback: xMask, yMask, xDst, yDst, width, height); done: - pSrc->repeat = saveSrcRepeat; - if (pMask) + if (srcRepeatAny) { + pSrc->repeat = saveSrcRepeat; + pSrc->repeatType = saveSrcRepeatType; + } + + if (maskRepeatAny) { pMask->repeat = saveMaskRepeat; + pMask->repeatType = saveMaskRepeatType; + } } /**