EXA: Handle separate alpha maps properly in Composite fallback, take two.
Preserve the EXA ABI by introducing a new driver flag EXA_SUPPORTS_PREPARE_AUX. If the driver doesn't set this flag, we have to assume any Prepare/FinishAccess driver hooks can't handle the EXA_PREPARE_AUX* indices, so we move out such pixmaps at PrepareAccess time. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=18710 . Signed-off-by: Michel Dänzer <daenzer@vmware.com>
This commit is contained in:
parent
4bf707f018
commit
4cfb36f6ad
13
exa/exa.c
13
exa/exa.c
|
@ -538,6 +538,12 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
if (pExaScr->info->PrepareAccess == NULL)
|
if (pExaScr->info->PrepareAccess == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (index >= EXA_PREPARE_AUX0 &&
|
||||||
|
!(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
|
||||||
|
exaMoveOutPixmap (pPixmap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
|
if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
|
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
|
||||||
|
@ -597,6 +603,13 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
|
||||||
if (!exaPixmapIsOffscreen (pPixmap))
|
if (!exaPixmapIsOffscreen (pPixmap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (index >= EXA_PREPARE_AUX0 &&
|
||||||
|
!(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
|
||||||
|
ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
|
||||||
|
"unsupported index EXA_PREPARE_AUX*\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
(*pExaScr->info->FinishAccess) (pPixmap, index);
|
(*pExaScr->info->FinishAccess) (pPixmap, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
exa/exa.h
14
exa/exa.h
|
@ -672,6 +672,13 @@ typedef struct _ExaDriver {
|
||||||
* from.
|
* from.
|
||||||
*/
|
*/
|
||||||
#define EXA_PREPARE_MASK 2
|
#define EXA_PREPARE_MASK 2
|
||||||
|
/**
|
||||||
|
* EXA_PREPARE_AUX* are additional indices for other purposes, e.g.
|
||||||
|
* separate alpha maps with Composite operations.
|
||||||
|
*/
|
||||||
|
#define EXA_PREPARE_AUX0 3
|
||||||
|
#define EXA_PREPARE_AUX1 4
|
||||||
|
#define EXA_PREPARE_AUX2 5
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -742,6 +749,13 @@ typedef struct _ExaDriver {
|
||||||
*/
|
*/
|
||||||
#define EXA_HANDLES_PIXMAPS (1 << 3)
|
#define EXA_HANDLES_PIXMAPS (1 << 3)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EXA_SUPPORTS_PREPARE_AUX indicates to EXA that the driver can handle the
|
||||||
|
* EXA_PREPARE_AUX* indices in the Prepare/FinishAccess hooks. If there are no
|
||||||
|
* such hooks, this flag has no effect.
|
||||||
|
*/
|
||||||
|
#define EXA_SUPPORTS_PREPARE_AUX (1 << 4)
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/* in exa.c */
|
/* in exa.c */
|
||||||
|
|
|
@ -392,6 +392,15 @@ ExaCheckComposite (CARD8 op,
|
||||||
|
|
||||||
REGION_NULL(pScreen, ®ion);
|
REGION_NULL(pScreen, ®ion);
|
||||||
|
|
||||||
|
/* We need to prepare access to any separate alpha maps first, in case the
|
||||||
|
* driver doesn't support EXA_PREPARE_AUX*, in which case EXA_PREPARE_SRC
|
||||||
|
* may be used for moving them out.
|
||||||
|
*/
|
||||||
|
if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
|
||||||
|
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
|
||||||
|
|
||||||
if (!exaOpReadsDestination(op)) {
|
if (!exaOpReadsDestination(op)) {
|
||||||
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
|
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
|
||||||
xSrc, ySrc, xMask, yMask, xDst, yDst,
|
xSrc, ySrc, xMask, yMask, xDst, yDst,
|
||||||
|
@ -404,9 +413,17 @@ ExaCheckComposite (CARD8 op,
|
||||||
|
|
||||||
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
||||||
|
|
||||||
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0,
|
||||||
|
®ion);
|
||||||
|
|
||||||
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
|
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
|
||||||
} else
|
} else {
|
||||||
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0);
|
||||||
|
|
||||||
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
}
|
||||||
|
|
||||||
EXA_FALLBACK(("from picts %p/%p to pict %p\n",
|
EXA_FALLBACK(("from picts %p/%p to pict %p\n",
|
||||||
pSrc, pMask, pDst));
|
pSrc, pMask, pDst));
|
||||||
|
@ -433,9 +450,15 @@ ExaCheckComposite (CARD8 op,
|
||||||
#endif /* RENDER */
|
#endif /* RENDER */
|
||||||
if (pMask && pMask->pDrawable != NULL)
|
if (pMask && pMask->pDrawable != NULL)
|
||||||
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
|
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
|
||||||
|
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
|
||||||
|
exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
|
||||||
if (pSrc->pDrawable != NULL)
|
if (pSrc->pDrawable != NULL)
|
||||||
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
|
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
|
||||||
|
if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
|
||||||
|
exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
|
||||||
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
|
exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0);
|
||||||
|
|
||||||
REGION_UNINIT(pScreen, ®ion);
|
REGION_UNINIT(pScreen, ®ion);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue