diff options
-rw-r--r-- | exa/Makefile.am | 3 | ||||
-rw-r--r-- | exa/exa.h | 46 | ||||
-rw-r--r-- | exa/exa_offscreen.c | 59 | ||||
-rw-r--r-- | exa/exa_priv.h | 6 | ||||
-rw-r--r-- | exa/exa_render.c | 20 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 20 | ||||
-rw-r--r-- | hw/xfree86/exa/Makefile.am | 3 |
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 \ @@ -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, ®ion); 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, ®ion, xoff, yoff); exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion); - - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0, - ®ion); - } 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, ®ion); } 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 |