Merge branch 'master' into exa-damagetrack
Conflicts: exa/exa_accel.c exa/exa_migration.c
This commit is contained in:
@@ -12,7 +12,7 @@ INCLUDES = \
|
||||
$(XORG_INCS) \
|
||||
-I$(srcdir)/../miext/cw
|
||||
|
||||
AM_CFLAGS = $(XORG_CFLAGS) @SERVER_DEFINES@ @LOADER_DEFINES@ $(DIX_CFLAGS)
|
||||
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
|
||||
|
||||
libexa_la_SOURCES = \
|
||||
exa.c \
|
||||
|
||||
40
exa/exa.c
40
exa/exa.c
@@ -32,6 +32,10 @@
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef MITSHM
|
||||
#include "shmint.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "exa_priv.h"
|
||||
@@ -169,7 +173,7 @@ exaLog2(int val)
|
||||
{
|
||||
int bits;
|
||||
|
||||
if (!val)
|
||||
if (val <= 0)
|
||||
return 0;
|
||||
for (bits = 0; val != 0; bits++)
|
||||
val >>= 1;
|
||||
@@ -549,6 +553,9 @@ exaDriverInit (ScreenPtr pScreen,
|
||||
ExaDriverPtr pScreenInfo)
|
||||
{
|
||||
ExaScreenPrivPtr pExaScr;
|
||||
#ifdef RENDER
|
||||
PictureScreenPtr ps;
|
||||
#endif
|
||||
|
||||
if (pScreenInfo->exa_major != EXA_VERSION_MAJOR ||
|
||||
pScreenInfo->exa_minor > EXA_VERSION_MINOR)
|
||||
@@ -562,7 +569,7 @@ exaDriverInit (ScreenPtr pScreen,
|
||||
}
|
||||
|
||||
#ifdef RENDER
|
||||
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
|
||||
ps = GetPictureScreenIfSet(pScreen);
|
||||
#endif
|
||||
if (exaGeneration != serverGeneration)
|
||||
{
|
||||
@@ -629,8 +636,17 @@ exaDriverInit (ScreenPtr pScreen,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPOSITE
|
||||
miDisableCompositeWrapper(pScreen);
|
||||
#endif
|
||||
|
||||
#ifdef MITSHM
|
||||
/* Re-register with the MI funcs, which don't allow shared pixmaps.
|
||||
* Shared pixmaps are almost always a performance loss for us, but this
|
||||
* still allows for SHM PutImage.
|
||||
*/
|
||||
ShmRegisterFuncs(pScreen, NULL);
|
||||
#endif
|
||||
/*
|
||||
* Hookup offscreen pixmaps
|
||||
*/
|
||||
@@ -649,6 +665,10 @@ exaDriverInit (ScreenPtr pScreen,
|
||||
|
||||
pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
|
||||
pScreen->DestroyPixmap = exaDestroyPixmap;
|
||||
|
||||
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
|
||||
pScreen->myNum,
|
||||
pExaScr->info->memorySize - pExaScr->info->offScreenBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -667,6 +687,22 @@ exaDriverInit (ScreenPtr pScreen,
|
||||
}
|
||||
}
|
||||
|
||||
LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
|
||||
" operations:\n", pScreen->myNum);
|
||||
assert(pScreenInfo->PrepareSolid != NULL);
|
||||
LogMessage(X_INFO, " Solid\n");
|
||||
assert(pScreenInfo->PrepareCopy != NULL);
|
||||
LogMessage(X_INFO, " Copy\n");
|
||||
if (pScreenInfo->PrepareComposite != NULL) {
|
||||
LogMessage(X_INFO, " Composite (RENDER acceleration)\n");
|
||||
}
|
||||
if (pScreenInfo->UploadToScreen != NULL) {
|
||||
LogMessage(X_INFO, " UploadToScreen\n");
|
||||
}
|
||||
if (pScreenInfo->DownloadFromScreen != NULL) {
|
||||
LogMessage(X_INFO, " DownloadFromScreen\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "windowstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "picturestr.h"
|
||||
#include "fb.h"
|
||||
|
||||
#define EXA_VERSION_MAJOR 2
|
||||
#define EXA_VERSION_MINOR 0
|
||||
@@ -715,4 +716,12 @@ exaGetPixmapSize(PixmapPtr pPix);
|
||||
void
|
||||
exaEnableDisableFBAccess (int index, Bool enable);
|
||||
|
||||
/**
|
||||
* Returns TRUE if the given planemask covers all the significant bits in the
|
||||
* pixel values for pDrawable.
|
||||
*/
|
||||
#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
|
||||
(((_pm) & FbFullMask((_pDrawable)->depth)) == \
|
||||
FbFullMask((_pDrawable)->depth))
|
||||
|
||||
#endif /* EXA_H */
|
||||
|
||||
@@ -54,12 +54,12 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
if (pExaScr->swappedOut ||
|
||||
pGC->fillStyle != FillSolid ||
|
||||
pDrawable->width > pExaScr->info->maxX ||
|
||||
pDrawable->height > pExaScr->info->maxY)
|
||||
pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pPixmap->drawable.height > pExaScr->info->maxY)
|
||||
{
|
||||
exaDoMigration (pixmaps, 1, FALSE);
|
||||
ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
|
||||
@@ -393,19 +393,19 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDstDrawable);
|
||||
pixmaps[0].pPix = pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
|
||||
pixmaps[1].as_dst = FALSE;
|
||||
pixmaps[1].as_src = TRUE;
|
||||
pixmaps[1].pPix = exaGetDrawablePixmap (pSrcDrawable);
|
||||
pixmaps[1].pPix = pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
|
||||
|
||||
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
|
||||
* violate the limits. The proper solution would be a temporary pixmap
|
||||
* adjusted so that the drawing happened within limits.
|
||||
*/
|
||||
if (pSrcDrawable->width > pExaScr->info->maxX ||
|
||||
pSrcDrawable->height > pExaScr->info->maxY ||
|
||||
pDstDrawable->width > pExaScr->info->maxX ||
|
||||
pDstDrawable->height > pExaScr->info->maxY)
|
||||
if (pSrcPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pSrcPixmap->drawable.height > pExaScr->info->maxY ||
|
||||
pDstPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pDstPixmap->drawable.height > pExaScr->info->maxY)
|
||||
{
|
||||
exaDoMigration (pixmaps, 2, FALSE);
|
||||
goto fallback;
|
||||
@@ -414,7 +414,8 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||
}
|
||||
|
||||
/* Mixed directions must be handled specially if the card is lame */
|
||||
if (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS && (dx*dy) < 0) {
|
||||
if (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS &&
|
||||
reverse != upsidedown) {
|
||||
if (!exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
|
||||
dx, dy))
|
||||
goto fallback;
|
||||
@@ -424,7 +425,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||
if ((pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) &&
|
||||
(pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) &&
|
||||
(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap,
|
||||
dx, dy,
|
||||
reverse ? -1 : 1, upsidedown ? -1 : 1,
|
||||
pGC ? pGC->alu : GXcopy,
|
||||
pGC ? pGC->planemask : FB_ALLONES))
|
||||
{
|
||||
@@ -643,12 +644,12 @@ exaPolyFillRect(DrawablePtr pDrawable,
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
if (pExaScr->swappedOut ||
|
||||
pGC->fillStyle != FillSolid ||
|
||||
pDrawable->width > pExaScr->info->maxX ||
|
||||
pDrawable->height > pExaScr->info->maxY)
|
||||
pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pPixmap->drawable.height > pExaScr->info->maxY)
|
||||
{
|
||||
exaDoMigration (pixmaps, 1, FALSE);
|
||||
ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||
@@ -767,14 +768,14 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
/* We need to initialize x/yoff for tracking damage in the fallback case */
|
||||
pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
|
||||
|
||||
if (pExaScr->swappedOut ||
|
||||
pDrawable->width > pExaScr->info->maxX ||
|
||||
pDrawable->height > pExaScr->info->maxY)
|
||||
pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pPixmap->drawable.height > pExaScr->info->maxY)
|
||||
{
|
||||
exaDoMigration (pixmaps, 1, FALSE);
|
||||
goto fallback;
|
||||
@@ -1042,10 +1043,10 @@ exaFillRegionSolid (DrawablePtr pDrawable,
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
if (pDrawable->width > pExaScr->info->maxX ||
|
||||
pDrawable->height > pExaScr->info->maxY)
|
||||
if (pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pPixmap->drawable.height > pExaScr->info->maxY)
|
||||
{
|
||||
exaDoMigration (pixmaps, 1, FALSE);
|
||||
goto fallback;
|
||||
@@ -1117,7 +1118,7 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[1].as_dst = FALSE;
|
||||
pixmaps[1].as_src = TRUE;
|
||||
pixmaps[1].pPix = pTile;
|
||||
@@ -1125,8 +1126,8 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||
/* We need to initialize x/yoff for tracking damage in the fallback case */
|
||||
pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
|
||||
|
||||
if (pDrawable->width > pExaScr->info->maxX ||
|
||||
pDrawable->height > pExaScr->info->maxY ||
|
||||
if (pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||
pPixmap->drawable.height > pExaScr->info->maxY ||
|
||||
tileWidth > pExaScr->info->maxX ||
|
||||
tileHeight > pExaScr->info->maxY)
|
||||
{
|
||||
|
||||
@@ -414,7 +414,6 @@ exaOffscreenInit (ScreenPtr pScreen)
|
||||
if (!area)
|
||||
return FALSE;
|
||||
|
||||
|
||||
area->state = ExaOffscreenAvail;
|
||||
area->base_offset = pExaScr->info->offScreenBase;
|
||||
area->offset = area->base_offset;
|
||||
@@ -423,10 +422,6 @@ exaOffscreenInit (ScreenPtr pScreen)
|
||||
area->next = NULL;
|
||||
area->score = 0;
|
||||
|
||||
#if DEBUG_OFFSCREEN
|
||||
ErrorF("============ initial memory block of %d\n", area->size);
|
||||
#endif
|
||||
|
||||
/* Add it to the free areas */
|
||||
pExaScr->info->offScreenAreas = area;
|
||||
|
||||
|
||||
@@ -138,14 +138,6 @@ extern int exaPixmapPrivateIndex;
|
||||
/** Align an offset to a power-of-two alignment */
|
||||
#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
|
||||
|
||||
/**
|
||||
* Returns TRUE if the given planemask covers all the significant bits in the
|
||||
* pixel values for pDrawable.
|
||||
*/
|
||||
#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
|
||||
(((_pm) & FbFullMask((_pDrawable)->depth)) == \
|
||||
FbFullMask((_pDrawable)->depth))
|
||||
|
||||
#define EXA_PIXMAP_SCORE_MOVE_IN 10
|
||||
#define EXA_PIXMAP_SCORE_MAX 20
|
||||
#define EXA_PIXMAP_SCORE_MOVE_OUT -10
|
||||
|
||||
123
exa/exa_render.c
123
exa/exa_render.c
@@ -282,8 +282,12 @@ exaTryDriverSolidFill(PicturePtr pSrc,
|
||||
return -1;
|
||||
}
|
||||
|
||||
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
|
||||
pDst->format);
|
||||
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))
|
||||
{
|
||||
@@ -333,16 +337,21 @@ exaTryDriverComposite(CARD8 op,
|
||||
struct _Pixmap scratch;
|
||||
ExaMigrationRec pixmaps[3];
|
||||
|
||||
pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
|
||||
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
|
||||
if (pMask)
|
||||
pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
|
||||
|
||||
/* Bail if we might exceed coord limits by rendering from/to these. We
|
||||
* should really be making some scratch pixmaps with offsets and coords
|
||||
* adjusted to deal with this, but it hasn't been done yet.
|
||||
*/
|
||||
if (pSrc->pDrawable->width > pExaScr->info->maxX ||
|
||||
pSrc->pDrawable->height > pExaScr->info->maxY ||
|
||||
pDst->pDrawable->width > pExaScr->info->maxX ||
|
||||
pDst->pDrawable->height > pExaScr->info->maxY ||
|
||||
(pMask && (pMask->pDrawable->width > pExaScr->info->maxX ||
|
||||
pMask->pDrawable->height > pExaScr->info->maxY)))
|
||||
if (pSrcPix->drawable.width > pExaScr->info->maxX ||
|
||||
pSrcPix->drawable.height > pExaScr->info->maxY ||
|
||||
pDstPix->drawable.width > pExaScr->info->maxX ||
|
||||
pDstPix->drawable.height > pExaScr->info->maxY ||
|
||||
(pMask && (pMaskPix->drawable.width > pExaScr->info->maxX ||
|
||||
pMaskPix->drawable.height > pExaScr->info->maxY)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -450,24 +459,72 @@ exaTryDriverComposite(CARD8 op,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* exaTryMagicTwoPassCompositeHelper implements PictOpOver using two passes of
|
||||
* simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component
|
||||
* alpha and limited 1-tmu cards.
|
||||
*
|
||||
* From http://anholt.livejournal.com/32058.html:
|
||||
*
|
||||
* The trouble is that component-alpha rendering requires two different sources
|
||||
* for blending: one for the source value to the blender, which is the
|
||||
* per-channel multiplication of source and mask, and one for the source alpha
|
||||
* for multiplying with the destination channels, which is the multiplication
|
||||
* of the source channels by the mask alpha. So the equation for Over is:
|
||||
*
|
||||
* dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A
|
||||
* dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R
|
||||
* dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G
|
||||
* dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B
|
||||
*
|
||||
* But we can do some simpler operations, right? How about PictOpOutReverse,
|
||||
* which has a source factor of 0 and dest factor of (1 - source alpha). We
|
||||
* can get the source alpha value (srca.X = src.A * mask.X) out of the texture
|
||||
* blenders pretty easily. So we can do a component-alpha OutReverse, which
|
||||
* gets us:
|
||||
*
|
||||
* dst.A = 0 + (1 - (src.A * mask.A)) * dst.A
|
||||
* dst.R = 0 + (1 - (src.A * mask.R)) * dst.R
|
||||
* dst.G = 0 + (1 - (src.A * mask.G)) * dst.G
|
||||
* dst.B = 0 + (1 - (src.A * mask.B)) * dst.B
|
||||
*
|
||||
* OK. And if an op doesn't use the source alpha value for the destination
|
||||
* factor, then we can do the channel multiplication in the texture blenders
|
||||
* to get the source value, and ignore the source alpha that we wouldn't use.
|
||||
* We've supported this in the Radeon driver for a long time. An example would
|
||||
* be PictOpAdd, which does:
|
||||
*
|
||||
* dst.A = src.A * mask.A + dst.A
|
||||
* dst.R = src.R * mask.R + dst.R
|
||||
* dst.G = src.G * mask.G + dst.G
|
||||
* dst.B = src.B * mask.B + dst.B
|
||||
*
|
||||
* Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right
|
||||
* after it, we get:
|
||||
*
|
||||
* dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A)
|
||||
* dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R)
|
||||
* dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G)
|
||||
* dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B)
|
||||
*/
|
||||
|
||||
static int
|
||||
exaTryComponentAlphaHelper(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
exaTryMagicTwoPassCompositeHelper(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
ExaScreenPriv (pDst->pDrawable->pScreen);
|
||||
|
||||
assert(op == PictOpOver);
|
||||
assert(pMask->componentAlpha == TRUE);
|
||||
|
||||
if (pExaScr->info->CheckComposite &&
|
||||
(!(*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
|
||||
@@ -533,7 +590,8 @@ exaComposite(CARD8 op,
|
||||
if (op == PictOpSrc)
|
||||
{
|
||||
if (pSrc->pDrawable->width == 1 &&
|
||||
pSrc->pDrawable->height == 1 && pSrc->repeat)
|
||||
pSrc->pDrawable->height == 1 && pSrc->repeat &&
|
||||
pSrc->repeatType == RepeatNormal)
|
||||
{
|
||||
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
|
||||
width, height);
|
||||
@@ -573,21 +631,34 @@ exaComposite(CARD8 op,
|
||||
pMask->repeat = 0;
|
||||
|
||||
if (pExaScr->info->PrepareComposite &&
|
||||
(!pSrc->repeat || pSrc->repeat == RepeatNormal) &&
|
||||
(!pMask || !pMask->repeat || pMask->repeat == RepeatNormal) &&
|
||||
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
|
||||
{
|
||||
Bool isSrcSolid;
|
||||
|
||||
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
|
||||
yMask, xDst, yDst, width, height);
|
||||
if (ret == 1)
|
||||
goto done;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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
|
||||
* an OutReverse and then an Add.
|
||||
*/
|
||||
if (ret == -1 && pMask && pMask->componentAlpha && op == PictOpOver) {
|
||||
ret = exaTryComponentAlphaHelper(op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||
xMask, yMask, xDst, yDst,
|
||||
width, height);
|
||||
if (ret == -1 && op == PictOpOver && pMask &&
|
||||
(pMask->componentAlpha || isSrcSolid)) {
|
||||
ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
|
||||
xSrc, ySrc,
|
||||
xMask, yMask, xDst, yDst,
|
||||
width, height);
|
||||
if (ret == 1)
|
||||
goto done;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user