diff options
author | Michel Dänzer <daenzer@vmware.com> | 2009-02-27 16:37:28 +0100 |
---|---|---|
committer | Michel Dänzer <daenzer@vmware.com> | 2009-02-27 16:37:28 +0100 |
commit | 4cfb36f6ad2df01215028fec48d99239a0e4496b (patch) | |
tree | ea547b39c0e7ab0248bed546e689c7bbd478b429 | |
parent | 4bf707f01822abe99286909fd561da7e7a4211d6 (diff) |
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>
-rw-r--r-- | exa/exa.c | 13 | ||||
-rw-r--r-- | exa/exa.h | 14 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 25 |
3 files changed, 51 insertions, 1 deletions
@@ -538,6 +538,12 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) | |||
538 | if (pExaScr->info->PrepareAccess == NULL) | 538 | if (pExaScr->info->PrepareAccess == NULL) |
539 | return; | 539 | return; |
540 | 540 | ||
541 | if (index >= EXA_PREPARE_AUX0 && | ||
542 | !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { | ||
543 | exaMoveOutPixmap (pPixmap); | ||
544 | return; | ||
545 | } | ||
546 | |||
541 | if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) { | 547 | if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) { |
542 | ExaPixmapPriv (pPixmap); | 548 | ExaPixmapPriv (pPixmap); |
543 | if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) | 549 | if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) |
@@ -597,6 +603,13 @@ exaFinishAccess(DrawablePtr pDrawable, int index) | |||
597 | if (!exaPixmapIsOffscreen (pPixmap)) | 603 | if (!exaPixmapIsOffscreen (pPixmap)) |
598 | return; | 604 | return; |
599 | 605 | ||
606 | if (index >= EXA_PREPARE_AUX0 && | ||
607 | !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { | ||
608 | ErrorF("EXA bug: Trying to call driver FinishAccess hook with " | ||
609 | "unsupported index EXA_PREPARE_AUX*\n"); | ||
610 | return; | ||
611 | } | ||
612 | |||
600 | (*pExaScr->info->FinishAccess) (pPixmap, index); | 613 | (*pExaScr->info->FinishAccess) (pPixmap, index); |
601 | } | 614 | } |
602 | 615 | ||
@@ -672,6 +672,13 @@ typedef struct _ExaDriver { | |||
672 | * from. | 672 | * from. |
673 | */ | 673 | */ |
674 | #define EXA_PREPARE_MASK 2 | 674 | #define EXA_PREPARE_MASK 2 |
675 | /** | ||
676 | * EXA_PREPARE_AUX* are additional indices for other purposes, e.g. | ||
677 | * separate alpha maps with Composite operations. | ||
678 | */ | ||
679 | #define EXA_PREPARE_AUX0 3 | ||
680 | #define EXA_PREPARE_AUX1 4 | ||
681 | #define EXA_PREPARE_AUX2 5 | ||
675 | /** @} */ | 682 | /** @} */ |
676 | 683 | ||
677 | /** | 684 | /** |
@@ -742,6 +749,13 @@ typedef struct _ExaDriver { | |||
742 | */ | 749 | */ |
743 | #define EXA_HANDLES_PIXMAPS (1 << 3) | 750 | #define EXA_HANDLES_PIXMAPS (1 << 3) |
744 | 751 | ||
752 | /** | ||
753 | * EXA_SUPPORTS_PREPARE_AUX indicates to EXA that the driver can handle the | ||
754 | * EXA_PREPARE_AUX* indices in the Prepare/FinishAccess hooks. If there are no | ||
755 | * such hooks, this flag has no effect. | ||
756 | */ | ||
757 | #define EXA_SUPPORTS_PREPARE_AUX (1 << 4) | ||
758 | |||
745 | /** @} */ | 759 | /** @} */ |
746 | 760 | ||
747 | /* in exa.c */ | 761 | /* in exa.c */ |
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index c821f0da8..9a0b0e5af 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c | |||
@@ -392,6 +392,15 @@ ExaCheckComposite (CARD8 op, | |||
392 | 392 | ||
393 | REGION_NULL(pScreen, ®ion); | 393 | REGION_NULL(pScreen, ®ion); |
394 | 394 | ||
395 | /* We need to prepare access to any separate alpha maps first, in case the | ||
396 | * driver doesn't support EXA_PREPARE_AUX*, in which case EXA_PREPARE_SRC | ||
397 | * may be used for moving them out. | ||
398 | */ | ||
399 | if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) | ||
400 | exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2); | ||
401 | if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) | ||
402 | exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1); | ||
403 | |||
395 | if (!exaOpReadsDestination(op)) { | 404 | if (!exaOpReadsDestination(op)) { |
396 | if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, | 405 | if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, |
397 | xSrc, ySrc, xMask, yMask, xDst, yDst, | 406 | xSrc, ySrc, xMask, yMask, xDst, yDst, |
@@ -404,9 +413,17 @@ ExaCheckComposite (CARD8 op, | |||
404 | 413 | ||
405 | REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); | 414 | REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); |
406 | 415 | ||
416 | if (pDst->alphaMap && pDst->alphaMap->pDrawable) | ||
417 | exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0, | ||
418 | ®ion); | ||
419 | |||
407 | exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion); | 420 | exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion); |
408 | } else | 421 | } else { |
422 | if (pDst->alphaMap && pDst->alphaMap->pDrawable) | ||
423 | exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0); | ||
424 | |||
409 | exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST); | 425 | exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST); |
426 | } | ||
410 | 427 | ||
411 | EXA_FALLBACK(("from picts %p/%p to pict %p\n", | 428 | EXA_FALLBACK(("from picts %p/%p to pict %p\n", |
412 | pSrc, pMask, pDst)); | 429 | pSrc, pMask, pDst)); |
@@ -433,9 +450,15 @@ ExaCheckComposite (CARD8 op, | |||
433 | #endif /* RENDER */ | 450 | #endif /* RENDER */ |
434 | if (pMask && pMask->pDrawable != NULL) | 451 | if (pMask && pMask->pDrawable != NULL) |
435 | exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK); | 452 | exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK); |
453 | if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) | ||
454 | exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1); | ||
436 | if (pSrc->pDrawable != NULL) | 455 | if (pSrc->pDrawable != NULL) |
437 | exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); | 456 | exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); |
457 | if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) | ||
458 | exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2); | ||
438 | exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); | 459 | exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); |
460 | if (pDst->alphaMap && pDst->alphaMap->pDrawable) | ||
461 | exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0); | ||
439 | 462 | ||
440 | REGION_UNINIT(pScreen, ®ion); | 463 | REGION_UNINIT(pScreen, ®ion); |
441 | } | 464 | } |