aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/exa
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/exa')
-rw-r--r--xorg-server/exa/exa.c5
-rw-r--r--xorg-server/exa/exa_priv.h1425
-rw-r--r--xorg-server/exa/exa_unaccel.c1502
3 files changed, 1484 insertions, 1448 deletions
diff --git a/xorg-server/exa/exa.c b/xorg-server/exa/exa.c
index c16870e5d..a7bb5a29f 100644
--- a/xorg-server/exa/exa.c
+++ b/xorg-server/exa/exa.c
@@ -932,8 +932,11 @@ exaDriverInit (ScreenPtr pScreen,
if (ps) {
wrap(pExaScr, ps, Composite, exaComposite);
- if (pScreenInfo->PrepareComposite)
+ if (pScreenInfo->PrepareComposite) {
wrap(pExaScr, ps, Glyphs, exaGlyphs);
+ } else {
+ wrap(pExaScr, ps, Glyphs, ExaCheckGlyphs);
+ }
wrap(pExaScr, ps, Trapezoids, exaTrapezoids);
wrap(pExaScr, ps, Triangles, exaTriangles);
wrap(pExaScr, ps, AddTraps, ExaCheckAddTraps);
diff --git a/xorg-server/exa/exa_priv.h b/xorg-server/exa/exa_priv.h
index ed8be31f6..575d836b8 100644
--- a/xorg-server/exa/exa_priv.h
+++ b/xorg-server/exa/exa_priv.h
@@ -1,707 +1,718 @@
-/*
- *
- * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc.
- * 2005 Zack Rusin, Trolltech
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifndef EXAPRIV_H
-#define EXAPRIV_H
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "exa.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#ifdef MITSHM
-#include "shmint.h"
-#endif
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#include "mibstore.h"
-#include "colormapst.h"
-#include "gcstruct.h"
-#include "input.h"
-#include "mipointer.h"
-#include "mi.h"
-#include "dix.h"
-#include "fb.h"
-#include "fboverlay.h"
-#include "fbpict.h"
-#include "glyphstr.h"
-#include "damage.h"
-
-#define DEBUG_TRACE_FALL 0
-#define DEBUG_MIGRATE 0
-#define DEBUG_PIXMAP 0
-#define DEBUG_OFFSCREEN 0
-#define DEBUG_GLYPH_CACHE 0
-
-#if DEBUG_TRACE_FALL
-#define EXA_FALLBACK(x) \
-do { \
- ErrorF("EXA fallback at %s: ", __FUNCTION__); \
- ErrorF x; \
-} while (0)
-
-char
-exaDrawableLocation(DrawablePtr pDrawable);
-#else
-#define EXA_FALLBACK(x)
-#endif
-
-#if DEBUG_PIXMAP
-#define DBG_PIXMAP(a) ErrorF a
-#else
-#define DBG_PIXMAP(a)
-#endif
-
-#ifndef EXA_MAX_FB
-#define EXA_MAX_FB FB_OVERLAY_MAX
-#endif
-
-#ifdef DEBUG
-#define EXA_FatalErrorDebug(x) FatalError x
-#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x
-#else
-#define EXA_FatalErrorDebug(x) ErrorF x
-#define EXA_FatalErrorDebugWithRet(x, ret) \
-do { \
- ErrorF x; \
- return ret; \
-} while (0)
-#endif
-
-/**
- * This is the list of migration heuristics supported by EXA. See
- * exaDoMigration() for what their implementations do.
- */
-enum ExaMigrationHeuristic {
- ExaMigrationGreedy,
- ExaMigrationAlways,
- ExaMigrationSmart
-};
-
-typedef struct {
- unsigned char sha1[20];
-} ExaCachedGlyphRec, *ExaCachedGlyphPtr;
-
-typedef struct {
- /* The identity of the cache, statically configured at initialization */
- unsigned int format;
- int glyphWidth;
- int glyphHeight;
-
- int size; /* Size of cache; eventually this should be dynamically determined */
-
- /* Hash table mapping from glyph sha1 to position in the glyph; we use
- * open addressing with a hash table size determined based on size and large
- * enough so that we always have a good amount of free space, so we can
- * use linear probing. (Linear probing is preferrable to double hashing
- * here because it allows us to easily remove entries.)
- */
- int *hashEntries;
- int hashSize;
-
- ExaCachedGlyphPtr glyphs;
- int glyphCount; /* Current number of glyphs */
-
- PicturePtr picture; /* Where the glyphs of the cache are stored */
- int yOffset; /* y location within the picture where the cache starts */
- int columns; /* Number of columns the glyphs are layed out in */
- int evictionPosition; /* Next random position to evict a glyph */
-} ExaGlyphCacheRec, *ExaGlyphCachePtr;
-
-#define EXA_NUM_GLYPH_CACHES 4
-
-#define EXA_FALLBACK_COPYWINDOW (1 << 0)
-#define EXA_ACCEL_COPYWINDOW (1 << 1)
-
-typedef struct _ExaMigrationRec {
- Bool as_dst;
- Bool as_src;
- PixmapPtr pPix;
- RegionPtr pReg;
-} ExaMigrationRec, *ExaMigrationPtr;
-
-typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
-typedef struct {
- ExaDriverPtr info;
- ScreenBlockHandlerProcPtr SavedBlockHandler;
- ScreenWakeupHandlerProcPtr SavedWakeupHandler;
- CreateGCProcPtr SavedCreateGC;
- CloseScreenProcPtr SavedCloseScreen;
- GetImageProcPtr SavedGetImage;
- GetSpansProcPtr SavedGetSpans;
- CreatePixmapProcPtr SavedCreatePixmap;
- DestroyPixmapProcPtr SavedDestroyPixmap;
- CopyWindowProcPtr SavedCopyWindow;
- ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
- BitmapToRegionProcPtr SavedBitmapToRegion;
- CreateScreenResourcesProcPtr SavedCreateScreenResources;
- ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
- SourceValidateProcPtr SavedSourceValidate;
- CompositeProcPtr SavedComposite;
- TrianglesProcPtr SavedTriangles;
- GlyphsProcPtr SavedGlyphs;
- TrapezoidsProcPtr SavedTrapezoids;
- AddTrapsProcPtr SavedAddTraps;
- void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
- Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap);
- void (*do_move_in_pixmap) (PixmapPtr pPixmap);
- void (*do_move_out_pixmap) (PixmapPtr pPixmap);
- void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
-
- Bool swappedOut;
- enum ExaMigrationHeuristic migration;
- Bool checkDirtyCorrectness;
- unsigned disableFbCount;
- Bool optimize_migration;
- unsigned offScreenCounter;
- unsigned numOffscreenAvailable;
- CARD32 lastDefragment;
- CARD32 nextDefragment;
- PixmapPtr deferred_mixed_pixmap;
-
- /* Reference counting for accessed pixmaps */
- struct {
- PixmapPtr pixmap;
- int count;
- Bool retval;
- } access[EXA_NUM_PREPARE_INDICES];
-
- /* Holds information on fallbacks that cannot be relayed otherwise. */
- unsigned int fallback_flags;
- unsigned int fallback_counter;
-
- ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
-
- /**
- * Regions affected by fallback composite source / mask operations.
- */
-
- RegionRec srcReg;
- RegionRec maskReg;
- PixmapPtr srcPix;
-
-} ExaScreenPrivRec, *ExaScreenPrivPtr;
-
-/*
- * This is the only completely portable way to
- * compute this info.
- */
-#ifndef BitsPerPixel
-#define BitsPerPixel(d) (\
- PixmapWidthPaddingInfo[d].notPower2 ? \
- (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
- ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
- (PixmapWidthPaddingInfo[d].padRoundUp+1)))
-#endif
-
-extern DevPrivateKey exaScreenPrivateKey;
-extern DevPrivateKey exaPixmapPrivateKey;
-extern DevPrivateKey exaGCPrivateKey;
-#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey))
-#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
-
-#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixLookupPrivate(&(gc)->devPrivates, exaGCPrivateKey))
-#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
-
-/*
- * Some macros to deal with function wrapping.
- */
-#define wrap(priv, real, mem, func) {\
- priv->Saved##mem = real->mem; \
- real->mem = func; \
-}
-
-#define unwrap(priv, real, mem) {\
- real->mem = priv->Saved##mem; \
-}
-
-#define swap(priv, real, mem) {\
- void *tmp = priv->Saved##mem; \
- priv->Saved##mem = real->mem; \
- real->mem = tmp; \
-}
-
-#define EXA_PRE_FALLBACK(_screen_) \
- ExaScreenPriv(_screen_); \
- pExaScr->fallback_counter++;
-
-#define EXA_POST_FALLBACK(_screen_) \
- pExaScr->fallback_counter--;
-
-#define EXA_PRE_FALLBACK_GC(_gc_) \
- ExaScreenPriv(_gc_->pScreen); \
- ExaGCPriv(_gc_); \
- pExaScr->fallback_counter++; \
- swap(pExaGC, _gc_, ops);
-
-#define EXA_POST_FALLBACK_GC(_gc_) \
- pExaScr->fallback_counter--; \
- swap(pExaGC, _gc_, ops);
-
-/** Align an offset to an arbitrary alignment */
-#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \
- (((offset) + (align) - 1) % (align)))
-/** Align an offset to a power-of-two alignment */
-#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
-
-#define EXA_PIXMAP_SCORE_MOVE_IN 10
-#define EXA_PIXMAP_SCORE_MAX 20
-#define EXA_PIXMAP_SCORE_MOVE_OUT -10
-#define EXA_PIXMAP_SCORE_MIN -20
-#define EXA_PIXMAP_SCORE_PINNED 1000
-#define EXA_PIXMAP_SCORE_INIT 1001
-
-#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey))
-#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a)
-#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
-
-#define EXA_RANGE_PITCH (1 << 0)
-#define EXA_RANGE_WIDTH (1 << 1)
-#define EXA_RANGE_HEIGHT (1 << 2)
-
-typedef struct {
- ExaOffscreenArea *area;
- int score; /**< score for the move-in vs move-out heuristic */
- Bool use_gpu_copy;
-
- CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
- int sys_pitch; /**< pitch of pixmap in system memory */
-
- CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */
- int fb_pitch; /**< pitch of pixmap in framebuffer memory */
- unsigned int fb_size; /**< size of pixmap in framebuffer memory */
-
- /**
- * Holds information about whether this pixmap can be used for
- * acceleration (== 0) or not (> 0).
- *
- * Contains a OR'ed combination of the following values:
- * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
- * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
- * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
- */
- unsigned int accel_blocked;
-
- /**
- * The damage record contains the areas of the pixmap's current location
- * (framebuffer or system) that have been damaged compared to the other
- * location.
- */
- DamagePtr pDamage;
- /**
- * The valid regions mark the valid bits (at least, as they're derived from
- * damage, which may be overreported) of a pixmap's system and FB copies.
- */
- RegionRec validSys, validFB;
- /**
- * Driver private storage per EXA pixmap
- */
- void *driverPriv;
-} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
-
-typedef struct {
- /* GC values from the layer below. */
- GCOps *Savedops;
- GCFuncs *Savedfuncs;
-} ExaGCPrivRec, *ExaGCPrivPtr;
-
-typedef struct {
- PicturePtr pDst;
- INT16 xSrc;
- INT16 ySrc;
- INT16 xMask;
- INT16 yMask;
- INT16 xDst;
- INT16 yDst;
- INT16 width;
- INT16 height;
-} ExaCompositeRectRec, *ExaCompositeRectPtr;
-
-/**
- * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place
- * to set EXA options or hook in screen functions to handle using EXA as the AA.
- */
-void exaDDXDriverInit (ScreenPtr pScreen);
-
-/* exa_unaccel.c */
-void
-exaPrepareAccessGC(GCPtr pGC);
-
-void
-exaFinishAccessGC(GCPtr pGC);
-
-void
-ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
- DDXPointPtr ppt, int *pwidth, int fSorted);
-
-void
-ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
-
-void
-ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad, int format,
- char *bits);
-
-void
-ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
- Bool upsidedown, Pixel bitplane, void *closure);
-
-RegionPtr
-ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty);
-
-RegionPtr
-ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitPlane);
-
-void
-ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr pptInit);
-
-void
-ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt);
-
-void
-ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
- int nsegInit, xSegment *pSegInit);
-
-void
-ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *pArcs);
-
-void
-ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
- int nrect, xRectangle *prect);
-
-void
-ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
-
-void
-ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
-
-void
-ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable,
- int w, int h, int x, int y);
-
-void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
-
-void
-ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d);
-
-void
-ExaCheckGetSpans (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart);
-
-void
-ExaCheckAddTraps (PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off,
- int ntrap,
- xTrap *traps);
-
-/* exa_accel.c */
-
-static _X_INLINE Bool
-exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
- unsigned int fillStyle, unsigned char alu,
- unsigned int clientClipType)
-{
- return ((alu != GXcopy && alu != GXclear && alu != GXset &&
- alu != GXcopyInverted) || fillStyle == FillStippled ||
- clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask));
-}
-
-void
-exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
-
-Bool
-exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
- DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
- unsigned int clientClipType);
-
-void
-exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d);
-
-RegionPtr
-exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
- int srcx, int srcy, int width, int height, int dstx, int dsty);
-
-Bool
-exaHWCopyNtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown);
-
-void
-exaCopyNtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown,
- Pixel bitplane,
- void *closure);
-
-extern const GCOps exaOps;
-
-void
-ExaCheckComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-/* exa_offscreen.c */
-void
-ExaOffscreenSwapOut (ScreenPtr pScreen);
-
-void
-ExaOffscreenSwapIn (ScreenPtr pScreen);
-
-ExaOffscreenArea*
-ExaOffscreenDefragment (ScreenPtr pScreen);
-
-Bool
-exaOffscreenInit(ScreenPtr pScreen);
-
-void
-ExaOffscreenFini (ScreenPtr pScreen);
-
-/* exa.c */
-Bool
-ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
-
-void
-exaPrepareAccess(DrawablePtr pDrawable, int index);
-
-void
-exaFinishAccess(DrawablePtr pDrawable, int index);
-
-void
-exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
-
-void
-exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
- int *xp, int *yp);
-
-Bool
-exaPixmapHasGpuCopy(PixmapPtr p);
-
-PixmapPtr
-exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
-
-PixmapPtr
-exaGetDrawablePixmap(DrawablePtr pDrawable);
-
-void
-exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
- int w, int h, int bpp);
-
-void
-exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
- int w, int h, int bpp);
-
-void
-exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-
-Bool
-exaPixmapIsPinned (PixmapPtr pPix);
-
-extern const GCFuncs exaGCFuncs;
-
-/* exa_classic.c */
-PixmapPtr
-exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-
-Bool
-exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData);
-
-Bool
-exaDestroyPixmap_classic (PixmapPtr pPixmap);
-
-Bool
-exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
-
-/* exa_driver.c */
-PixmapPtr
-exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-
-Bool
-exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData);
-
-Bool
-exaDestroyPixmap_driver (PixmapPtr pPixmap);
-
-Bool
-exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
-
-/* exa_mixed.c */
-PixmapPtr
-exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-
-Bool
-exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData);
-
-Bool
-exaDestroyPixmap_mixed(PixmapPtr pPixmap);
-
-Bool
-exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
-
-/* exa_migration_mixed.c */
-void
-exaCreateDriverPixmap_mixed(PixmapPtr pPixmap);
-
-void
-exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-
-void
-exaMoveInPixmap_mixed(PixmapPtr pPixmap);
-
-void
-exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
-
-void
-exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
-
-/* exa_render.c */
-Bool
-exaOpReadsDestination (CARD8 op);
-
-void
-exaComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-void
-exaCompositeRects(CARD8 op,
- PicturePtr Src,
- PicturePtr pMask,
- PicturePtr pDst,
- int nrect,
- ExaCompositeRectPtr rects);
-
-void
-exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntrap, xTrapezoid *traps);
-
-void
-exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntri, xTriangle *tris);
-
-/* exa_glyph.c */
-void
-exaGlyphsInit(ScreenPtr pScreen);
-
-void
-exaGlyphsFini (ScreenPtr pScreen);
-
-void
-exaGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
-
-/* exa_migration_classic.c */
-void
-exaCopyDirtyToSys (ExaMigrationPtr migrate);
-
-void
-exaCopyDirtyToFb (ExaMigrationPtr migrate);
-
-void
-exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-
-void
-exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area);
-
-void
-exaMoveOutPixmap_classic (PixmapPtr pPixmap);
-
-void
-exaMoveInPixmap_classic (PixmapPtr pPixmap);
-
-void
-exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
-
-#endif /* EXAPRIV_H */
+/*
+ *
+ * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * 2005 Zack Rusin, Trolltech
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef EXAPRIV_H
+#define EXAPRIV_H
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "exa.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#ifdef MITSHM
+#include "shmint.h"
+#endif
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#include "mi.h"
+#include "dix.h"
+#include "fb.h"
+#include "fboverlay.h"
+#include "fbpict.h"
+#include "glyphstr.h"
+#include "damage.h"
+
+#define DEBUG_TRACE_FALL 0
+#define DEBUG_MIGRATE 0
+#define DEBUG_PIXMAP 0
+#define DEBUG_OFFSCREEN 0
+#define DEBUG_GLYPH_CACHE 0
+
+#if DEBUG_TRACE_FALL
+#define EXA_FALLBACK(x) \
+do { \
+ ErrorF("EXA fallback at %s: ", __FUNCTION__); \
+ ErrorF x; \
+} while (0)
+
+char
+exaDrawableLocation(DrawablePtr pDrawable);
+#else
+#define EXA_FALLBACK(x)
+#endif
+
+#if DEBUG_PIXMAP
+#define DBG_PIXMAP(a) ErrorF a
+#else
+#define DBG_PIXMAP(a)
+#endif
+
+#ifndef EXA_MAX_FB
+#define EXA_MAX_FB FB_OVERLAY_MAX
+#endif
+
+#ifdef DEBUG
+#define EXA_FatalErrorDebug(x) FatalError x
+#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x
+#else
+#define EXA_FatalErrorDebug(x) ErrorF x
+#define EXA_FatalErrorDebugWithRet(x, ret) \
+do { \
+ ErrorF x; \
+ return ret; \
+} while (0)
+#endif
+
+/**
+ * This is the list of migration heuristics supported by EXA. See
+ * exaDoMigration() for what their implementations do.
+ */
+enum ExaMigrationHeuristic {
+ ExaMigrationGreedy,
+ ExaMigrationAlways,
+ ExaMigrationSmart
+};
+
+typedef struct {
+ unsigned char sha1[20];
+} ExaCachedGlyphRec, *ExaCachedGlyphPtr;
+
+typedef struct {
+ /* The identity of the cache, statically configured at initialization */
+ unsigned int format;
+ int glyphWidth;
+ int glyphHeight;
+
+ int size; /* Size of cache; eventually this should be dynamically determined */
+
+ /* Hash table mapping from glyph sha1 to position in the glyph; we use
+ * open addressing with a hash table size determined based on size and large
+ * enough so that we always have a good amount of free space, so we can
+ * use linear probing. (Linear probing is preferrable to double hashing
+ * here because it allows us to easily remove entries.)
+ */
+ int *hashEntries;
+ int hashSize;
+
+ ExaCachedGlyphPtr glyphs;
+ int glyphCount; /* Current number of glyphs */
+
+ PicturePtr picture; /* Where the glyphs of the cache are stored */
+ int yOffset; /* y location within the picture where the cache starts */
+ int columns; /* Number of columns the glyphs are layed out in */
+ int evictionPosition; /* Next random position to evict a glyph */
+} ExaGlyphCacheRec, *ExaGlyphCachePtr;
+
+#define EXA_NUM_GLYPH_CACHES 4
+
+#define EXA_FALLBACK_COPYWINDOW (1 << 0)
+#define EXA_ACCEL_COPYWINDOW (1 << 1)
+
+typedef struct _ExaMigrationRec {
+ Bool as_dst;
+ Bool as_src;
+ PixmapPtr pPix;
+ RegionPtr pReg;
+} ExaMigrationRec, *ExaMigrationPtr;
+
+typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
+typedef struct {
+ ExaDriverPtr info;
+ ScreenBlockHandlerProcPtr SavedBlockHandler;
+ ScreenWakeupHandlerProcPtr SavedWakeupHandler;
+ CreateGCProcPtr SavedCreateGC;
+ CloseScreenProcPtr SavedCloseScreen;
+ GetImageProcPtr SavedGetImage;
+ GetSpansProcPtr SavedGetSpans;
+ CreatePixmapProcPtr SavedCreatePixmap;
+ DestroyPixmapProcPtr SavedDestroyPixmap;
+ CopyWindowProcPtr SavedCopyWindow;
+ ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
+ BitmapToRegionProcPtr SavedBitmapToRegion;
+ CreateScreenResourcesProcPtr SavedCreateScreenResources;
+ ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
+ SourceValidateProcPtr SavedSourceValidate;
+ CompositeProcPtr SavedComposite;
+ TrianglesProcPtr SavedTriangles;
+ GlyphsProcPtr SavedGlyphs;
+ TrapezoidsProcPtr SavedTrapezoids;
+ AddTrapsProcPtr SavedAddTraps;
+ void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+ Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap);
+ void (*do_move_in_pixmap) (PixmapPtr pPixmap);
+ void (*do_move_out_pixmap) (PixmapPtr pPixmap);
+ void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+ Bool swappedOut;
+ enum ExaMigrationHeuristic migration;
+ Bool checkDirtyCorrectness;
+ unsigned disableFbCount;
+ Bool optimize_migration;
+ unsigned offScreenCounter;
+ unsigned numOffscreenAvailable;
+ CARD32 lastDefragment;
+ CARD32 nextDefragment;
+ PixmapPtr deferred_mixed_pixmap;
+
+ /* Reference counting for accessed pixmaps */
+ struct {
+ PixmapPtr pixmap;
+ int count;
+ Bool retval;
+ } access[EXA_NUM_PREPARE_INDICES];
+
+ /* Holds information on fallbacks that cannot be relayed otherwise. */
+ unsigned int fallback_flags;
+ unsigned int fallback_counter;
+
+ ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
+
+ /**
+ * Regions affected by fallback composite source / mask operations.
+ */
+
+ RegionRec srcReg;
+ RegionRec maskReg;
+ PixmapPtr srcPix;
+
+} ExaScreenPrivRec, *ExaScreenPrivPtr;
+
+/*
+ * This is the only completely portable way to
+ * compute this info.
+ */
+#ifndef BitsPerPixel
+#define BitsPerPixel(d) (\
+ PixmapWidthPaddingInfo[d].notPower2 ? \
+ (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
+ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1)))
+#endif
+
+extern DevPrivateKey exaScreenPrivateKey;
+extern DevPrivateKey exaPixmapPrivateKey;
+extern DevPrivateKey exaGCPrivateKey;
+#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey))
+#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
+
+#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixLookupPrivate(&(gc)->devPrivates, exaGCPrivateKey))
+#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
+
+/*
+ * Some macros to deal with function wrapping.
+ */
+#define wrap(priv, real, mem, func) {\
+ priv->Saved##mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->Saved##mem; \
+}
+
+#define swap(priv, real, mem) {\
+ void *tmp = priv->Saved##mem; \
+ priv->Saved##mem = real->mem; \
+ real->mem = tmp; \
+}
+
+#define EXA_PRE_FALLBACK(_screen_) \
+ ExaScreenPriv(_screen_); \
+ pExaScr->fallback_counter++;
+
+#define EXA_POST_FALLBACK(_screen_) \
+ pExaScr->fallback_counter--;
+
+#define EXA_PRE_FALLBACK_GC(_gc_) \
+ ExaScreenPriv(_gc_->pScreen); \
+ ExaGCPriv(_gc_); \
+ pExaScr->fallback_counter++; \
+ swap(pExaGC, _gc_, ops);
+
+#define EXA_POST_FALLBACK_GC(_gc_) \
+ pExaScr->fallback_counter--; \
+ swap(pExaGC, _gc_, ops);
+
+/** Align an offset to an arbitrary alignment */
+#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \
+ (((offset) + (align) - 1) % (align)))
+/** Align an offset to a power-of-two alignment */
+#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
+
+#define EXA_PIXMAP_SCORE_MOVE_IN 10
+#define EXA_PIXMAP_SCORE_MAX 20
+#define EXA_PIXMAP_SCORE_MOVE_OUT -10
+#define EXA_PIXMAP_SCORE_MIN -20
+#define EXA_PIXMAP_SCORE_PINNED 1000
+#define EXA_PIXMAP_SCORE_INIT 1001
+
+#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey))
+#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a)
+#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
+
+#define EXA_RANGE_PITCH (1 << 0)
+#define EXA_RANGE_WIDTH (1 << 1)
+#define EXA_RANGE_HEIGHT (1 << 2)
+
+typedef struct {
+ ExaOffscreenArea *area;
+ int score; /**< score for the move-in vs move-out heuristic */
+ Bool use_gpu_copy;
+
+ CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
+ int sys_pitch; /**< pitch of pixmap in system memory */
+
+ CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */
+ int fb_pitch; /**< pitch of pixmap in framebuffer memory */
+ unsigned int fb_size; /**< size of pixmap in framebuffer memory */
+
+ /**
+ * Holds information about whether this pixmap can be used for
+ * acceleration (== 0) or not (> 0).
+ *
+ * Contains a OR'ed combination of the following values:
+ * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
+ * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
+ * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
+ */
+ unsigned int accel_blocked;
+
+ /**
+ * The damage record contains the areas of the pixmap's current location
+ * (framebuffer or system) that have been damaged compared to the other
+ * location.
+ */
+ DamagePtr pDamage;
+ /**
+ * The valid regions mark the valid bits (at least, as they're derived from
+ * damage, which may be overreported) of a pixmap's system and FB copies.
+ */
+ RegionRec validSys, validFB;
+ /**
+ * Driver private storage per EXA pixmap
+ */
+ void *driverPriv;
+} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
+
+typedef struct {
+ /* GC values from the layer below. */
+ GCOps *Savedops;
+ GCFuncs *Savedfuncs;
+} ExaGCPrivRec, *ExaGCPrivPtr;
+
+typedef struct {
+ PicturePtr pDst;
+ INT16 xSrc;
+ INT16 ySrc;
+ INT16 xMask;
+ INT16 yMask;
+ INT16 xDst;
+ INT16 yDst;
+ INT16 width;
+ INT16 height;
+} ExaCompositeRectRec, *ExaCompositeRectPtr;
+
+/**
+ * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place
+ * to set EXA options or hook in screen functions to handle using EXA as the AA.
+ */
+void exaDDXDriverInit (ScreenPtr pScreen);
+
+/* exa_unaccel.c */
+void
+exaPrepareAccessGC(GCPtr pGC);
+
+void
+exaFinishAccessGC(GCPtr pGC);
+
+void
+ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+
+void
+ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+
+void
+ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits);
+
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure);
+
+RegionPtr
+ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty);
+
+RegionPtr
+ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane);
+
+void
+ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+
+void
+ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt);
+
+void
+ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit);
+
+void
+ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs);
+
+void
+ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect);
+
+void
+ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+
+void
+ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+
+void
+ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y);
+
+void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+void
+ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+void
+ExaCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart);
+
+void
+ExaCheckAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps);
+
+/* exa_accel.c */
+
+static _X_INLINE Bool
+exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
+ unsigned int fillStyle, unsigned char alu,
+ unsigned int clientClipType)
+{
+ return ((alu != GXcopy && alu != GXclear && alu != GXset &&
+ alu != GXcopyInverted) || fillStyle == FillStippled ||
+ clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask));
+}
+
+void
+exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+Bool
+exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType);
+
+void
+exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+RegionPtr
+exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty);
+
+Bool
+exaHWCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown);
+
+void
+exaCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+extern const GCOps exaOps;
+
+void
+ExaCheckComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+ExaCheckGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+/* exa_offscreen.c */
+void
+ExaOffscreenSwapOut (ScreenPtr pScreen);
+
+void
+ExaOffscreenSwapIn (ScreenPtr pScreen);
+
+ExaOffscreenArea*
+ExaOffscreenDefragment (ScreenPtr pScreen);
+
+Bool
+exaOffscreenInit(ScreenPtr pScreen);
+
+void
+ExaOffscreenFini (ScreenPtr pScreen);
+
+/* exa.c */
+Bool
+ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
+
+void
+exaPrepareAccess(DrawablePtr pDrawable, int index);
+
+void
+exaFinishAccess(DrawablePtr pDrawable, int index);
+
+void
+exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
+
+void
+exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
+ int *xp, int *yp);
+
+Bool
+exaPixmapHasGpuCopy(PixmapPtr p);
+
+PixmapPtr
+exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
+
+PixmapPtr
+exaGetDrawablePixmap(DrawablePtr pDrawable);
+
+void
+exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
+ int w, int h, int bpp);
+
+void
+exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
+ int w, int h, int bpp);
+
+void
+exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+
+Bool
+exaPixmapIsPinned (PixmapPtr pPix);
+
+extern const GCFuncs exaGCFuncs;
+
+/* exa_classic.c */
+PixmapPtr
+exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+
+Bool
+exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData);
+
+Bool
+exaDestroyPixmap_classic (PixmapPtr pPixmap);
+
+Bool
+exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
+
+/* exa_driver.c */
+PixmapPtr
+exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+
+Bool
+exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData);
+
+Bool
+exaDestroyPixmap_driver (PixmapPtr pPixmap);
+
+Bool
+exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
+
+/* exa_mixed.c */
+PixmapPtr
+exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+
+Bool
+exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData);
+
+Bool
+exaDestroyPixmap_mixed(PixmapPtr pPixmap);
+
+Bool
+exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
+
+/* exa_migration_mixed.c */
+void
+exaCreateDriverPixmap_mixed(PixmapPtr pPixmap);
+
+void
+exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+
+void
+exaMoveInPixmap_mixed(PixmapPtr pPixmap);
+
+void
+exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
+
+void
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+/* exa_render.c */
+Bool
+exaOpReadsDestination (CARD8 op);
+
+void
+exaComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+exaCompositeRects(CARD8 op,
+ PicturePtr Src,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ int nrect,
+ ExaCompositeRectPtr rects);
+
+void
+exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps);
+
+void
+exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tris);
+
+/* exa_glyph.c */
+void
+exaGlyphsInit(ScreenPtr pScreen);
+
+void
+exaGlyphsFini (ScreenPtr pScreen);
+
+void
+exaGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+/* exa_migration_classic.c */
+void
+exaCopyDirtyToSys (ExaMigrationPtr migrate);
+
+void
+exaCopyDirtyToFb (ExaMigrationPtr migrate);
+
+void
+exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+
+void
+exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area);
+
+void
+exaMoveOutPixmap_classic (PixmapPtr pPixmap);
+
+void
+exaMoveInPixmap_classic (PixmapPtr pPixmap);
+
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+#endif /* EXAPRIV_H */
diff --git a/xorg-server/exa/exa_unaccel.c b/xorg-server/exa/exa_unaccel.c
index 2f8c4622d..46be2eff9 100644
--- a/xorg-server/exa/exa_unaccel.c
+++ b/xorg-server/exa/exa_unaccel.c
@@ -1,740 +1,762 @@
-/*
- *
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "exa_priv.h"
-
-#include "mipict.h"
-
-/*
- * These functions wrap the low-level fb rendering functions and
- * synchronize framebuffer/accelerated drawing by stalling until
- * the accelerator is idle
- */
-
-/**
- * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
- * current fill style.
- *
- * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
- * 1bpp and never in fb, so we don't worry about them.
- * We should worry about them for completeness sake and going forward.
- */
-void
-exaPrepareAccessGC(GCPtr pGC)
-{
- if (pGC->stipple)
- exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
- if (pGC->fillStyle == FillTiled)
- exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
-}
-
-/**
- * Finishes access to the tile in the GC, if used.
- */
-void
-exaFinishAccessGC(GCPtr pGC)
-{
- if (pGC->fillStyle == FillTiled)
- exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
- if (pGC->stipple)
- exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-}
-
-#if DEBUG_TRACE_FALL
-char
-exaDrawableLocation(DrawablePtr pDrawable)
-{
- return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
-}
-#endif /* DEBUG_TRACE_FALL */
-
-void
-ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad, int format,
- char *bits)
-{
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
- ExaPixmapPriv(pPixmap);
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
- exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
- pGC->alu, pGC->clientClipType))
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- else
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
- DamagePendingRegion(pExaPixmap->pDamage));
- pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
- Bool upsidedown, Pixel bitplane, void *closure)
-{
- RegionRec reg;
- int xoff, yoff;
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-
- if (pExaScr->prepare_access_reg) {
- PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
-
- exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
- REGION_INIT(pScreen, &reg, pbox, nbox);
- REGION_TRANSLATE(pScreen, &reg, xoff + dx, yoff + dy);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
- REGION_UNINIT(pScreen, &reg);
- } else
- exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
-
- if (pExaScr->prepare_access_reg &&
- !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
- pGC->alu, pGC->clientClipType)) {
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
-
- exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
- REGION_INIT(pScreen, &reg, pbox, nbox);
- REGION_TRANSLATE(pScreen, &reg, xoff, yoff);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
- REGION_UNINIT(pScreen, &reg);
- } else
- exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-
- /* This will eventually call fbCopyNtoN, with some calculation overhead. */
- while (nbox--) {
- pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y);
- pbox++;
- }
- exaFinishAccess (pSrc, EXA_PREPARE_SRC);
- exaFinishAccess (pDst, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-static void
-ExaFallbackPrepareReg(DrawablePtr pDrawable,
- GCPtr pGC,
- int x, int y, int width, int height,
- int index, Bool checkReads)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- ExaScreenPriv(pScreen);
-
- if (pExaScr->prepare_access_reg &&
- !(checkReads && exaGCReadsDestination(pDrawable,
- pGC->planemask,
- pGC->fillStyle,
- pGC->alu,
- pGC->clientClipType))) {
- BoxRec box;
- RegionRec reg;
- int xoff, yoff;
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
- box.x1 = pDrawable->x + x + xoff;
- box.y1 = pDrawable->y + y + yoff;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- REGION_INIT(pScreen, &reg, &box, 1);
- pExaScr->prepare_access_reg(pPixmap, index, &reg);
- REGION_UNINIT(pScreen, &reg);
- } else
- exaPrepareAccess(pDrawable, index);
-}
-
-
-RegionPtr
-ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
-{
- RegionPtr ret;
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
- EXA_PREPARE_SRC, FALSE);
- ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
- EXA_PREPARE_DEST, TRUE);
- ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
- exaFinishAccess (pSrc, EXA_PREPARE_SRC);
- exaFinishAccess (pDst, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-
- return ret;
-}
-
-RegionPtr
-ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitPlane)
-{
- RegionPtr ret;
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
- EXA_PREPARE_SRC, FALSE);
- ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
- EXA_PREPARE_DEST, TRUE);
- ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
- bitPlane);
- exaFinishAccess (pSrc, EXA_PREPARE_SRC);
- exaFinishAccess (pDst, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-
- return ret;
-}
-
-void
-ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr pptInit)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
- pDrawable, exaDrawableLocation(pDrawable),
- pGC->lineWidth, mode, npt));
-
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
- int nsegInit, xSegment *pSegInit)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
- exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
-
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *pArcs)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
- int nrect, xRectangle *prect)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
- exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable,
- int w, int h, int x, int y)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
- exaDrawableLocation(&pBitmap->drawable),
- exaDrawableLocation(pDrawable)));
- ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
- EXA_PREPARE_DEST, TRUE);
- ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
- EXA_PREPARE_SRC, FALSE);
- exaPrepareAccessGC (pGC);
- pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
- exaFinishAccessGC (pGC);
- exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- DrawablePtr pDrawable = &pWin->drawable;
- ScreenPtr pScreen = pDrawable->pScreen;
- EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p\n", pWin));
-
- /* Only need the source bits, the destination region will be overwritten */
- if (pExaScr->prepare_access_reg) {
- PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
- int xoff, yoff;
-
- exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
- REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
- REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff);
- } else
- exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
-
- swap(pExaScr, pScreen, CopyWindow);
- pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
- swap(pExaScr, pScreen, CopyWindow);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
- EXA_POST_FALLBACK(pScreen);
-}
-
-void
-ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
-
- ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
- EXA_PREPARE_SRC, FALSE);
- swap(pExaScr, pScreen, GetImage);
- pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
- swap(pExaScr, pScreen, GetImage);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
- EXA_POST_FALLBACK(pScreen);
-}
-
-void
-ExaCheckGetSpans (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
- swap(pExaScr, pScreen, GetSpans);
- pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
- swap(pExaScr, pScreen, GetSpans);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
- EXA_POST_FALLBACK(pScreen);
-}
-
-static void
-ExaSrcValidate(DrawablePtr pDrawable,
- int x,
- int y,
- int width,
- int height)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- ExaScreenPriv(pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
- BoxRec box;
- RegionRec reg;
- RegionPtr dst;
- int xoff, yoff;
-
- exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
-
- box.x1 = x + xoff;
- box.y1 = y + yoff;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
- &pExaScr->maskReg;
-
- REGION_INIT(pScreen, &reg, &box, 1);
- REGION_UNION(pScreen, dst, dst, &reg);
- REGION_UNINIT(pScreen, &reg);
-
- if (pExaScr->SavedSourceValidate) {
- swap(pExaScr, pScreen, SourceValidate);
- pScreen->SourceValidate(pDrawable, x, y, width, height);
- swap(pExaScr, pScreen, SourceValidate);
- }
-}
-
-static Bool
-ExaPrepareCompositeReg(ScreenPtr pScreen,
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- RegionRec region;
- RegionPtr dstReg = NULL;
- RegionPtr srcReg = NULL;
- RegionPtr maskReg = NULL;
- PixmapPtr pSrcPix = NULL;
- PixmapPtr pMaskPix = NULL;
- PixmapPtr pDstPix;
- ExaScreenPriv(pScreen);
- Bool ret;
-
-
- REGION_NULL(pScreen, &region);
-
- if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- REGION_NULL(pScreen, &pExaScr->srcReg);
- srcReg = &pExaScr->srcReg;
- pExaScr->srcPix = pSrcPix;
- if (pSrc != pDst)
- REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
- -pSrc->pDrawable->x,
- -pSrc->pDrawable->y);
- }
-
- if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
- REGION_NULL(pScreen, &pExaScr->maskReg);
- maskReg = &pExaScr->maskReg;
- if (pMask != pDst && pMask != pSrc)
- REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
- -pMask->pDrawable->x,
- -pMask->pDrawable->y);
- }
-
- REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
- -pDst->pDrawable->x,
- -pDst->pDrawable->y);
-
- pExaScr->SavedSourceValidate = ExaSrcValidate;
- swap(pExaScr, pScreen, SourceValidate);
- ret = miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask,
- xDst,
- yDst,
- width, height);
- swap(pExaScr, pScreen, SourceValidate);
-
- REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
- pDst->pDrawable->x,
- pDst->pDrawable->y);
- if (pSrc->pDrawable && pSrc != pDst)
- REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
- pSrc->pDrawable->x,
- pSrc->pDrawable->y);
- if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
- REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
- pMask->pDrawable->x,
- pMask->pDrawable->y);
-
- if (!ret) {
- if (srcReg)
- REGION_UNINIT(pScreen, srcReg);
- if (maskReg)
- REGION_UNINIT(pScreen, maskReg);
-
- return FALSE;
- }
-
- /**
- * Don't limit alphamaps readbacks for now until we've figured out how that
- * should be done.
- */
-
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
- EXA_PREPARE_AUX_SRC,
- NULL);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
- EXA_PREPARE_AUX_MASK,
- NULL);
-
- if (pSrcPix)
- pExaScr->prepare_access_reg(pSrcPix,
- EXA_PREPARE_SRC,
- srcReg);
-
- if (pMaskPix)
- pExaScr->prepare_access_reg(pMaskPix,
- EXA_PREPARE_MASK,
- maskReg);
-
- if (srcReg)
- REGION_UNINIT(pScreen, srcReg);
- if (maskReg)
- REGION_UNINIT(pScreen, maskReg);
-
- pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- if (!exaOpReadsDestination(op)) {
- int xoff;
- int yoff;
-
- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
- REGION_TRANSLATE(pScreen, &region, pDst->pDrawable->x + xoff,
- pDst->pDrawable->y + yoff);
- dstReg = &region;
- }
-
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
- EXA_PREPARE_AUX_DEST,
- dstReg);
- pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
-
- REGION_UNINIT(pScreen, &region);
- return TRUE;
-}
-
-void
-ExaCheckComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- EXA_PRE_FALLBACK(pScreen);
-
- if (pExaScr->prepare_access_reg) {
- if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst, width,
- height))
- goto out_no_clip;
- } else {
-
- /* We need to prepare access to any separate alpha maps first,
- * in case the driver doesn't support EXA_PREPARE_AUX*,
- * in which case EXA_PREPARE_SRC may be used for moving them out.
- */
-
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
-
- exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
-
- EXA_FALLBACK(("from picts %p/%p to pict %p\n",
- pSrc, pMask, pDst));
-
- if (pSrc->pDrawable != NULL)
- exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
- if (pMask && pMask->pDrawable != NULL)
- exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
- }
-
- swap(pExaScr, ps, Composite);
- ps->Composite (op,
- pSrc,
- pMask,
- pDst,
- xSrc,
- ySrc,
- xMask,
- yMask,
- xDst,
- yDst,
- width,
- height);
- swap(pExaScr, ps, Composite);
- if (pMask && pMask->pDrawable != NULL)
- exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
- if (pSrc->pDrawable != NULL)
- exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
- exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
-
-out_no_clip:
- EXA_POST_FALLBACK(pScreen);
-}
-
-void
-ExaCheckAddTraps (PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off,
- int ntrap,
- xTrap *traps)
-{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- EXA_PRE_FALLBACK(pScreen);
-
- EXA_FALLBACK(("to pict %p (%c)\n",
- exaDrawableLocation(pPicture->pDrawable)));
- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- swap(pExaScr, ps, AddTraps);
- ps->AddTraps (pPicture, x_off, y_off, ntrap, traps);
- swap(pExaScr, ps, AddTraps);
- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK(pScreen);
-}
-
-/**
- * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
- * that happen to be 1x1. Pixmap must be at least 8bpp.
- */
-CARD32
-exaGetPixmapFirstPixel (PixmapPtr pPixmap)
-{
- switch (pPixmap->drawable.bitsPerPixel) {
- case 32:
- {
- CARD32 pixel;
-
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char*)&pixel);
- return pixel;
- }
- case 16:
- {
- CARD16 pixel;
-
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char*)&pixel);
- return pixel;
- }
- case 8:
- {
- CARD8 pixel;
-
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char*)&pixel);
- return pixel;
- }
- default:
- FatalError("%s called for invalid bpp %d\n", __func__,
- pPixmap->drawable.bitsPerPixel);
- }
-}
+/*
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "exa_priv.h"
+
+#include "mipict.h"
+
+/*
+ * These functions wrap the low-level fb rendering functions and
+ * synchronize framebuffer/accelerated drawing by stalling until
+ * the accelerator is idle
+ */
+
+/**
+ * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
+ * current fill style.
+ *
+ * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
+ * 1bpp and never in fb, so we don't worry about them.
+ * We should worry about them for completeness sake and going forward.
+ */
+void
+exaPrepareAccessGC(GCPtr pGC)
+{
+ if (pGC->stipple)
+ exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+ if (pGC->fillStyle == FillTiled)
+ exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+}
+
+/**
+ * Finishes access to the tile in the GC, if used.
+ */
+void
+exaFinishAccessGC(GCPtr pGC)
+{
+ if (pGC->fillStyle == FillTiled)
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ if (pGC->stipple)
+ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+}
+
+#if DEBUG_TRACE_FALL
+char
+exaDrawableLocation(DrawablePtr pDrawable)
+{
+ return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
+}
+#endif /* DEBUG_TRACE_FALL */
+
+void
+ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits)
+{
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv(pPixmap);
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
+ exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType))
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ else
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
+ DamagePendingRegion(pExaPixmap->pDamage));
+ pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure)
+{
+ RegionRec reg;
+ int xoff, yoff;
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, &reg, pbox, nbox);
+ REGION_TRANSLATE(pScreen, &reg, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
+ REGION_UNINIT(pScreen, &reg);
+ } else
+ exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+ if (pExaScr->prepare_access_reg &&
+ !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType)) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, &reg, pbox, nbox);
+ REGION_TRANSLATE(pScreen, &reg, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
+ REGION_UNINIT(pScreen, &reg);
+ } else
+ exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+
+ /* This will eventually call fbCopyNtoN, with some calculation overhead. */
+ while (nbox--) {
+ pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y);
+ pbox++;
+ }
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+static void
+ExaFallbackPrepareReg(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y, int width, int height,
+ int index, Bool checkReads)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+
+ if (pExaScr->prepare_access_reg &&
+ !(checkReads && exaGCReadsDestination(pDrawable,
+ pGC->planemask,
+ pGC->fillStyle,
+ pGC->alu,
+ pGC->clientClipType))) {
+ BoxRec box;
+ RegionRec reg;
+ int xoff, yoff;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ box.x1 = pDrawable->x + x + xoff;
+ box.y1 = pDrawable->y + y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ REGION_INIT(pScreen, &reg, &box, 1);
+ pExaScr->prepare_access_reg(pPixmap, index, &reg);
+ REGION_UNINIT(pScreen, &reg);
+ } else
+ exaPrepareAccess(pDrawable, index);
+}
+
+
+RegionPtr
+ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ RegionPtr ret;
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+
+ return ret;
+}
+
+RegionPtr
+ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+ bitPlane);
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+
+ return ret;
+}
+
+void
+ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
+ pDrawable, exaDrawableLocation(pDrawable),
+ pGC->lineWidth, mode, npt));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
+ exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
+ exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
+ exaDrawableLocation(&pBitmap->drawable),
+ exaDrawableLocation(pDrawable)));
+ ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ DrawablePtr pDrawable = &pWin->drawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p\n", pWin));
+
+ /* Only need the source bits, the destination region will be overwritten */
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
+ REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff);
+ } else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
+ swap(pExaScr, pScreen, CopyWindow);
+ pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
+ swap(pExaScr, pScreen, CopyWindow);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+
+ ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ swap(pExaScr, pScreen, GetImage);
+ pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ swap(pExaScr, pScreen, GetImage);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
+ swap(pExaScr, pScreen, GetSpans);
+ pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ swap(pExaScr, pScreen, GetSpans);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+static void
+ExaSrcValidate(DrawablePtr pDrawable,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr dst;
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+ box.x1 = x + xoff;
+ box.y1 = y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
+ &pExaScr->maskReg;
+
+ REGION_INIT(pScreen, &reg, &box, 1);
+ REGION_UNION(pScreen, dst, dst, &reg);
+ REGION_UNINIT(pScreen, &reg);
+
+ if (pExaScr->SavedSourceValidate) {
+ swap(pExaScr, pScreen, SourceValidate);
+ pScreen->SourceValidate(pDrawable, x, y, width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+ }
+}
+
+static Bool
+ExaPrepareCompositeReg(ScreenPtr pScreen,
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ RegionPtr dstReg = NULL;
+ RegionPtr srcReg = NULL;
+ RegionPtr maskReg = NULL;
+ PixmapPtr pSrcPix = NULL;
+ PixmapPtr pMaskPix = NULL;
+ PixmapPtr pDstPix;
+ ExaScreenPriv(pScreen);
+ Bool ret;
+
+
+ REGION_NULL(pScreen, &region);
+
+ if (pSrc->pDrawable) {
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->srcReg);
+ srcReg = &pExaScr->srcReg;
+ pExaScr->srcPix = pSrcPix;
+ if (pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ -pSrc->pDrawable->x,
+ -pSrc->pDrawable->y);
+ }
+
+ if (pMask && pMask->pDrawable) {
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->maskReg);
+ maskReg = &pExaScr->maskReg;
+ if (pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ -pMask->pDrawable->x,
+ -pMask->pDrawable->y);
+ }
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ -pDst->pDrawable->x,
+ -pDst->pDrawable->y);
+
+ pExaScr->SavedSourceValidate = ExaSrcValidate;
+ swap(pExaScr, pScreen, SourceValidate);
+ ret = miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst,
+ yDst,
+ width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ pDst->pDrawable->x,
+ pDst->pDrawable->y);
+ if (pSrc->pDrawable && pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ pSrc->pDrawable->x,
+ pSrc->pDrawable->y);
+ if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ pMask->pDrawable->x,
+ pMask->pDrawable->y);
+
+ if (!ret) {
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ return FALSE;
+ }
+
+ /**
+ * Don't limit alphamaps readbacks for now until we've figured out how that
+ * should be done.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_SRC,
+ NULL);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_MASK,
+ NULL);
+
+ if (pSrcPix)
+ pExaScr->prepare_access_reg(pSrcPix,
+ EXA_PREPARE_SRC,
+ srcReg);
+
+ if (pMaskPix)
+ pExaScr->prepare_access_reg(pMaskPix,
+ EXA_PREPARE_MASK,
+ maskReg);
+
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+ if (!exaOpReadsDestination(op)) {
+ int xoff;
+ int yoff;
+
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, &region, pDst->pDrawable->x + xoff,
+ pDst->pDrawable->y + yoff);
+ dstReg = &region;
+ }
+
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_DEST,
+ dstReg);
+ pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
+
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+}
+
+void
+ExaCheckComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ EXA_PRE_FALLBACK(pScreen);
+
+ if (pExaScr->prepare_access_reg) {
+ if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst, width,
+ height))
+ goto out_no_clip;
+ } else {
+
+ /* We need to prepare access to any separate alpha maps first,
+ * in case the driver doesn't support EXA_PREPARE_AUX*,
+ * in which case EXA_PREPARE_SRC may be used for moving them out.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+
+ exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+
+ EXA_FALLBACK(("from picts %p/%p to pict %p\n",
+ pSrc, pMask, pDst));
+
+ if (pSrc->pDrawable != NULL)
+ exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ if (pMask && pMask->pDrawable != NULL)
+ exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ }
+
+ swap(pExaScr, ps, Composite);
+ ps->Composite (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ swap(pExaScr, ps, Composite);
+ if (pMask && pMask->pDrawable != NULL)
+ exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ if (pSrc->pDrawable != NULL)
+ exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+
+out_no_clip:
+ EXA_POST_FALLBACK(pScreen);
+}
+
+/**
+ * Avoid migration ping-pong when using a mask.
+ */
+void
+ExaCheckGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+
+ miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ EXA_PRE_FALLBACK(pScreen);
+
+ EXA_FALLBACK(("to pict %p (%c)\n",
+ exaDrawableLocation(pPicture->pDrawable)));
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ swap(pExaScr, ps, AddTraps);
+ ps->AddTraps (pPicture, x_off, y_off, ntrap, traps);
+ swap(pExaScr, ps, AddTraps);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+/**
+ * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
+ * that happen to be 1x1. Pixmap must be at least 8bpp.
+ */
+CARD32
+exaGetPixmapFirstPixel (PixmapPtr pPixmap)
+{
+ switch (pPixmap->drawable.bitsPerPixel) {
+ case 32:
+ {
+ CARD32 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ case 16:
+ {
+ CARD16 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ case 8:
+ {
+ CARD8 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ default:
+ FatalError("%s called for invalid bpp %d\n", __func__,
+ pPixmap->drawable.bitsPerPixel);
+ }
+}