summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.c20
-rw-r--r--exa/exa_unaccel.c20
-rw-r--r--hw/xfree86/exa/Makefile.am3
7 files changed, 110 insertions, 47 deletions
diff --git a/exa/Makefile.am b/exa/Makefile.am
index 7065e197d..2b3f1e416 100644
--- a/exa/Makefile.am
+++ b/exa/Makefile.am
@@ -12,8 +12,7 @@ INCLUDES = \
$(XORG_INCS) \
-I$(srcdir)/../miext/cw
-# 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
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
libexa_la_SOURCES = \
exa.c \
diff --git a/exa/exa.h b/exa/exa.h
index b80d0d4a2..21a0f1abf 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -38,17 +38,8 @@
#include "picturestr.h"
#include "fb.h"
-/* 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_MAJOR 2
+#define EXA_VERSION_MINOR 4
#define EXA_VERSION_RELEASE 0
typedef struct _ExaOffscreenArea ExaOffscreenArea;
@@ -508,6 +499,32 @@ 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
@@ -655,13 +672,6 @@ 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 c45df6711..4aaa2c132 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -285,6 +285,36 @@ 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)
@@ -314,14 +344,26 @@ ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
ExaOffscreenValidate (pScreen);
}
+void
+ExaOffscreenSwapIn (ScreenPtr pScreen)
+{
+ exaOffscreenInit (pScreen);
+}
+
/**
* Prepares EXA for disabling of FB access, or restoring it.
*
- * 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.
+ * 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.
*/
void
exaEnableDisableFBAccess (int index, Bool enable)
@@ -330,11 +372,16 @@ exaEnableDisableFBAccess (int index, Bool enable)
ExaScreenPriv (pScreen);
if (!enable && pExaScr->disableFbCount++ == 0) {
- ExaOffscreenEjectPixmaps (pScreen);
+ if (pExaScr->info->exa_minor < 1)
+ ExaOffscreenSwapOut (pScreen);
+ else
+ 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 8f83701bf..a618fb42a 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -436,6 +436,12 @@ 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 d53f13bee..1a5d0ef5f 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -343,6 +343,7 @@ exaTryDriverCompositeRects(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];
if (!pExaScr->info->PrepareComposite)
@@ -397,6 +398,14 @@ exaTryDriverCompositeRects(CARD8 op,
return 0;
pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+
+ if (!pSrcPix && pExaScr->info->UploadToScratch)
+ {
+ pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
+ if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
+ pSrcPix = &scratch;
+ }
+
if (!pSrcPix)
return 0;
@@ -614,6 +623,7 @@ 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);
@@ -692,6 +702,16 @@ 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 0c4319f5a..c821f0da8 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -405,28 +405,16 @@ ExaCheckComposite (CARD8 op,
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
-
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0,
- &region);
- } else {
+ } 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,
@@ -445,15 +433,9 @@ 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);
}
diff --git a/hw/xfree86/exa/Makefile.am b/hw/xfree86/exa/Makefile.am
index 9fb515153..9eb2e1797 100644
--- a/hw/xfree86/exa/Makefile.am
+++ b/hw/xfree86/exa/Makefile.am
@@ -7,8 +7,7 @@ INCLUDES = \
-I$(srcdir)/../../../exa \
-I$(srcdir)/../../../miext/cw
-# 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
+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
libexa_la_SOURCES = \
examodule.c