diff options
Diffstat (limited to 'xorg-server/exa/exa_unaccel.c')
-rw-r--r-- | xorg-server/exa/exa_unaccel.c | 1480 |
1 files changed, 740 insertions, 740 deletions
diff --git a/xorg-server/exa/exa_unaccel.c b/xorg-server/exa/exa_unaccel.c index 2f8c4622d..f6d74f11b 100644 --- a/xorg-server/exa/exa_unaccel.c +++ b/xorg-server/exa/exa_unaccel.c @@ -1,740 +1,740 @@ -/* - * - * 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, ®, pbox, nbox); - REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); - REGION_UNINIT(pScreen, ®); - } 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, ®, pbox, nbox); - REGION_TRANSLATE(pScreen, ®, xoff, yoff); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); - REGION_UNINIT(pScreen, ®); - } 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, ®, &box, 1); - pExaScr->prepare_access_reg(pPixmap, index, ®); - REGION_UNINIT(pScreen, ®); - } 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, ®, &box, 1); - REGION_UNION(pScreen, dst, dst, ®); - REGION_UNINIT(pScreen, ®); - - 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, ®ion); - - 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 (®ion, 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, ®ion, pDst->pDrawable->x + xoff, - pDst->pDrawable->y + yoff); - dstReg = ®ion; - } - - 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, ®ion); - 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, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®);
+ REGION_UNINIT(pScreen, ®);
+ } 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, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®);
+ REGION_UNINIT(pScreen, ®);
+ } 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, ®, &box, 1);
+ pExaScr->prepare_access_reg(pPixmap, index, ®);
+ REGION_UNINIT(pScreen, ®);
+ } 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, ®, &box, 1);
+ REGION_UNION(pScreen, dst, dst, ®);
+ REGION_UNINIT(pScreen, ®);
+
+ 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, ®ion);
+
+ 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 (®ion, 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, ®ion, pDst->pDrawable->x + xoff,
+ pDst->pDrawable->y + yoff);
+ dstReg = ®ion;
+ }
+
+ 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, ®ion);
+ 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", __FUNCTION__,
+ pPixmap->drawable.bitsPerPixel);
+ }
+}
|