EXA: Handle separate alpha maps properly in Composite fallback.
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=18710 . As this can't work without new EXA_PREPARE_AUX* indices, this requires a major version bump, so we can also drop the UploadToScratch driver hook and ExaOffscreenSwap*(). So this also fixes http://bugs.freedesktop.org/show_bug.cgi?id=20213 . Moreover, introduce EXA_DRIVER_KNOWN_MAJOR to break compilation of drivers which may not be able to handle EXA_PREPARE_AUX*, giving instructions how to make them build again in the #error message. Signed-off-by: Michel Dänzer <daenzer@vmware.com>
This commit is contained in:
parent
d3b355875a
commit
170cf1270d
|
@ -12,7 +12,8 @@ INCLUDES = \
|
||||||
$(XORG_INCS) \
|
$(XORG_INCS) \
|
||||||
-I$(srcdir)/../miext/cw
|
-I$(srcdir)/../miext/cw
|
||||||
|
|
||||||
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
|
# Use an arbitrary high major version here to satisfy any driver checks in exa.h
|
||||||
|
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) -DEXA_DRIVER_KNOWN_MAJOR=99
|
||||||
|
|
||||||
libexa_la_SOURCES = \
|
libexa_la_SOURCES = \
|
||||||
exa.c \
|
exa.c \
|
||||||
|
|
46
exa/exa.h
46
exa/exa.h
|
@ -38,8 +38,17 @@
|
||||||
#include "picturestr.h"
|
#include "picturestr.h"
|
||||||
#include "fb.h"
|
#include "fb.h"
|
||||||
|
|
||||||
#define EXA_VERSION_MAJOR 2
|
/* If the driver can't seem to handle this major version, abort compilation with
|
||||||
#define EXA_VERSION_MINOR 4
|
* instructions how to fix it.
|
||||||
|
*/
|
||||||
|
#if !defined(EXA_DRIVER_KNOWN_MAJOR) || EXA_DRIVER_KNOWN_MAJOR < 3
|
||||||
|
#error Make sure this EXA driver either does not have Prepare/FinishAccess \
|
||||||
|
hooks or that they can handle EXA_PREPARE_AUX*, and \
|
||||||
|
#define EXA_DRIVER_KNOWN_MAJOR 3 before including exa.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EXA_VERSION_MAJOR 3
|
||||||
|
#define EXA_VERSION_MINOR 0
|
||||||
#define EXA_VERSION_RELEASE 0
|
#define EXA_VERSION_RELEASE 0
|
||||||
|
|
||||||
typedef struct _ExaOffscreenArea ExaOffscreenArea;
|
typedef struct _ExaOffscreenArea ExaOffscreenArea;
|
||||||
|
@ -498,32 +507,6 @@ typedef struct _ExaDriver {
|
||||||
char *src,
|
char *src,
|
||||||
int src_pitch);
|
int src_pitch);
|
||||||
|
|
||||||
/**
|
|
||||||
* UploadToScratch() is used to upload a pixmap to a scratch area for
|
|
||||||
* acceleration.
|
|
||||||
*
|
|
||||||
* @param pSrc source pixmap in host memory
|
|
||||||
* @param pDst fake, scratch pixmap to be set up in offscreen memory.
|
|
||||||
*
|
|
||||||
* The UploadToScratch() call was added to support Xati before Xati had
|
|
||||||
* support for hostdata uploads and before exaGlyphs() was written. It
|
|
||||||
* behaves incorrectly (uses an invalid pixmap as pDst),
|
|
||||||
* and UploadToScreen() should be implemented instead.
|
|
||||||
*
|
|
||||||
* Drivers implementing UploadToScratch() had to set up space (likely in a
|
|
||||||
* statically allocated area) in offscreen memory, copy pSrc to that
|
|
||||||
* scratch area, and adust pDst->devKind for the pitch and
|
|
||||||
* pDst->devPrivate.ptr for the pointer to that scratch area. The driver
|
|
||||||
* was responsible for syncing (as it was implemented using memcpy() in
|
|
||||||
* Xati), and only the data from the last UploadToScratch() was guaranteed
|
|
||||||
* to be valid at any given time.
|
|
||||||
*
|
|
||||||
* UploadToScratch() should not be implemented by drivers, and will likely
|
|
||||||
* be removed in a future version of EXA.
|
|
||||||
*/
|
|
||||||
Bool (*UploadToScratch) (PixmapPtr pSrc,
|
|
||||||
PixmapPtr pDst);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DownloadFromScreen() loads a rectangle of data from pSrc into dst
|
* DownloadFromScreen() loads a rectangle of data from pSrc into dst
|
||||||
*
|
*
|
||||||
|
@ -672,6 +655,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
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -285,36 +285,6 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Ejects all offscreen areas, and uninitializes the offscreen memory manager.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ExaOffscreenSwapOut (ScreenPtr pScreen)
|
|
||||||
{
|
|
||||||
ExaScreenPriv (pScreen);
|
|
||||||
|
|
||||||
ExaOffscreenValidate (pScreen);
|
|
||||||
/* loop until a single free area spans the space */
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
ExaOffscreenArea *area = pExaScr->info->offScreenAreas;
|
|
||||||
|
|
||||||
if (!area)
|
|
||||||
break;
|
|
||||||
if (area->state == ExaOffscreenAvail)
|
|
||||||
{
|
|
||||||
area = area->next;
|
|
||||||
if (!area)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert (area->state != ExaOffscreenAvail);
|
|
||||||
(void) ExaOffscreenKickOut (pScreen, area);
|
|
||||||
ExaOffscreenValidate (pScreen);
|
|
||||||
}
|
|
||||||
ExaOffscreenValidate (pScreen);
|
|
||||||
ExaOffscreenFini (pScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Ejects all pixmaps managed by EXA. */
|
/** Ejects all pixmaps managed by EXA. */
|
||||||
static void
|
static void
|
||||||
ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
|
ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
|
||||||
|
@ -344,26 +314,14 @@ ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
|
||||||
ExaOffscreenValidate (pScreen);
|
ExaOffscreenValidate (pScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ExaOffscreenSwapIn (ScreenPtr pScreen)
|
|
||||||
{
|
|
||||||
exaOffscreenInit (pScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares EXA for disabling of FB access, or restoring it.
|
* Prepares EXA for disabling of FB access, or restoring it.
|
||||||
*
|
*
|
||||||
* In version 2.1, the disabling results in pixmaps being ejected, while other
|
* The disabling results in pixmaps being ejected, while other allocations
|
||||||
* allocations remain. With this plus the prevention of migration while
|
* remain. With this plus the prevention of migration while swappedOut is
|
||||||
* swappedOut is set, EXA by itself should not cause any access of the
|
* set, EXA by itself should not cause any access of the framebuffer to occur
|
||||||
* framebuffer to occur while swapped out. Any remaining issues are the
|
* while swapped out. Any remaining issues are the responsibility of the
|
||||||
* responsibility of the driver.
|
* driver.
|
||||||
*
|
|
||||||
* Prior to version 2.1, all allocations, including locked ones, are ejected
|
|
||||||
* when access is disabled, and the allocator is torn down while swappedOut
|
|
||||||
* is set. This is more drastic, and caused implementation difficulties for
|
|
||||||
* many drivers that could otherwise handle the lack of FB access while
|
|
||||||
* swapped out.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
exaEnableDisableFBAccess (int index, Bool enable)
|
exaEnableDisableFBAccess (int index, Bool enable)
|
||||||
|
@ -372,16 +330,11 @@ exaEnableDisableFBAccess (int index, Bool enable)
|
||||||
ExaScreenPriv (pScreen);
|
ExaScreenPriv (pScreen);
|
||||||
|
|
||||||
if (!enable && pExaScr->disableFbCount++ == 0) {
|
if (!enable && pExaScr->disableFbCount++ == 0) {
|
||||||
if (pExaScr->info->exa_minor < 1)
|
ExaOffscreenEjectPixmaps (pScreen);
|
||||||
ExaOffscreenSwapOut (pScreen);
|
|
||||||
else
|
|
||||||
ExaOffscreenEjectPixmaps (pScreen);
|
|
||||||
pExaScr->swappedOut = TRUE;
|
pExaScr->swappedOut = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable && --pExaScr->disableFbCount == 0) {
|
if (enable && --pExaScr->disableFbCount == 0) {
|
||||||
if (pExaScr->info->exa_minor < 1)
|
|
||||||
ExaOffscreenSwapIn (pScreen);
|
|
||||||
pExaScr->swappedOut = FALSE;
|
pExaScr->swappedOut = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,12 +433,6 @@ ExaCheckComposite (CARD8 op,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* exa_offscreen.c */
|
/* exa_offscreen.c */
|
||||||
void
|
|
||||||
ExaOffscreenSwapOut (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
void
|
|
||||||
ExaOffscreenSwapIn (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
exaOffscreenInit(ScreenPtr pScreen);
|
exaOffscreenInit(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,6 @@ exaTryDriverCompositeRects(CARD8 op,
|
||||||
int src_off_x, src_off_y, dst_off_x, dst_off_y;
|
int src_off_x, src_off_y, dst_off_x, dst_off_y;
|
||||||
PixmapPtr pSrcPix, pDstPix;
|
PixmapPtr pSrcPix, pDstPix;
|
||||||
ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
|
ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
|
||||||
struct _Pixmap scratch;
|
|
||||||
ExaMigrationRec pixmaps[2];
|
ExaMigrationRec pixmaps[2];
|
||||||
|
|
||||||
if (!pExaScr->info->PrepareComposite)
|
if (!pExaScr->info->PrepareComposite)
|
||||||
|
@ -386,13 +385,6 @@ exaTryDriverCompositeRects(CARD8 op,
|
||||||
if (!exaPixmapIsOffscreen(pDstPix))
|
if (!exaPixmapIsOffscreen(pDstPix))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!pSrcPix && pExaScr->info->UploadToScratch)
|
|
||||||
{
|
|
||||||
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
|
||||||
if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
|
|
||||||
pSrcPix = &scratch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pSrcPix)
|
if (!pSrcPix)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -573,7 +565,6 @@ exaTryDriverComposite(CARD8 op,
|
||||||
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
|
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
|
||||||
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
|
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
|
||||||
ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
|
ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
|
||||||
struct _Pixmap scratch;
|
|
||||||
ExaMigrationRec pixmaps[3];
|
ExaMigrationRec pixmaps[3];
|
||||||
|
|
||||||
pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
|
pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
|
||||||
|
@ -652,16 +643,6 @@ exaTryDriverComposite(CARD8 op,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->UploadToScratch) {
|
|
||||||
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
|
||||||
if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
|
|
||||||
pSrcPix = &scratch;
|
|
||||||
} else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->UploadToScratch) {
|
|
||||||
pMaskPix = exaGetDrawablePixmap (pMask->pDrawable);
|
|
||||||
if ((*pExaScr->info->UploadToScratch) (pMaskPix, &scratch))
|
|
||||||
pMaskPix = &scratch;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pSrcPix || (pMask && !pMaskPix)) {
|
if (!pSrcPix || (pMask && !pMaskPix)) {
|
||||||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -405,16 +405,28 @@ ExaCheckComposite (CARD8 op,
|
||||||
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
||||||
|
|
||||||
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
|
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
|
||||||
} else
|
|
||||||
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0,
|
||||||
|
®ion);
|
||||||
|
} else {
|
||||||
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
||||||
|
|
||||||
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0);
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
if (pSrc->pDrawable != NULL)
|
if (pSrc->pDrawable != NULL)
|
||||||
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
|
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
|
||||||
|
if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
|
||||||
if (pMask && pMask->pDrawable != NULL)
|
if (pMask && pMask->pDrawable != NULL)
|
||||||
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
|
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
|
||||||
|
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
|
||||||
|
exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
swap(pExaScr, ps, Composite);
|
swap(pExaScr, ps, Composite);
|
||||||
ps->Composite (op,
|
ps->Composite (op,
|
||||||
|
@ -433,9 +445,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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@ INCLUDES = \
|
||||||
-I$(srcdir)/../../../exa \
|
-I$(srcdir)/../../../exa \
|
||||||
-I$(srcdir)/../../../miext/cw
|
-I$(srcdir)/../../../miext/cw
|
||||||
|
|
||||||
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
|
# Use an arbitrary high major version here to satisfy any driver checks in exa.h
|
||||||
|
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) -DEXA_DRIVER_KNOWN_MAJOR=99
|
||||||
|
|
||||||
libexa_la_SOURCES = \
|
libexa_la_SOURCES = \
|
||||||
examodule.c
|
examodule.c
|
||||||
|
|
Loading…
Reference in New Issue