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,&region);
>   	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,&region, xoff, yoff);
>
>   	exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST,&region);
> -    } 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,
> +				&region);
> +	}
> +    } 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,&region);
>   }
> 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