3 * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc.
4 * 2005 Zack Rusin, Trolltech
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
21 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
22 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
36 #include <X11/Xproto.h>
40 #include "scrnintstr.h"
41 #include "pixmapstr.h"
42 #include "windowstr.h"
44 #include "colormapst.h"
47 #include "mipointer.h"
51 #include "fboverlay.h"
56 #define DEBUG_TRACE_FALL 0
57 #define DEBUG_MIGRATE 0
58 #define DEBUG_PIXMAP 0
59 #define DEBUG_OFFSCREEN 0
60 #define DEBUG_GLYPH_CACHE 0
63 #define EXA_FALLBACK(x) \
65 ErrorF("EXA fallback at %s: ", __FUNCTION__); \
70 exaDrawableLocation(DrawablePtr pDrawable
);
72 #define EXA_FALLBACK(x)
76 #define DBG_PIXMAP(a) ErrorF a
82 #define EXA_MAX_FB FB_OVERLAY_MAX
86 #define EXA_FatalErrorDebug(x) FatalError x
87 #define EXA_FatalErrorDebugWithRet(x, ret) FatalError x
89 #define EXA_FatalErrorDebug(x) ErrorF x
90 #define EXA_FatalErrorDebugWithRet(x, ret) \
98 * This is the list of migration heuristics supported by EXA. See
99 * exaDoMigration() for what their implementations do.
101 enum ExaMigrationHeuristic
{
108 unsigned char sha1
[20];
109 } ExaCachedGlyphRec
, *ExaCachedGlyphPtr
;
112 /* The identity of the cache, statically configured at initialization */
117 int size
; /* Size of cache; eventually this should be dynamically determined */
119 /* Hash table mapping from glyph sha1 to position in the glyph; we use
120 * open addressing with a hash table size determined based on size and large
121 * enough so that we always have a good amount of free space, so we can
122 * use linear probing. (Linear probing is preferrable to double hashing
123 * here because it allows us to easily remove entries.)
128 ExaCachedGlyphPtr glyphs
;
129 int glyphCount
; /* Current number of glyphs */
131 PicturePtr picture
; /* Where the glyphs of the cache are stored */
132 int yOffset
; /* y location within the picture where the cache starts */
133 int columns
; /* Number of columns the glyphs are layed out in */
134 int evictionPosition
; /* Next random position to evict a glyph */
135 } ExaGlyphCacheRec
, *ExaGlyphCachePtr
;
137 #define EXA_NUM_GLYPH_CACHES 4
139 #define EXA_FALLBACK_COPYWINDOW (1 << 0)
140 #define EXA_ACCEL_COPYWINDOW (1 << 1)
142 typedef struct _ExaMigrationRec
{
147 } ExaMigrationRec
, *ExaMigrationPtr
;
149 typedef void (*EnableDisableFBAccessProcPtr
) (ScreenPtr
, Bool
);
152 ScreenBlockHandlerProcPtr SavedBlockHandler
;
153 ScreenWakeupHandlerProcPtr SavedWakeupHandler
;
154 CreateGCProcPtr SavedCreateGC
;
155 CloseScreenProcPtr SavedCloseScreen
;
156 GetImageProcPtr SavedGetImage
;
157 GetSpansProcPtr SavedGetSpans
;
158 CreatePixmapProcPtr SavedCreatePixmap
;
159 DestroyPixmapProcPtr SavedDestroyPixmap
;
160 CopyWindowProcPtr SavedCopyWindow
;
161 ChangeWindowAttributesProcPtr SavedChangeWindowAttributes
;
162 BitmapToRegionProcPtr SavedBitmapToRegion
;
163 CreateScreenResourcesProcPtr SavedCreateScreenResources
;
164 ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader
;
165 SharePixmapBackingProcPtr SavedSharePixmapBacking
;
166 SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking
;
167 SourceValidateProcPtr SavedSourceValidate
;
168 CompositeProcPtr SavedComposite
;
169 TrianglesProcPtr SavedTriangles
;
170 GlyphsProcPtr SavedGlyphs
;
171 TrapezoidsProcPtr SavedTrapezoids
;
172 AddTrapsProcPtr SavedAddTraps
;
173 void (*do_migration
) (ExaMigrationPtr pixmaps
, int npixmaps
,
175 Bool (*pixmap_has_gpu_copy
) (PixmapPtr pPixmap
);
176 void (*do_move_in_pixmap
) (PixmapPtr pPixmap
);
177 void (*do_move_out_pixmap
) (PixmapPtr pPixmap
);
178 void (*prepare_access_reg
) (PixmapPtr pPixmap
, int index
, RegionPtr pReg
);
181 enum ExaMigrationHeuristic migration
;
182 Bool checkDirtyCorrectness
;
183 unsigned disableFbCount
;
184 Bool optimize_migration
;
185 unsigned offScreenCounter
;
186 unsigned numOffscreenAvailable
;
187 CARD32 lastDefragment
;
188 CARD32 nextDefragment
;
189 PixmapPtr deferred_mixed_pixmap
;
191 /* Reference counting for accessed pixmaps */
196 } access
[EXA_NUM_PREPARE_INDICES
];
198 /* Holds information on fallbacks that cannot be relayed otherwise. */
199 unsigned int fallback_flags
;
200 unsigned int fallback_counter
;
202 ExaGlyphCacheRec glyphCaches
[EXA_NUM_GLYPH_CACHES
];
205 * Regions affected by fallback composite source / mask operations.
213 DevPrivateKeyRec pixmapPrivateKeyRec
;
214 DevPrivateKeyRec gcPrivateKeyRec
;
215 } ExaScreenPrivRec
, *ExaScreenPrivPtr
;
218 * This is the only completely portable way to
222 #define BitsPerPixel(d) (\
223 PixmapWidthPaddingInfo[d].notPower2 ? \
224 (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
225 ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
226 (PixmapWidthPaddingInfo[d].padRoundUp+1)))
229 extern DevPrivateKeyRec exaScreenPrivateKeyRec
;
231 #define exaScreenPrivateKey (&exaScreenPrivateKeyRec)
233 #define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey))
234 #define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
236 #define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec))
237 #define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
240 * Some macros to deal with function wrapping.
242 #define wrap(priv, real, mem, func) {\
243 priv->Saved##mem = real->mem; \
247 #define unwrap(priv, real, mem) {\
248 real->mem = priv->Saved##mem; \
251 #define swap(priv, real, mem) {\
252 void *tmp = priv->Saved##mem; \
253 priv->Saved##mem = real->mem; \
257 #define EXA_PRE_FALLBACK(_screen_) \
258 ExaScreenPriv(_screen_); \
259 pExaScr->fallback_counter++;
261 #define EXA_POST_FALLBACK(_screen_) \
262 pExaScr->fallback_counter--;
264 #define EXA_PRE_FALLBACK_GC(_gc_) \
265 ExaScreenPriv(_gc_->pScreen); \
267 pExaScr->fallback_counter++; \
268 swap(pExaGC, _gc_, ops);
270 #define EXA_POST_FALLBACK_GC(_gc_) \
271 pExaScr->fallback_counter--; \
272 swap(pExaGC, _gc_, ops);
274 /** Align an offset to an arbitrary alignment */
275 #define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \
276 (((offset) + (align) - 1) % (align)))
277 /** Align an offset to a power-of-two alignment */
278 #define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
280 #define EXA_PIXMAP_SCORE_MOVE_IN 10
281 #define EXA_PIXMAP_SCORE_MAX 20
282 #define EXA_PIXMAP_SCORE_MOVE_OUT -10
283 #define EXA_PIXMAP_SCORE_MIN -20
284 #define EXA_PIXMAP_SCORE_PINNED 1000
285 #define EXA_PIXMAP_SCORE_INIT 1001
287 #define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec))
288 #define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
290 #define EXA_RANGE_PITCH (1 << 0)
291 #define EXA_RANGE_WIDTH (1 << 1)
292 #define EXA_RANGE_HEIGHT (1 << 2)
295 ExaOffscreenArea
*area
;
296 int score
; /**< score for the move-in vs move-out heuristic */
299 CARD8
*sys_ptr
; /**< pointer to pixmap data in system memory */
300 int sys_pitch
; /**< pitch of pixmap in system memory */
302 CARD8
*fb_ptr
; /**< pointer to pixmap data in framebuffer memory */
303 int fb_pitch
; /**< pitch of pixmap in framebuffer memory */
304 unsigned int fb_size
; /**< size of pixmap in framebuffer memory */
307 * Holds information about whether this pixmap can be used for
308 * acceleration (== 0) or not (> 0).
310 * Contains a OR'ed combination of the following values:
311 * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
312 * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
313 * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
315 unsigned int accel_blocked
;
318 * The damage record contains the areas of the pixmap's current location
319 * (framebuffer or system) that have been damaged compared to the other
324 * The valid regions mark the valid bits (at least, as they're derived from
325 * damage, which may be overreported) of a pixmap's system and FB copies.
327 RegionRec validSys
, validFB
;
329 * Driver private storage per EXA pixmap
332 } ExaPixmapPrivRec
, *ExaPixmapPrivPtr
;
335 /* GC values from the layer below. */
338 } ExaGCPrivRec
, *ExaGCPrivPtr
;
350 } ExaCompositeRectRec
, *ExaCompositeRectPtr
;
353 * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place
354 * to set EXA options or hook in screen functions to handle using EXA as the AA.
356 void exaDDXDriverInit(ScreenPtr pScreen
);
360 exaPrepareAccessGC(GCPtr pGC
);
363 exaFinishAccessGC(GCPtr pGC
);
367 ExaCheckFillSpans(DrawablePtr pDrawable
, GCPtr pGC
, int nspans
,
368 DDXPointPtr ppt
, int *pwidth
, int fSorted
);
372 ExaCheckSetSpans(DrawablePtr pDrawable
, GCPtr pGC
, char *psrc
,
373 DDXPointPtr ppt
, int *pwidth
, int nspans
, int fSorted
);
377 ExaCheckPutImage(DrawablePtr pDrawable
, GCPtr pGC
, int depth
,
378 int x
, int y
, int w
, int h
, int leftPad
, int format
,
383 ExaCheckCopyNtoN(DrawablePtr pSrc
, DrawablePtr pDst
, GCPtr pGC
,
384 BoxPtr pbox
, int nbox
, int dx
, int dy
, Bool reverse
,
385 Bool upsidedown
, Pixel bitplane
, void *closure
);
389 ExaCheckCopyArea(DrawablePtr pSrc
, DrawablePtr pDst
, GCPtr pGC
,
390 int srcx
, int srcy
, int w
, int h
, int dstx
, int dsty
);
394 ExaCheckCopyPlane(DrawablePtr pSrc
, DrawablePtr pDst
, GCPtr pGC
,
395 int srcx
, int srcy
, int w
, int h
, int dstx
, int dsty
,
396 unsigned long bitPlane
);
400 ExaCheckPolyPoint(DrawablePtr pDrawable
, GCPtr pGC
, int mode
, int npt
,
401 DDXPointPtr pptInit
);
405 ExaCheckPolylines(DrawablePtr pDrawable
, GCPtr pGC
,
406 int mode
, int npt
, DDXPointPtr ppt
);
410 ExaCheckPolySegment(DrawablePtr pDrawable
, GCPtr pGC
,
411 int nsegInit
, xSegment
* pSegInit
);
414 ExaCheckPolyArc(DrawablePtr pDrawable
, GCPtr pGC
, int narcs
, xArc
* pArcs
);
418 ExaCheckPolyFillRect(DrawablePtr pDrawable
, GCPtr pGC
,
419 int nrect
, xRectangle
*prect
);
423 ExaCheckImageGlyphBlt(DrawablePtr pDrawable
, GCPtr pGC
,
424 int x
, int y
, unsigned int nglyph
,
425 CharInfoPtr
* ppci
, pointer pglyphBase
);
429 ExaCheckPolyGlyphBlt(DrawablePtr pDrawable
, GCPtr pGC
,
430 int x
, int y
, unsigned int nglyph
,
431 CharInfoPtr
* ppci
, pointer pglyphBase
);
435 ExaCheckPushPixels(GCPtr pGC
, PixmapPtr pBitmap
,
436 DrawablePtr pDrawable
, int w
, int h
, int x
, int y
);
439 ExaCheckCopyWindow(WindowPtr pWin
, DDXPointRec ptOldOrg
, RegionPtr prgnSrc
);
443 ExaCheckGetImage(DrawablePtr pDrawable
, int x
, int y
, int w
, int h
,
444 unsigned int format
, unsigned long planeMask
, char *d
);
448 ExaCheckGetSpans(DrawablePtr pDrawable
,
450 DDXPointPtr ppt
, int *pwidth
, int nspans
, char *pdstStart
);
454 ExaCheckAddTraps(PicturePtr pPicture
,
455 INT16 x_off
, INT16 y_off
, int ntrap
, xTrap
* traps
);
459 static _X_INLINE Bool
460 exaGCReadsDestination(DrawablePtr pDrawable
, unsigned long planemask
,
461 unsigned int fillStyle
, unsigned char alu
,
462 unsigned int clientClipType
)
464 return ((alu
!= GXcopy
&& alu
!= GXclear
&& alu
!= GXset
&&
465 alu
!= GXcopyInverted
) || fillStyle
== FillStippled
||
466 clientClipType
!= CT_NONE
||
467 !EXA_PM_IS_SOLID(pDrawable
, planemask
));
471 exaCopyWindow(WindowPtr pWin
, DDXPointRec ptOldOrg
, RegionPtr prgnSrc
);
475 exaFillRegionTiled(DrawablePtr pDrawable
, RegionPtr pRegion
, PixmapPtr pTile
,
476 DDXPointPtr pPatOrg
, CARD32 planemask
, CARD32 alu
,
477 unsigned int clientClipType
);
481 exaGetImage(DrawablePtr pDrawable
, int x
, int y
, int w
, int h
,
482 unsigned int format
, unsigned long planeMask
, char *d
);
486 exaCopyArea(DrawablePtr pSrcDrawable
, DrawablePtr pDstDrawable
, GCPtr pGC
,
487 int srcx
, int srcy
, int width
, int height
, int dstx
, int dsty
);
491 exaHWCopyNtoN(DrawablePtr pSrcDrawable
,
492 DrawablePtr pDstDrawable
,
495 int nbox
, int dx
, int dy
, Bool reverse
, Bool upsidedown
);
499 exaCopyNtoN(DrawablePtr pSrcDrawable
,
500 DrawablePtr pDstDrawable
,
506 Bool reverse
, Bool upsidedown
, Pixel bitplane
, void *closure
);
508 extern const GCOps exaOps
;
512 ExaCheckComposite(CARD8 op
,
520 INT16 xDst
, INT16 yDst
, CARD16 width
, CARD16 height
);
524 ExaCheckGlyphs(CARD8 op
,
527 PictFormatPtr maskFormat
,
529 INT16 ySrc
, int nlist
, GlyphListPtr list
, GlyphPtr
* glyphs
);
531 /* exa_offscreen.c */
533 ExaOffscreenSwapOut(ScreenPtr pScreen
);
536 ExaOffscreenSwapIn(ScreenPtr pScreen
);
538 ExaOffscreenArea
*ExaOffscreenDefragment(ScreenPtr pScreen
);
541 exaOffscreenInit(ScreenPtr pScreen
);
544 ExaOffscreenFini(ScreenPtr pScreen
);
548 ExaDoPrepareAccess(PixmapPtr pPixmap
, int index
);
551 exaPrepareAccess(DrawablePtr pDrawable
, int index
);
554 exaFinishAccess(DrawablePtr pDrawable
, int index
);
557 exaDestroyPixmap(PixmapPtr pPixmap
);
560 exaPixmapDirty(PixmapPtr pPix
, int x1
, int y1
, int x2
, int y2
);
564 exaGetDrawableDeltas(DrawablePtr pDrawable
, PixmapPtr pPixmap
,
568 exaPixmapHasGpuCopy(PixmapPtr p
);
571 exaGetOffscreenPixmap(DrawablePtr pDrawable
, int *xp
, int *yp
);
574 exaGetDrawablePixmap(DrawablePtr pDrawable
);
578 exaSetFbPitch(ExaScreenPrivPtr pExaScr
, ExaPixmapPrivPtr pExaPixmap
,
579 int w
, int h
, int bpp
);
583 exaSetAccelBlock(ExaScreenPrivPtr pExaScr
, ExaPixmapPrivPtr pExaPixmap
,
584 int w
, int h
, int bpp
);
587 exaDoMigration(ExaMigrationPtr pixmaps
, int npixmaps
, Bool can_accel
);
590 exaPixmapIsPinned(PixmapPtr pPix
);
592 extern const GCFuncs exaGCFuncs
;
597 exaCreatePixmap_classic(ScreenPtr pScreen
, int w
, int h
, int depth
,
598 unsigned usage_hint
);
602 exaModifyPixmapHeader_classic(PixmapPtr pPixmap
, int width
, int height
,
603 int depth
, int bitsPerPixel
, int devKind
,
607 exaDestroyPixmap_classic(PixmapPtr pPixmap
);
610 exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap
);
615 exaCreatePixmap_driver(ScreenPtr pScreen
, int w
, int h
, int depth
,
616 unsigned usage_hint
);
620 exaModifyPixmapHeader_driver(PixmapPtr pPixmap
, int width
, int height
,
621 int depth
, int bitsPerPixel
, int devKind
,
625 exaDestroyPixmap_driver(PixmapPtr pPixmap
);
628 exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap
);
633 exaCreatePixmap_mixed(ScreenPtr pScreen
, int w
, int h
, int depth
,
634 unsigned usage_hint
);
638 exaModifyPixmapHeader_mixed(PixmapPtr pPixmap
, int width
, int height
, int depth
,
639 int bitsPerPixel
, int devKind
, pointer pPixData
);
642 exaDestroyPixmap_mixed(PixmapPtr pPixmap
);
645 exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap
);
647 /* exa_migration_mixed.c */
649 exaCreateDriverPixmap_mixed(PixmapPtr pPixmap
);
652 exaDoMigration_mixed(ExaMigrationPtr pixmaps
, int npixmaps
, Bool can_accel
);
655 exaMoveInPixmap_mixed(PixmapPtr pPixmap
);
658 exaDamageReport_mixed(DamagePtr pDamage
, RegionPtr pRegion
, void *closure
);
661 exaPrepareAccessReg_mixed(PixmapPtr pPixmap
, int index
, RegionPtr pReg
);
664 exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap
, void *handle
);
666 exaSharePixmapBacking_mixed(PixmapPtr pPixmap
, ScreenPtr slave
, void **handle_p
);
670 exaOpReadsDestination(CARD8 op
);
674 exaComposite(CARD8 op
,
681 INT16 yMask
, INT16 xDst
, INT16 yDst
, CARD16 width
, CARD16 height
);
685 exaCompositeRects(CARD8 op
,
688 PicturePtr pDst
, int nrect
, ExaCompositeRectPtr rects
);
692 exaTrapezoids(CARD8 op
, PicturePtr pSrc
, PicturePtr pDst
,
693 PictFormatPtr maskFormat
, INT16 xSrc
, INT16 ySrc
,
694 int ntrap
, xTrapezoid
* traps
);
698 exaTriangles(CARD8 op
, PicturePtr pSrc
, PicturePtr pDst
,
699 PictFormatPtr maskFormat
, INT16 xSrc
, INT16 ySrc
,
700 int ntri
, xTriangle
* tris
);
704 exaGlyphsInit(ScreenPtr pScreen
);
707 exaGlyphsFini(ScreenPtr pScreen
);
714 PictFormatPtr maskFormat
,
716 INT16 ySrc
, int nlist
, GlyphListPtr list
, GlyphPtr
* glyphs
);
718 /* exa_migration_classic.c */
720 exaCopyDirtyToSys(ExaMigrationPtr migrate
);
723 exaCopyDirtyToFb(ExaMigrationPtr migrate
);
726 exaDoMigration_classic(ExaMigrationPtr pixmaps
, int npixmaps
, Bool can_accel
);
729 exaPixmapSave(ScreenPtr pScreen
, ExaOffscreenArea
* area
);
732 exaMoveOutPixmap_classic(PixmapPtr pPixmap
);
735 exaMoveInPixmap_classic(PixmapPtr pPixmap
);
738 exaPrepareAccessReg_classic(PixmapPtr pPixmap
, int index
, RegionPtr pReg
);
740 #endif /* EXAPRIV_H */