2 * Copyright © 2001 Keith Packard
4 * Partly based on code that is Copyright © The XFree86 Project Inc.
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 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
26 * This file covers the initialization and teardown of EXA, and has various
27 * functions not responsible for performing rendering, pixmap migration, or
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
42 #include <X11/fonts/fontstruct.h>
43 #include "dixfontstr.h"
47 static int exaGeneration
;
48 int exaScreenPrivateIndex
;
49 int exaPixmapPrivateIndex
;
52 * exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
53 * the beginning of the given pixmap.
55 * Note that drivers are free to, and often do, munge this offset as necessary
56 * for handing to the hardware -- for example, translating it into a different
57 * aperture. This function may need to be extended in the future if we grow
58 * support for having multiple card-accessible offscreen, such as an AGP memory
59 * pool alongside the framebuffer pool.
62 exaGetPixmapOffset(PixmapPtr pPix
)
64 ExaScreenPriv (pPix
->drawable
.pScreen
);
68 /* Return the offscreen pointer if we've hidden the data. */
69 if (pPix
->devPrivate
.ptr
== NULL
)
70 ptr
= pExaPixmap
->fb_ptr
;
72 ptr
= pPix
->devPrivate
.ptr
;
74 return ((unsigned long)ptr
- (unsigned long)pExaScr
->info
->memoryBase
);
78 * exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
80 * This is a helper to make driver code more obvious, due to the rather obscure
81 * naming of the pitch field in the pixmap.
84 exaGetPixmapPitch(PixmapPtr pPix
)
90 * exaGetPixmapSize() returns the size in bytes of the given pixmap in video
91 * memory. Only valid when the pixmap is currently in framebuffer.
94 exaGetPixmapSize(PixmapPtr pPix
)
96 ExaPixmapPrivPtr pExaPixmap
;
98 pExaPixmap
= ExaGetPixmapPriv(pPix
);
99 if (pExaPixmap
!= NULL
)
100 return pExaPixmap
->fb_size
;
105 * exaGetDrawablePixmap() returns a backing pixmap for a given drawable.
107 * @param pDrawable the drawable being requested.
109 * This function returns the backing pixmap for a drawable, whether it is a
110 * redirected window, unredirected window, or already a pixmap. Note that
111 * coordinate translation is needed when drawing to the backing pixmap of a
112 * redirected window, and the translation coordinates are provided by calling
113 * exaGetOffscreenPixmap() on the drawable.
116 exaGetDrawablePixmap(DrawablePtr pDrawable
)
118 if (pDrawable
->type
== DRAWABLE_WINDOW
)
119 return pDrawable
->pScreen
->GetWindowPixmap ((WindowPtr
) pDrawable
);
121 return (PixmapPtr
) pDrawable
;
125 * Sets the offsets to add to coordinates to make them address the same bits in
126 * the backing drawable. These coordinates are nonzero only for redirected
130 exaGetDrawableDeltas (DrawablePtr pDrawable
, PixmapPtr pPixmap
,
134 if (pDrawable
->type
== DRAWABLE_WINDOW
) {
135 *xp
= -pPixmap
->screen_x
;
136 *yp
= -pPixmap
->screen_y
;
146 * exaPixmapDirty() marks a pixmap as dirty, allowing for
147 * optimizations in pixmap migration when no changes have occurred.
150 exaPixmapDirty (PixmapPtr pPix
, int x1
, int y1
, int x2
, int y2
)
154 RegionPtr pDamageReg
;
162 box
.x2
= min(x2
, pPix
->drawable
.width
);
163 box
.y2
= min(y2
, pPix
->drawable
.height
);
165 if (box
.x1
>= box
.x2
|| box
.y1
>= box
.y2
)
168 pDamageReg
= DamageRegion(pExaPixmap
->pDamage
);
170 REGION_INIT(pScreen
, ®ion
, &box
, 1);
171 REGION_UNION(pScreen
, pDamageReg
, pDamageReg
, ®ion
);
172 REGION_UNINIT(pScreen
, ®ion
);
176 exaDestroyPixmap (PixmapPtr pPixmap
)
178 if (pPixmap
->refcnt
== 1)
180 ExaPixmapPriv (pPixmap
);
181 if (pExaPixmap
->area
)
183 DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
184 (void*)pPixmap
->drawable
.id
,
185 ExaGetPixmapPriv(pPixmap
)->area
->offset
,
186 pPixmap
->drawable
.width
,
187 pPixmap
->drawable
.height
));
188 /* Free the offscreen area */
189 exaOffscreenFree (pPixmap
->drawable
.pScreen
, pExaPixmap
->area
);
190 pPixmap
->devPrivate
.ptr
= pExaPixmap
->sys_ptr
;
191 pPixmap
->devKind
= pExaPixmap
->sys_pitch
;
193 REGION_UNINIT(pPixmap
->drawable
.pScreen
, &pExaPixmap
->validReg
);
195 return fbDestroyPixmap (pPixmap
);
205 for (bits
= 0; val
!= 0; bits
++)
211 * exaCreatePixmap() creates a new pixmap.
213 * If width and height are 0, this won't be a full-fledged pixmap and it will
214 * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because
215 * ModifyPixmapHeader() would break migration. These types of pixmaps are used
216 * for scratch pixmaps, or to represent the visible screen.
219 exaCreatePixmap(ScreenPtr pScreen
, int w
, int h
, int depth
)
222 ExaPixmapPrivPtr pExaPixmap
;
224 ExaScreenPriv(pScreen
);
226 if (w
> 32767 || h
> 32767)
229 pPixmap
= fbCreatePixmap (pScreen
, w
, h
, depth
);
232 pExaPixmap
= ExaGetPixmapPriv(pPixmap
);
234 bpp
= pPixmap
->drawable
.bitsPerPixel
;
236 /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
238 pExaPixmap
->score
= EXA_PIXMAP_SCORE_PINNED
;
240 pExaPixmap
->score
= EXA_PIXMAP_SCORE_INIT
;
242 pExaPixmap
->area
= NULL
;
244 pExaPixmap
->sys_ptr
= pPixmap
->devPrivate
.ptr
;
245 pExaPixmap
->sys_pitch
= pPixmap
->devKind
;
247 pExaPixmap
->fb_ptr
= NULL
;
248 if (pExaScr
->info
->flags
& EXA_OFFSCREEN_ALIGN_POT
&& w
!= 1)
249 pExaPixmap
->fb_pitch
= (1 << (exaLog2(w
- 1) + 1)) * bpp
/ 8;
251 pExaPixmap
->fb_pitch
= w
* bpp
/ 8;
252 pExaPixmap
->fb_pitch
= EXA_ALIGN(pExaPixmap
->fb_pitch
,
253 pExaScr
->info
->pixmapPitchAlign
);
254 pExaPixmap
->fb_size
= pExaPixmap
->fb_pitch
* h
;
256 if (pExaPixmap
->fb_pitch
> 32767) {
257 fbDestroyPixmap(pPixmap
);
261 /* Set up damage tracking */
262 pExaPixmap
->pDamage
= DamageCreate (NULL
, NULL
, DamageReportNone
, TRUE
,
265 if (pExaPixmap
->pDamage
== NULL
) {
266 fbDestroyPixmap (pPixmap
);
270 DamageRegister (&pPixmap
->drawable
, pExaPixmap
->pDamage
);
271 DamageSetReportAfterOp (pExaPixmap
->pDamage
, TRUE
);
273 /* None of the pixmap bits are valid initially */
274 REGION_NULL(pScreen
, &pExaPixmap
->validReg
);
280 * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
281 * memory, meaning that acceleration could probably be done to it, and that it
282 * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
285 * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly
286 * deal with moving pixmaps in and out of system memory), EXA will give drivers
287 * pixmaps as arguments for which exaPixmapIsOffscreen() is TRUE.
289 * @return TRUE if the given drawable is in framebuffer memory.
292 exaPixmapIsOffscreen(PixmapPtr p
)
294 ScreenPtr pScreen
= p
->drawable
.pScreen
;
295 ExaScreenPriv(pScreen
);
297 /* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
299 if (p
->devPrivate
.ptr
== NULL
)
302 if (pExaScr
->info
->PixmapIsOffscreen
)
303 return pExaScr
->info
->PixmapIsOffscreen(p
);
305 return ((unsigned long) ((CARD8
*) p
->devPrivate
.ptr
-
306 (CARD8
*) pExaScr
->info
->memoryBase
) <
307 pExaScr
->info
->memorySize
);
311 * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapIsOffscreen().
314 exaDrawableIsOffscreen (DrawablePtr pDrawable
)
316 return exaPixmapIsOffscreen (exaGetDrawablePixmap (pDrawable
));
320 * Returns the pixmap which backs a drawable, and the offsets to add to
321 * coordinates to make them address the same bits in the backing drawable.
324 exaGetOffscreenPixmap (DrawablePtr pDrawable
, int *xp
, int *yp
)
326 PixmapPtr pPixmap
= exaGetDrawablePixmap (pDrawable
);
328 exaGetDrawableDeltas (pDrawable
, pPixmap
, xp
, yp
);
330 if (exaPixmapIsOffscreen (pPixmap
))
337 * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
339 * It deals with waiting for synchronization with the card, determining if
340 * PrepareAccess() is necessary, and working around PrepareAccess() failure.
343 exaPrepareAccess(DrawablePtr pDrawable
, int index
)
345 ScreenPtr pScreen
= pDrawable
->pScreen
;
346 ExaScreenPriv (pScreen
);
349 pPixmap
= exaGetDrawablePixmap (pDrawable
);
351 if (exaPixmapIsOffscreen (pPixmap
))
352 exaWaitSync (pDrawable
->pScreen
);
356 /* Unhide pixmap pointer */
357 if (pPixmap
->devPrivate
.ptr
== NULL
) {
358 ExaPixmapPriv (pPixmap
);
360 pPixmap
->devPrivate
.ptr
= pExaPixmap
->fb_ptr
;
363 if (pExaScr
->info
->PrepareAccess
== NULL
)
366 if (!(*pExaScr
->info
->PrepareAccess
) (pPixmap
, index
)) {
367 ExaPixmapPriv (pPixmap
);
368 if (pExaPixmap
->score
!= EXA_PIXMAP_SCORE_PINNED
)
369 FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
370 exaMoveOutPixmap (pPixmap
);
375 * exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
377 * It deals with calling the driver's FinishAccess() only if necessary.
380 exaFinishAccess(DrawablePtr pDrawable
, int index
)
382 ScreenPtr pScreen
= pDrawable
->pScreen
;
383 ExaScreenPriv (pScreen
);
385 ExaPixmapPrivPtr pExaPixmap
;
387 pPixmap
= exaGetDrawablePixmap (pDrawable
);
389 pExaPixmap
= ExaGetPixmapPriv(pPixmap
);
391 /* Rehide pixmap pointer if we're doing that. */
392 if (pExaPixmap
!= NULL
&& pExaScr
->hideOffscreenPixmapData
&&
393 pExaPixmap
->fb_ptr
== pPixmap
->devPrivate
.ptr
)
395 pPixmap
->devPrivate
.ptr
= pExaPixmap
->fb_ptr
;
398 if (pExaScr
->info
->FinishAccess
== NULL
)
401 if (!exaPixmapIsOffscreen (pPixmap
))
404 (*pExaScr
->info
->FinishAccess
) (pPixmap
, index
);
408 * exaValidateGC() sets the ops to EXA's implementations, which may be
409 * accelerated or may sync the card and fall back to fb.
412 exaValidateGC (GCPtr pGC
, unsigned long changes
, DrawablePtr pDrawable
)
414 /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
415 * Preempt fbValidateGC by doing its work and masking the change out, so
416 * that we can do the Prepare/FinishAccess.
419 if ((changes
& GCTile
) && fbGetRotatedPixmap(pGC
)) {
420 (*pGC
->pScreen
->DestroyPixmap
) (fbGetRotatedPixmap(pGC
));
421 fbGetRotatedPixmap(pGC
) = 0;
424 if (pGC
->fillStyle
== FillTiled
) {
425 PixmapPtr pOldTile
, pNewTile
;
427 pOldTile
= pGC
->tile
.pixmap
;
428 if (pOldTile
->drawable
.bitsPerPixel
!= pDrawable
->bitsPerPixel
)
430 pNewTile
= fbGetRotatedPixmap(pGC
);
432 pNewTile
->drawable
.bitsPerPixel
!= pDrawable
->bitsPerPixel
)
435 (*pGC
->pScreen
->DestroyPixmap
) (pNewTile
);
436 /* fb24_32ReformatTile will do direct access of a newly-
437 * allocated pixmap. This isn't a problem yet, since we don't
438 * put pixmaps in FB until at least one accelerated EXA op.
440 exaPrepareAccess(&pOldTile
->drawable
, EXA_PREPARE_SRC
);
441 pNewTile
= fb24_32ReformatTile (pOldTile
,
442 pDrawable
->bitsPerPixel
);
443 exaPixmapDirty(pNewTile
, 0, 0, pNewTile
->drawable
.width
, pNewTile
->drawable
.height
);
444 exaFinishAccess(&pOldTile
->drawable
, EXA_PREPARE_SRC
);
448 fbGetRotatedPixmap(pGC
) = pOldTile
;
449 pGC
->tile
.pixmap
= pNewTile
;
455 if (changes
& GCTile
) {
456 if (!pGC
->tileIsPixel
&& FbEvenTile (pGC
->tile
.pixmap
->drawable
.width
*
457 pDrawable
->bitsPerPixel
))
459 /* XXX This fixes corruption with tiled pixmaps, but may just be a
460 * workaround for broken drivers
462 exaMoveOutPixmap(pGC
->tile
.pixmap
);
463 fbPadPixmap (pGC
->tile
.pixmap
);
464 exaPixmapDirty(pGC
->tile
.pixmap
, 0, 0,
465 pGC
->tile
.pixmap
->drawable
.width
,
466 pGC
->tile
.pixmap
->drawable
.height
);
468 /* Mask out the GCTile change notification, now that we've done FB's
474 fbValidateGC (pGC
, changes
, pDrawable
);
476 pGC
->ops
= (GCOps
*) &exaOps
;
479 static GCFuncs exaGCFuncs
= {
490 * exaCreateGC makes a new GC and hooks up its funcs handler, so that
491 * exaValidateGC() will get called.
494 exaCreateGC (GCPtr pGC
)
496 if (!fbCreateGC (pGC
))
499 pGC
->funcs
= &exaGCFuncs
;
505 * exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's
506 * screen private, before calling down to the next CloseSccreen.
509 exaCloseScreen(int i
, ScreenPtr pScreen
)
511 ExaScreenPriv(pScreen
);
513 PictureScreenPtr ps
= GetPictureScreenIfSet(pScreen
);
516 pScreen
->CreateGC
= pExaScr
->SavedCreateGC
;
517 pScreen
->CloseScreen
= pExaScr
->SavedCloseScreen
;
518 pScreen
->GetImage
= pExaScr
->SavedGetImage
;
519 pScreen
->GetSpans
= pExaScr
->SavedGetSpans
;
520 pScreen
->PaintWindowBackground
= pExaScr
->SavedPaintWindowBackground
;
521 pScreen
->PaintWindowBorder
= pExaScr
->SavedPaintWindowBorder
;
522 pScreen
->CreatePixmap
= pExaScr
->SavedCreatePixmap
;
523 pScreen
->DestroyPixmap
= pExaScr
->SavedDestroyPixmap
;
524 pScreen
->CopyWindow
= pExaScr
->SavedCopyWindow
;
527 ps
->Composite
= pExaScr
->SavedComposite
;
528 ps
->Glyphs
= pExaScr
->SavedGlyphs
;
529 ps
->Trapezoids
= pExaScr
->SavedTrapezoids
;
535 return (*pScreen
->CloseScreen
) (i
, pScreen
);
539 * This function allocates a driver structure for EXA drivers to fill in. By
540 * having EXA allocate the structure, the driver structure can be extended
541 * without breaking ABI between EXA and the drivers. The driver's
542 * responsibility is to check beforehand that the EXA module has a matching
543 * major number and sufficient minor. Drivers are responsible for freeing the
544 * driver structure using xfree().
546 * @return a newly allocated, zero-filled driver structure
551 return xcalloc(1, sizeof(ExaDriverRec
));
555 * @param pScreen screen being initialized
556 * @param pScreenInfo EXA driver record
558 * exaDriverInit sets up EXA given a driver record filled in by the driver.
559 * pScreenInfo should have been allocated by exaDriverAlloc(). See the
560 * comments in _ExaDriver for what must be filled in and what is optional.
562 * @return TRUE if EXA was successfully initialized.
565 exaDriverInit (ScreenPtr pScreen
,
566 ExaDriverPtr pScreenInfo
)
568 ExaScreenPrivPtr pExaScr
;
576 if (!pScreenInfo
->memoryBase
) {
577 LogMessage(X_ERROR
, "EXA(%d): ExaDriverRec::memoryBase must be "
578 "non-zero\n", pScreen
->myNum
);
582 if (!pScreenInfo
->memorySize
) {
583 LogMessage(X_ERROR
, "EXA(%d): ExaDriverRec::memorySize must be "
584 "non-zero\n", pScreen
->myNum
);
588 if (pScreenInfo
->offScreenBase
> pScreenInfo
->memorySize
) {
589 LogMessage(X_ERROR
, "EXA(%d): ExaDriverRec::offScreenBase must be <= "
590 "ExaDriverRec::memorySize\n", pScreen
->myNum
);
594 if (!pScreenInfo
->PrepareSolid
) {
595 LogMessage(X_ERROR
, "EXA(%d): ExaDriverRec::PrepareSolid must be "
596 "non-NULL\n", pScreen
->myNum
);
600 if (!pScreenInfo
->PrepareCopy
) {
601 LogMessage(X_ERROR
, "EXA(%d): ExaDriverRec::PrepareCopy must be "
602 "non-NULL\n", pScreen
->myNum
);
606 if (!pScreenInfo
->WaitMarker
) {
607 LogMessage(X_ERROR
, "EXA(%d): ExaDriverRec::WaitMarker must be "
608 "non-NULL\n", pScreen
->myNum
);
612 if (pScreenInfo
->exa_major
!= EXA_VERSION_MAJOR
||
613 pScreenInfo
->exa_minor
> EXA_VERSION_MINOR
)
615 LogMessage(X_ERROR
, "EXA(%d): driver's EXA version requirements "
616 "(%d.%d) are incompatible with EXA version (%d.%d)\n",
618 pScreenInfo
->exa_major
, pScreenInfo
->exa_minor
,
619 EXA_VERSION_MAJOR
, EXA_VERSION_MINOR
);
624 ps
= GetPictureScreenIfSet(pScreen
);
626 if (exaGeneration
!= serverGeneration
)
628 exaScreenPrivateIndex
= AllocateScreenPrivateIndex();
629 exaPixmapPrivateIndex
= AllocatePixmapPrivateIndex();
630 exaGeneration
= serverGeneration
;
633 pExaScr
= xcalloc (sizeof (ExaScreenPrivRec
), 1);
636 LogMessage(X_WARNING
, "EXA(%d): Failed to allocate screen private\n",
641 pExaScr
->info
= pScreenInfo
;
643 pScreen
->devPrivates
[exaScreenPrivateIndex
].ptr
= (pointer
) pExaScr
;
645 pExaScr
->migration
= ExaMigrationAlways
;
647 exaDDXDriverInit(pScreen
);
650 * Replace various fb screen functions
652 pExaScr
->SavedCloseScreen
= pScreen
->CloseScreen
;
653 pScreen
->CloseScreen
= exaCloseScreen
;
655 pExaScr
->SavedCreateGC
= pScreen
->CreateGC
;
656 pScreen
->CreateGC
= exaCreateGC
;
658 pExaScr
->SavedGetImage
= pScreen
->GetImage
;
659 pScreen
->GetImage
= exaGetImage
;
661 pExaScr
->SavedGetSpans
= pScreen
->GetSpans
;
662 pScreen
->GetSpans
= exaGetSpans
;
664 pExaScr
->SavedCopyWindow
= pScreen
->CopyWindow
;
665 pScreen
->CopyWindow
= exaCopyWindow
;
667 pExaScr
->SavedPaintWindowBackground
= pScreen
->PaintWindowBackground
;
668 pScreen
->PaintWindowBackground
= exaPaintWindow
;
670 pExaScr
->SavedPaintWindowBorder
= pScreen
->PaintWindowBorder
;
671 pScreen
->PaintWindowBorder
= exaPaintWindow
;
673 pScreen
->BackingStoreFuncs
.SaveAreas
= ExaCheckSaveAreas
;
674 pScreen
->BackingStoreFuncs
.RestoreAreas
= ExaCheckRestoreAreas
;
677 pExaScr
->SavedComposite
= ps
->Composite
;
678 ps
->Composite
= exaComposite
;
680 pExaScr
->SavedRasterizeTrapezoid
= ps
->RasterizeTrapezoid
;
681 ps
->RasterizeTrapezoid
= exaRasterizeTrapezoid
;
683 pExaScr
->SavedAddTriangles
= ps
->AddTriangles
;
684 ps
->AddTriangles
= exaAddTriangles
;
686 pExaScr
->SavedGlyphs
= ps
->Glyphs
;
687 ps
->Glyphs
= exaGlyphs
;
689 pExaScr
->SavedTrapezoids
= ps
->Trapezoids
;
690 ps
->Trapezoids
= exaTrapezoids
;
695 /* Re-register with the MI funcs, which don't allow shared pixmaps.
696 * Shared pixmaps are almost always a performance loss for us, but this
697 * still allows for SHM PutImage.
699 ShmRegisterFuncs(pScreen
, NULL
);
702 * Hookup offscreen pixmaps
704 if ((pExaScr
->info
->flags
& EXA_OFFSCREEN_PIXMAPS
) &&
705 pExaScr
->info
->offScreenBase
< pExaScr
->info
->memorySize
)
707 if (!AllocatePixmapPrivate(pScreen
, exaPixmapPrivateIndex
,
708 sizeof (ExaPixmapPrivRec
))) {
709 LogMessage(X_WARNING
,
710 "EXA(%d): Failed to allocate pixmap private\n",
714 pExaScr
->SavedCreatePixmap
= pScreen
->CreatePixmap
;
715 pScreen
->CreatePixmap
= exaCreatePixmap
;
717 pExaScr
->SavedDestroyPixmap
= pScreen
->DestroyPixmap
;
718 pScreen
->DestroyPixmap
= exaDestroyPixmap
;
720 LogMessage(X_INFO
, "EXA(%d): Offscreen pixmap area of %d bytes\n",
722 pExaScr
->info
->memorySize
- pExaScr
->info
->offScreenBase
);
726 LogMessage(X_INFO
, "EXA(%d): No offscreen pixmaps\n", pScreen
->myNum
);
727 if (!AllocatePixmapPrivate(pScreen
, exaPixmapPrivateIndex
, 0))
731 DBG_PIXMAP(("============== %ld < %ld\n", pExaScr
->info
->offScreenBase
,
732 pExaScr
->info
->memorySize
));
733 if (pExaScr
->info
->offScreenBase
< pExaScr
->info
->memorySize
) {
734 if (!exaOffscreenInit (pScreen
)) {
735 LogMessage(X_WARNING
, "EXA(%d): Offscreen pixmap setup failed\n",
741 LogMessage(X_INFO
, "EXA(%d): Driver registered support for the following"
742 " operations:\n", pScreen
->myNum
);
743 assert(pScreenInfo
->PrepareSolid
!= NULL
);
744 LogMessage(X_INFO
, " Solid\n");
745 assert(pScreenInfo
->PrepareCopy
!= NULL
);
746 LogMessage(X_INFO
, " Copy\n");
747 if (pScreenInfo
->PrepareComposite
!= NULL
) {
748 LogMessage(X_INFO
, " Composite (RENDER acceleration)\n");
750 if (pScreenInfo
->UploadToScreen
!= NULL
) {
751 LogMessage(X_INFO
, " UploadToScreen\n");
753 if (pScreenInfo
->DownloadFromScreen
!= NULL
) {
754 LogMessage(X_INFO
, " DownloadFromScreen\n");
761 * exaDriverFini tears down EXA on a given screen.
763 * @param pScreen screen being torn down.
766 exaDriverFini (ScreenPtr pScreen
)
768 /*right now does nothing*/
772 * exaMarkSync() should be called after any asynchronous drawing by the hardware.
774 * @param pScreen screen which drawing occurred on
776 * exaMarkSync() sets a flag to indicate that some asynchronous drawing has
777 * happened and a WaitSync() will be necessary before relying on the contents of
778 * offscreen memory from the CPU's perspective. It also calls an optional
779 * driver MarkSync() callback, the return value of which may be used to do partial
780 * synchronization with the hardware in the future.
782 void exaMarkSync(ScreenPtr pScreen
)
784 ExaScreenPriv(pScreen
);
786 pExaScr
->info
->needsSync
= TRUE
;
787 if (pExaScr
->info
->MarkSync
!= NULL
) {
788 pExaScr
->info
->lastMarker
= (*pExaScr
->info
->MarkSync
)(pScreen
);
793 * exaWaitSync() ensures that all drawing has been completed.
795 * @param pScreen screen being synchronized.
797 * Calls down into the driver to ensure that all previous drawing has completed.
798 * It should always be called before relying on the framebuffer contents
799 * reflecting previous drawing, from a CPU perspective.
801 void exaWaitSync(ScreenPtr pScreen
)
803 ExaScreenPriv(pScreen
);
805 if (pExaScr
->info
->needsSync
&& !pExaScr
->swappedOut
) {
806 (*pExaScr
->info
->WaitMarker
)(pScreen
, pExaScr
->info
->lastMarker
);
807 pExaScr
->info
->needsSync
= FALSE
;