From 170cf1270dff38d3cce7f5ba5b940d1c0d70eff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 24 Feb 2009 09:22:09 +0100 Subject: [PATCH] EXA: Handle separate alpha maps properly in Composite fallback. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- exa/Makefile.am | 3 +- exa/exa.h | 46 ++++++++++++----------------- exa/exa_offscreen.c | 59 ++++---------------------------------- exa/exa_priv.h | 6 ---- exa/exa_render.c | 19 ------------ exa/exa_unaccel.c | 20 ++++++++++++- hw/xfree86/exa/Makefile.am | 3 +- 7 files changed, 47 insertions(+), 109 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; @@ -498,32 +507,6 @@ typedef struct _ExaDriver { char *src, 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 * @@ -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, ®ion); 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, ®ion, xoff, yoff); 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); + 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, ®ion); } diff --git a/hw/xfree86/exa/Makefile.am b/hw/xfree86/exa/Makefile.am index 9eb2e1797..9fb515153 100644 --- a/hw/xfree86/exa/Makefile.am +++ b/hw/xfree86/exa/Makefile.am @@ -7,7 +7,8 @@ INCLUDES = \ -I$(srcdir)/../../../exa \ -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 = \ examodule.c