/* * * 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 #endif #include "exa.h" #include #include #ifdef MITSHM #include "shmint.h" #endif #include "scrnintstr.h" #include "pixmapstr.h" #include "windowstr.h" #include "servermd.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) (ScreenPtr, 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; SharePixmapBackingProcPtr SavedSharePixmapBacking; SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking; 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; PixmapPtr maskPix; DevPrivateKeyRec pixmapPrivateKeyRec; DevPrivateKeyRec gcPrivateKeyRec; } 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 DevPrivateKeyRec exaScreenPrivateKeyRec; #define exaScreenPrivateKey (&exaScreenPrivateKeyRec) #define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey)) #define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s) #define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec)) #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)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec)) #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 exaDestroyPixmap(PixmapPtr pPixmap); 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); Bool exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap, void *handle); Bool exaSharePixmapBacking_mixed(PixmapPtr pPixmap, ScreenPtr slave, void **handle_p); /* 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 */