summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2009-02-24 09:22:09 +0100
committerMichel Dänzer <daenzer@vmware.com>2009-02-24 09:22:09 +0100
commit170cf1270dff38d3cce7f5ba5b940d1c0d70eff5 (patch)
tree3c8257191fd843070f2a9701e999d6868a775d2a /exa
parentd3b355875ac46104a174966e1974e6af99e40fd6 (diff)
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>
Diffstat (limited to 'exa')
-rw-r--r--exa/Makefile.am3
-rw-r--r--exa/exa.h46
-rw-r--r--exa/exa_offscreen.c59
-rw-r--r--exa/exa_priv.h6
-rw-r--r--exa/exa_render.c19
-rw-r--r--exa/exa_unaccel.c20
6 files changed, 45 insertions, 108 deletions
diff --git a/exa/Makefile.am b/exa/Makefile.am
index 2b3f1e416..7065e197d 100644
--- a/exa/Makefile.am
+++ b/exa/Makefile.am
@@ -12,7 +12,8 @@ INCLUDES = \
$(XORG_INCS) \
-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 = \
exa.c \
diff --git a/exa/exa.h b/exa/exa.h
index 21a0f1abf..b80d0d4a2 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -38,8 +38,17 @@
#include "picturestr.h"
#include "fb.h"
-#define EXA_VERSION_MAJOR 2
-#define EXA_VERSION_MINOR 4
+/* If the driver can't seem to handle this major version, abort compilation with
+ * 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
typedef struct _ExaOffscreenArea ExaOffscreenArea;
@@ -499,32 +508,6 @@ typedef struct _ExaDriver {
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
*
* @param pSrc source pixmap
@@ -672,6 +655,13 @@ typedef struct _ExaDriver {
* from.
*/
#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
/** @} */
/**
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 4aaa2c132..c45df6711 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -285,36 +285,6 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
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. */
static void
ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
@@ -344,26 +314,14 @@ ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
ExaOffscreenValidate (pScreen);
}
-void
-ExaOffscreenSwapIn (ScreenPtr pScreen)
-{
- exaOffscreenInit (pScreen);
-}
-
/**
* Prepares EXA for disabling of FB access, or restoring it.
*
- * In version 2.1, the disabling results in pixmaps being ejected, while other
- * allocations remain. With this plus the prevention of migration while
- * swappedOut is set, EXA by itself should not cause any access of the
- * framebuffer to occur while swapped out. Any remaining issues are the
- * responsibility of the 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.
+ * The disabling results in pixmaps being ejected, while other allocations
+ * remain. With this plus the prevention of migration while swappedOut is
+ * set, EXA by itself should not cause any access of the framebuffer to occur
+ * while swapped out. Any remaining issues are the responsibility of the
+ * driver.
*/
void
exaEnableDisableFBAccess (int index, Bool enable)
@@ -372,16 +330,11 @@ exaEnableDisableFBAccess (int index, Bool enable)
ExaScreenPriv (pScreen);
if (!enable && pExaScr->disableFbCount++ == 0) {
- if (pExaScr->info->exa_minor < 1)
- ExaOffscreenSwapOut (pScreen);
- else
- ExaOffscreenEjectPixmaps (pScreen);
+ ExaOffscreenEjectPixmaps (pScreen);
pExaScr->swappedOut = TRUE;
}
if (enable && --pExaScr->disableFbCount == 0) {
- if (pExaScr->info->exa_minor < 1)
- ExaOffscreenSwapIn (pScreen);
pExaScr->swappedOut = FALSE;
}
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 461e5e37f..ea8c3da91 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -433,12 +433,6 @@ ExaCheckComposite (CARD8 op,
#endif
/* exa_offscreen.c */
-void
-ExaOffscreenSwapOut (ScreenPtr pScreen);
-
-void
-ExaOffscreenSwapIn (ScreenPtr pScreen);
-
Bool
exaOffscreenInit(ScreenPtr pScreen);
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 17885317f..bdc1ed195 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -342,7 +342,6 @@ exaTryDriverCompositeRects(CARD8 op,
int src_off_x, src_off_y, dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pDstPix;
ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
- struct _Pixmap scratch;
ExaMigrationRec pixmaps[2];
if (!pExaScr->info->PrepareComposite)
@@ -386,13 +385,6 @@ exaTryDriverCompositeRects(CARD8 op,
if (!exaPixmapIsOffscreen(pDstPix))
return 0;
- if (!pSrcPix && pExaScr->info->UploadToScratch)
- {
- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
- if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
- pSrcPix = &scratch;
- }
-
if (!pSrcPix)
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;
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
- struct _Pixmap scratch;
ExaMigrationRec pixmaps[3];
pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
@@ -652,16 +643,6 @@ exaTryDriverComposite(CARD8 op,
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)) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0;
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index c821f0da8..0c4319f5a 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -405,16 +405,28 @@ ExaCheckComposite (CARD8 op,
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
- } else
+
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0,
+ &region);
+ } else {
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",
pSrc, pMask, pDst));
if (pSrc->pDrawable != NULL)
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
if (pMask && pMask->pDrawable != NULL)
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
#ifdef RENDER
swap(pExaScr, ps, Composite);
ps->Composite (op,
@@ -433,9 +445,15 @@ ExaCheckComposite (CARD8 op,
#endif /* RENDER */
if (pMask && pMask->pDrawable != NULL)
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
if (pSrc->pDrawable != NULL)
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);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0);
REGION_UNINIT(pScreen, &region);
}