xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

exa_unaccel.c (25134B)


      1 /*
      2  *
      3  * Copyright © 1999 Keith Packard
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of Keith Packard not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  Keith Packard makes no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #include "exa_priv.h"
     25 
     26 #include "mipict.h"
     27 
     28 /*
     29  * These functions wrap the low-level fb rendering functions and
     30  * synchronize framebuffer/accelerated drawing by stalling until
     31  * the accelerator is idle
     32  */
     33 
     34 /**
     35  * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
     36  * current fill style.
     37  *
     38  * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
     39  * 1bpp and never in fb, so we don't worry about them.
     40  * We should worry about them for completeness sake and going forward.
     41  */
     42 void
     43 exaPrepareAccessGC(GCPtr pGC)
     44 {
     45     if (pGC->stipple)
     46         exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
     47     if (pGC->fillStyle == FillTiled)
     48         exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
     49 }
     50 
     51 /**
     52  * Finishes access to the tile in the GC, if used.
     53  */
     54 void
     55 exaFinishAccessGC(GCPtr pGC)
     56 {
     57     if (pGC->fillStyle == FillTiled)
     58         exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
     59     if (pGC->stipple)
     60         exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
     61 }
     62 
     63 #if DEBUG_TRACE_FALL
     64 char
     65 exaDrawableLocation(DrawablePtr pDrawable)
     66 {
     67     return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
     68 }
     69 #endif                          /* DEBUG_TRACE_FALL */
     70 
     71 void
     72 ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
     73                   DDXPointPtr ppt, int *pwidth, int fSorted)
     74 {
     75     EXA_PRE_FALLBACK_GC(pGC);
     76     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     77     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
     78     exaPrepareAccessGC(pGC);
     79     pGC->ops->FillSpans(pDrawable, pGC, nspans, ppt, pwidth, fSorted);
     80     exaFinishAccessGC(pGC);
     81     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
     82     EXA_POST_FALLBACK_GC(pGC);
     83 }
     84 
     85 void
     86 ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
     87                  DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
     88 {
     89     EXA_PRE_FALLBACK_GC(pGC);
     90     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     91     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
     92     pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
     93     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
     94     EXA_POST_FALLBACK_GC(pGC);
     95 }
     96 
     97 void
     98 ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
     99                  int x, int y, int w, int h, int leftPad, int format,
    100                  char *bits)
    101 {
    102     PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
    103 
    104     ExaPixmapPriv(pPixmap);
    105 
    106     EXA_PRE_FALLBACK_GC(pGC);
    107     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    108     if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
    109         exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
    110                               pGC->alu, pGC->clientClip != NULL))
    111         exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    112     else
    113         pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
    114                                     DamagePendingRegion(pExaPixmap->pDamage));
    115     pGC->ops->PutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
    116                        bits);
    117     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    118     EXA_POST_FALLBACK_GC(pGC);
    119 }
    120 
    121 void
    122 ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
    123                  BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
    124                  Bool upsidedown, Pixel bitplane, void *closure)
    125 {
    126     RegionRec reg;
    127     int xoff, yoff;
    128 
    129     EXA_PRE_FALLBACK_GC(pGC);
    130     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
    131                   exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
    132 
    133     if (pExaScr->prepare_access_reg && RegionInitBoxes(&reg, pbox, nbox)) {
    134         PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
    135 
    136         exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
    137         RegionTranslate(&reg, xoff + dx, yoff + dy);
    138         pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
    139         RegionUninit(&reg);
    140     }
    141     else
    142         exaPrepareAccess(pSrc, EXA_PREPARE_SRC);
    143 
    144     if (pExaScr->prepare_access_reg &&
    145         !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
    146                                pGC->alu, pGC->clientClip != NULL) &&
    147         RegionInitBoxes(&reg, pbox, nbox)) {
    148         PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
    149 
    150         exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
    151         RegionTranslate(&reg, xoff, yoff);
    152         pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
    153         RegionUninit(&reg);
    154     }
    155     else
    156         exaPrepareAccess(pDst, EXA_PREPARE_DEST);
    157 
    158     /* This will eventually call fbCopyNtoN, with some calculation overhead. */
    159     while (nbox--) {
    160         pGC->ops->CopyArea(pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx,
    161                            pbox->y1 - pSrc->y + dy, pbox->x2 - pbox->x1,
    162                            pbox->y2 - pbox->y1, pbox->x1 - pDst->x,
    163                            pbox->y1 - pDst->y);
    164         pbox++;
    165     }
    166     exaFinishAccess(pSrc, EXA_PREPARE_SRC);
    167     exaFinishAccess(pDst, EXA_PREPARE_DEST);
    168     EXA_POST_FALLBACK_GC(pGC);
    169 }
    170 
    171 static void
    172 ExaFallbackPrepareReg(DrawablePtr pDrawable,
    173                       GCPtr pGC,
    174                       int x, int y, int width, int height,
    175                       int index, Bool checkReads)
    176 {
    177     ScreenPtr pScreen = pDrawable->pScreen;
    178 
    179     ExaScreenPriv(pScreen);
    180 
    181     if (pExaScr->prepare_access_reg &&
    182         !(checkReads && exaGCReadsDestination(pDrawable, pGC->planemask,
    183                                               pGC->fillStyle, pGC->alu,
    184                                               pGC->clientClip != NULL))) {
    185         BoxRec box;
    186         RegionRec reg;
    187         int xoff, yoff;
    188         PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
    189 
    190         exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
    191         box.x1 = pDrawable->x + x + xoff;
    192         box.y1 = pDrawable->y + y + yoff;
    193         box.x2 = box.x1 + width;
    194         box.y2 = box.y1 + height;
    195 
    196         RegionInit(&reg, &box, 1);
    197         pExaScr->prepare_access_reg(pPixmap, index, &reg);
    198         RegionUninit(&reg);
    199     }
    200     else
    201         exaPrepareAccess(pDrawable, index);
    202 }
    203 
    204 RegionPtr
    205 ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
    206                  int srcx, int srcy, int w, int h, int dstx, int dsty)
    207 {
    208     RegionPtr ret;
    209 
    210     EXA_PRE_FALLBACK_GC(pGC);
    211     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
    212                   exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
    213     ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE);
    214     ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE);
    215     ret = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
    216     exaFinishAccess(pSrc, EXA_PREPARE_SRC);
    217     exaFinishAccess(pDst, EXA_PREPARE_DEST);
    218     EXA_POST_FALLBACK_GC(pGC);
    219 
    220     return ret;
    221 }
    222 
    223 RegionPtr
    224 ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
    225                   int srcx, int srcy, int w, int h, int dstx, int dsty,
    226                   unsigned long bitPlane)
    227 {
    228     RegionPtr ret;
    229 
    230     EXA_PRE_FALLBACK_GC(pGC);
    231     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
    232                   exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
    233     ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE);
    234     ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE);
    235     ret = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
    236                               bitPlane);
    237     exaFinishAccess(pSrc, EXA_PREPARE_SRC);
    238     exaFinishAccess(pDst, EXA_PREPARE_DEST);
    239     EXA_POST_FALLBACK_GC(pGC);
    240 
    241     return ret;
    242 }
    243 
    244 void
    245 ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
    246                   DDXPointPtr pptInit)
    247 {
    248     EXA_PRE_FALLBACK_GC(pGC);
    249     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    250     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    251     pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, pptInit);
    252     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    253     EXA_POST_FALLBACK_GC(pGC);
    254 }
    255 
    256 void
    257 ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
    258                   int mode, int npt, DDXPointPtr ppt)
    259 {
    260     EXA_PRE_FALLBACK_GC(pGC);
    261     EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
    262                   pDrawable, exaDrawableLocation(pDrawable),
    263                   pGC->lineWidth, mode, npt));
    264 
    265     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    266     exaPrepareAccessGC(pGC);
    267     pGC->ops->Polylines(pDrawable, pGC, mode, npt, ppt);
    268     exaFinishAccessGC(pGC);
    269     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    270     EXA_POST_FALLBACK_GC(pGC);
    271 }
    272 
    273 void
    274 ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
    275                     int nsegInit, xSegment * pSegInit)
    276 {
    277     EXA_PRE_FALLBACK_GC(pGC);
    278     EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
    279                   exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
    280 
    281     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    282     exaPrepareAccessGC(pGC);
    283     pGC->ops->PolySegment(pDrawable, pGC, nsegInit, pSegInit);
    284     exaFinishAccessGC(pGC);
    285     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    286     EXA_POST_FALLBACK_GC(pGC);
    287 }
    288 
    289 void
    290 ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs)
    291 {
    292     EXA_PRE_FALLBACK_GC(pGC);
    293     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    294 
    295     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    296     exaPrepareAccessGC(pGC);
    297     pGC->ops->PolyArc(pDrawable, pGC, narcs, pArcs);
    298     exaFinishAccessGC(pGC);
    299     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    300     EXA_POST_FALLBACK_GC(pGC);
    301 }
    302 
    303 void
    304 ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
    305                      int nrect, xRectangle *prect)
    306 {
    307     EXA_PRE_FALLBACK_GC(pGC);
    308     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    309 
    310     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    311     exaPrepareAccessGC(pGC);
    312     pGC->ops->PolyFillRect(pDrawable, pGC, nrect, prect);
    313     exaFinishAccessGC(pGC);
    314     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    315     EXA_POST_FALLBACK_GC(pGC);
    316 }
    317 
    318 void
    319 ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
    320                       int x, int y, unsigned int nglyph,
    321                       CharInfoPtr * ppci, void *pglyphBase)
    322 {
    323     EXA_PRE_FALLBACK_GC(pGC);
    324     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    325     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    326     exaPrepareAccessGC(pGC);
    327     pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
    328     exaFinishAccessGC(pGC);
    329     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    330     EXA_POST_FALLBACK_GC(pGC);
    331 }
    332 
    333 void
    334 ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
    335                      int x, int y, unsigned int nglyph,
    336                      CharInfoPtr * ppci, void *pglyphBase)
    337 {
    338     EXA_PRE_FALLBACK_GC(pGC);
    339     EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
    340                   exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
    341     exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    342     exaPrepareAccessGC(pGC);
    343     pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
    344     exaFinishAccessGC(pGC);
    345     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    346     EXA_POST_FALLBACK_GC(pGC);
    347 }
    348 
    349 void
    350 ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap,
    351                    DrawablePtr pDrawable, int w, int h, int x, int y)
    352 {
    353     EXA_PRE_FALLBACK_GC(pGC);
    354     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
    355                   exaDrawableLocation(&pBitmap->drawable),
    356                   exaDrawableLocation(pDrawable)));
    357     ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, EXA_PREPARE_DEST, TRUE);
    358     ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
    359                           EXA_PREPARE_SRC, FALSE);
    360     exaPrepareAccessGC(pGC);
    361     pGC->ops->PushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
    362     exaFinishAccessGC(pGC);
    363     exaFinishAccess(&pBitmap->drawable, EXA_PREPARE_SRC);
    364     exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    365     EXA_POST_FALLBACK_GC(pGC);
    366 }
    367 
    368 void
    369 ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
    370 {
    371     DrawablePtr pDrawable = &pWin->drawable;
    372     ScreenPtr pScreen = pDrawable->pScreen;
    373 
    374     EXA_PRE_FALLBACK(pScreen);
    375     EXA_FALLBACK(("from %p\n", pWin));
    376 
    377     /* Only need the source bits, the destination region will be overwritten */
    378     if (pExaScr->prepare_access_reg) {
    379         PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
    380         int xoff, yoff;
    381 
    382         exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
    383         RegionTranslate(prgnSrc, xoff, yoff);
    384         pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
    385         RegionTranslate(prgnSrc, -xoff, -yoff);
    386     }
    387     else
    388         exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
    389 
    390     swap(pExaScr, pScreen, CopyWindow);
    391     pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
    392     swap(pExaScr, pScreen, CopyWindow);
    393     exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
    394     EXA_POST_FALLBACK(pScreen);
    395 }
    396 
    397 void
    398 ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
    399                  unsigned int format, unsigned long planeMask, char *d)
    400 {
    401     ScreenPtr pScreen = pDrawable->pScreen;
    402 
    403     EXA_PRE_FALLBACK(pScreen);
    404     EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    405 
    406     ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, EXA_PREPARE_SRC, FALSE);
    407     swap(pExaScr, pScreen, GetImage);
    408     pScreen->GetImage(pDrawable, x, y, w, h, format, planeMask, d);
    409     swap(pExaScr, pScreen, GetImage);
    410     exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
    411     EXA_POST_FALLBACK(pScreen);
    412 }
    413 
    414 void
    415 ExaCheckGetSpans(DrawablePtr pDrawable,
    416                  int wMax,
    417                  DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
    418 {
    419     ScreenPtr pScreen = pDrawable->pScreen;
    420 
    421     EXA_PRE_FALLBACK(pScreen);
    422     EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    423     exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
    424     swap(pExaScr, pScreen, GetSpans);
    425     pScreen->GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
    426     swap(pExaScr, pScreen, GetSpans);
    427     exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
    428     EXA_POST_FALLBACK(pScreen);
    429 }
    430 
    431 static void
    432 ExaSrcValidate(DrawablePtr pDrawable,
    433                int x, int y, int width, int height, unsigned int subWindowMode)
    434 {
    435     ScreenPtr pScreen = pDrawable->pScreen;
    436 
    437     ExaScreenPriv(pScreen);
    438     PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
    439     BoxRec box;
    440     RegionRec reg;
    441     RegionPtr dst;
    442     int xoff, yoff;
    443 
    444     if (pExaScr->srcPix == pPix)
    445         dst = &pExaScr->srcReg;
    446     else if (pExaScr->maskPix == pPix)
    447         dst = &pExaScr->maskReg;
    448     else
    449         return;
    450 
    451     exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
    452 
    453     box.x1 = x + xoff;
    454     box.y1 = y + yoff;
    455     box.x2 = box.x1 + width;
    456     box.y2 = box.y1 + height;
    457 
    458     RegionInit(&reg, &box, 1);
    459     RegionUnion(dst, dst, &reg);
    460     RegionUninit(&reg);
    461 
    462     swap(pExaScr, pScreen, SourceValidate);
    463     pScreen->SourceValidate(pDrawable, x, y, width, height, subWindowMode);
    464     swap(pExaScr, pScreen, SourceValidate);
    465 }
    466 
    467 static Bool
    468 ExaPrepareCompositeReg(ScreenPtr pScreen,
    469                        CARD8 op,
    470                        PicturePtr pSrc,
    471                        PicturePtr pMask,
    472                        PicturePtr pDst,
    473                        INT16 xSrc,
    474                        INT16 ySrc,
    475                        INT16 xMask,
    476                        INT16 yMask,
    477                        INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
    478 {
    479     RegionRec region;
    480     RegionPtr dstReg = NULL;
    481     RegionPtr srcReg = NULL;
    482     RegionPtr maskReg = NULL;
    483     PixmapPtr pSrcPix = NULL;
    484     PixmapPtr pMaskPix = NULL;
    485     PixmapPtr pDstPix;
    486 
    487     ExaScreenPriv(pScreen);
    488     Bool ret;
    489 
    490     RegionNull(&region);
    491 
    492     if (pSrc->pDrawable) {
    493         pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
    494         RegionNull(&pExaScr->srcReg);
    495         srcReg = &pExaScr->srcReg;
    496         pExaScr->srcPix = pSrcPix;
    497         if (pSrc != pDst)
    498             RegionTranslate(pSrc->pCompositeClip,
    499                             -pSrc->pDrawable->x, -pSrc->pDrawable->y);
    500     } else
    501         pExaScr->srcPix = NULL;
    502 
    503     if (pMask && pMask->pDrawable) {
    504         pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
    505         RegionNull(&pExaScr->maskReg);
    506         maskReg = &pExaScr->maskReg;
    507         pExaScr->maskPix = pMaskPix;
    508         if (pMask != pDst && pMask != pSrc)
    509             RegionTranslate(pMask->pCompositeClip,
    510                             -pMask->pDrawable->x, -pMask->pDrawable->y);
    511     } else
    512         pExaScr->maskPix = NULL;
    513 
    514     RegionTranslate(pDst->pCompositeClip,
    515                     -pDst->pDrawable->x, -pDst->pDrawable->y);
    516 
    517     pExaScr->SavedSourceValidate = ExaSrcValidate;
    518     swap(pExaScr, pScreen, SourceValidate);
    519     ret = miComputeCompositeRegion(&region, pSrc, pMask, pDst,
    520                                    xSrc, ySrc, xMask, yMask,
    521                                    xDst, yDst, width, height);
    522     swap(pExaScr, pScreen, SourceValidate);
    523 
    524     RegionTranslate(pDst->pCompositeClip,
    525                     pDst->pDrawable->x, pDst->pDrawable->y);
    526     if (pSrc->pDrawable && pSrc != pDst)
    527         RegionTranslate(pSrc->pCompositeClip,
    528                         pSrc->pDrawable->x, pSrc->pDrawable->y);
    529     if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
    530         RegionTranslate(pMask->pCompositeClip,
    531                         pMask->pDrawable->x, pMask->pDrawable->y);
    532 
    533     if (!ret) {
    534         if (srcReg)
    535             RegionUninit(srcReg);
    536         if (maskReg)
    537             RegionUninit(maskReg);
    538 
    539         return FALSE;
    540     }
    541 
    542     /**
    543      * Don't limit alphamaps readbacks for now until we've figured out how that
    544      * should be done.
    545      */
    546 
    547     if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
    548         pExaScr->
    549             prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
    550                                EXA_PREPARE_AUX_SRC, NULL);
    551     if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
    552         pExaScr->
    553             prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
    554                                EXA_PREPARE_AUX_MASK, NULL);
    555 
    556     if (pSrcPix)
    557         pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg);
    558 
    559     if (pMaskPix)
    560         pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg);
    561 
    562     if (srcReg)
    563         RegionUninit(srcReg);
    564     if (maskReg)
    565         RegionUninit(maskReg);
    566 
    567     pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
    568     if (!exaOpReadsDestination(op)) {
    569         int xoff;
    570         int yoff;
    571 
    572         exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff);
    573         RegionTranslate(&region, pDst->pDrawable->x + xoff,
    574                         pDst->pDrawable->y + yoff);
    575         dstReg = &region;
    576     }
    577 
    578     if (pDst->alphaMap && pDst->alphaMap->pDrawable)
    579         pExaScr->
    580             prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
    581                                EXA_PREPARE_AUX_DEST, dstReg);
    582     pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
    583 
    584     RegionUninit(&region);
    585     return TRUE;
    586 }
    587 
    588 void
    589 ExaCheckComposite(CARD8 op,
    590                   PicturePtr pSrc,
    591                   PicturePtr pMask,
    592                   PicturePtr pDst,
    593                   INT16 xSrc,
    594                   INT16 ySrc,
    595                   INT16 xMask,
    596                   INT16 yMask,
    597                   INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
    598 {
    599     ScreenPtr pScreen = pDst->pDrawable->pScreen;
    600     PictureScreenPtr ps = GetPictureScreen(pScreen);
    601 
    602     EXA_PRE_FALLBACK(pScreen);
    603 
    604     if (pExaScr->prepare_access_reg) {
    605         if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
    606                                     ySrc, xMask, yMask, xDst, yDst, width,
    607                                     height))
    608             goto out_no_clip;
    609     }
    610     else {
    611 
    612         /* We need to prepare access to any separate alpha maps first,
    613          * in case the driver doesn't support EXA_PREPARE_AUX*,
    614          * in which case EXA_PREPARE_SRC may be used for moving them out.
    615          */
    616 
    617         if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
    618             exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
    619         if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
    620             exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
    621         if (pDst->alphaMap && pDst->alphaMap->pDrawable)
    622             exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
    623 
    624         exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST);
    625 
    626         EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));
    627 
    628         if (pSrc->pDrawable != NULL)
    629             exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
    630         if (pMask && pMask->pDrawable != NULL)
    631             exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK);
    632     }
    633 
    634     swap(pExaScr, ps, Composite);
    635     ps->Composite(op,
    636                   pSrc,
    637                   pMask,
    638                   pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
    639     swap(pExaScr, ps, Composite);
    640     if (pMask && pMask->pDrawable != NULL)
    641         exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK);
    642     if (pSrc->pDrawable != NULL)
    643         exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
    644     exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST);
    645     if (pDst->alphaMap && pDst->alphaMap->pDrawable)
    646         exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
    647     if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
    648         exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
    649     if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
    650         exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
    651 
    652  out_no_clip:
    653     EXA_POST_FALLBACK(pScreen);
    654 }
    655 
    656 /**
    657  * Avoid migration ping-pong when using a mask.
    658  */
    659 void
    660 ExaCheckGlyphs(CARD8 op,
    661                PicturePtr pSrc,
    662                PicturePtr pDst,
    663                PictFormatPtr maskFormat,
    664                INT16 xSrc,
    665                INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
    666 {
    667     ScreenPtr pScreen = pDst->pDrawable->pScreen;
    668 
    669     EXA_PRE_FALLBACK(pScreen);
    670 
    671     miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    672 
    673     EXA_POST_FALLBACK(pScreen);
    674 }
    675 
    676 void
    677 ExaCheckAddTraps(PicturePtr pPicture,
    678                  INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
    679 {
    680     ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    681     PictureScreenPtr ps = GetPictureScreen(pScreen);
    682 
    683     EXA_PRE_FALLBACK(pScreen);
    684 
    685     EXA_FALLBACK(("to pict %p (%c)\n", pPicture,
    686                   exaDrawableLocation(pPicture->pDrawable)));
    687     exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
    688     swap(pExaScr, ps, AddTraps);
    689     ps->AddTraps(pPicture, x_off, y_off, ntrap, traps);
    690     swap(pExaScr, ps, AddTraps);
    691     exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
    692     EXA_POST_FALLBACK(pScreen);
    693 }
    694 
    695 /**
    696  * Gets the 0,0 pixel of a pixmap.  Used for doing solid fills of tiled pixmaps
    697  * that happen to be 1x1.  Pixmap must be at least 8bpp.
    698  */
    699 CARD32
    700 exaGetPixmapFirstPixel(PixmapPtr pPixmap)
    701 {
    702     switch (pPixmap->drawable.bitsPerPixel) {
    703     case 32:
    704     {
    705         CARD32 pixel;
    706 
    707         pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
    708                                             ZPixmap, ~0, (char *) &pixel);
    709         return pixel;
    710     }
    711     case 16:
    712     {
    713         CARD16 pixel;
    714 
    715         pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
    716                                             ZPixmap, ~0, (char *) &pixel);
    717         return pixel;
    718     }
    719     case 8:
    720     case 4:
    721     case 1:
    722     {
    723         CARD8 pixel;
    724 
    725         pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
    726                                             ZPixmap, ~0, (char *) &pixel);
    727         return pixel;
    728     }
    729     default:
    730         FatalError("%s called for invalid bpp %d\n", __func__,
    731                    pPixmap->drawable.bitsPerPixel);
    732     }
    733 }