EXA: Handle separate alpha maps in Composite fallback.
Joel Feiner
jafeiner at gmail.com
Fri Feb 27 06:45:24 PST 2009
Since this change, I haven't been able to run the X server. It
complains of a major version mismatch between libexa.so (which
supposedly has a major version of 2) and the server which expects a
major version of 3. I have done the whole make distclean && autogen.sh
rigamarole and to no avail. I have also rebuilt all of proto/ and libs/
and my drivers following the same process and it still does not work.
Is there some other dependency which needs to change? Is something
broken on your end?
Michel � wrote:
> On Sun, 2009-02-22 at 19:12 +0100, Maarten Maathuis wrote:
>> A minor bump is probably nice, the question is, should the new indices
>> be used on drivers claiming an older minor version? A major bump would
>> avoid this problem, but might be overdone?
>
> I'm afraid there isn't really a choice, I don't see any way to handle
> all possible Composite operations with separate alpha maps correctly
> without the new indices. So the patch below bumps the major version and
> drops the UploadToScratch driver hook and ExaOffscreenSwap*().
>
>
>> From cd7167f56b1259f92e4c91d398bad9452f7f8ab4 Mon Sep 17 00:00:00 2001
> From: =?utf-8?q?Michel=20D=C3=A4nzer?=<daenzer at vmware.com>
> Date: Mon, 23 Feb 2009 09:52:29 +0100
> Subject: EXA: Handle separate alpha maps 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*().
>
> Moreover, introduce EXA_DRIVER_KNOWN_MAJOR to break compilation of drivers
> which can't seem to handle EXA_PREPARE_AUX*, giving instructions how to make
> them build again in the #error message.
>
> Signed-off-by: Michel Dänzer<daenzer at vmware.com>
> ---
> 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 | 34 ++++++++++++++++++++++++-
> hw/xfree86/exa/Makefile.am | 3 +-
> 7 files changed, 61 insertions(+), 109 deletions(-)
>
> diff --git a/exa/Makefile.am b/exa/Makefile.am
> index 2b3f1e4..7065e19 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 21a0f1a..b80d0d4 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 4aaa2c1..c45df67 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 461e5e3..ea8c3da 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 1788531..bdc1ed1 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 c821f0d..88d3121 100644
> --- a/exa/exa_unaccel.c
> +++ b/exa/exa_unaccel.c
> @@ -387,6 +387,7 @@ ExaCheckComposite (CARD8 op,
> PictureScreenPtr ps = GetPictureScreen(pScreen);
> #endif /* RENDER */
> ExaScreenPriv(pScreen);
> + ExaPixmapPrivPtr pExaDstAlphaPix = NULL, pExaMaskAlphaPix = NULL, pExaSrcAlphaPix = NULL;
> RegionRec region;
> int xoff, yoff;
>
> @@ -405,16 +406,41 @@ ExaCheckComposite (CARD8 op,
> REGION_TRANSLATE(pScreen,®ion, xoff, yoff);
>
> exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST,®ion);
> - } else
> +
> + if (pDst->alphaMap&& pDst->alphaMap->pDrawable) {
> + /* The RENDER spec doesn't allow windows for separate alpha maps */
> + pExaDstAlphaPix =
> + ExaGetPixmapPriv((PixmapPtr)pDst->alphaMap->pDrawable);
> + exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX0,
> + ®ion);
> + }
> + } else {
> exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
>
> + if (pDst->alphaMap&& pDst->alphaMap->pDrawable) {
> + pExaDstAlphaPix =
> + ExaGetPixmapPriv((PixmapPtr)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) {
> + pExaSrcAlphaPix =
> + ExaGetPixmapPriv((PixmapPtr)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) {
> + pExaMaskAlphaPix =
> + ExaGetPixmapPriv((PixmapPtr)pMask->alphaMap->pDrawable);
> + exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
> + }
> #ifdef RENDER
> swap(pExaScr, ps, Composite);
> ps->Composite (op,
> @@ -433,9 +459,15 @@ ExaCheckComposite (CARD8 op,
> #endif /* RENDER */
> if (pMask&& pMask->pDrawable != NULL)
> exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
> + if (pExaMaskAlphaPix)
> + exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX1);
> if (pSrc->pDrawable != NULL)
> exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
> + if (pExaSrcAlphaPix)
> + exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX2);
> exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
> + if (pExaDstAlphaPix)
> + 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 9eb2e17..9fb5151 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
More information about the xorg-devel
mailing list