exa_unaccel.c revision f7df2e56
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 */ 42void 43exaPrepareAccessGC(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 */ 54void 55exaFinishAccessGC(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 64char 65exaDrawableLocation(DrawablePtr pDrawable) 66{ 67 return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm'; 68} 69#endif /* DEBUG_TRACE_FALL */ 70 71void 72ExaCheckFillSpans(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 85void 86ExaCheckSetSpans(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 97void 98ExaCheckPutImage(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 121void 122ExaCheckCopyNtoN(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(®, pbox, nbox)) { 134 PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc); 135 136 exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); 137 RegionTranslate(®, xoff + dx, yoff + dy); 138 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); 139 RegionUninit(®); 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(®, pbox, nbox)) { 148 PixmapPtr pPixmap = exaGetDrawablePixmap(pDst); 149 150 exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff); 151 RegionTranslate(®, xoff, yoff); 152 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); 153 RegionUninit(®); 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 171static void 172ExaFallbackPrepareReg(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(®, &box, 1); 197 pExaScr->prepare_access_reg(pPixmap, index, ®); 198 RegionUninit(®); 199 } 200 else 201 exaPrepareAccess(pDrawable, index); 202} 203 204RegionPtr 205ExaCheckCopyArea(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 223RegionPtr 224ExaCheckCopyPlane(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 244void 245ExaCheckPolyPoint(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 256void 257ExaCheckPolylines(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 273void 274ExaCheckPolySegment(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 289void 290ExaCheckPolyArc(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 303void 304ExaCheckPolyFillRect(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 318void 319ExaCheckImageGlyphBlt(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 333void 334ExaCheckPolyGlyphBlt(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 349void 350ExaCheckPushPixels(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 368void 369ExaCheckCopyWindow(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 397void 398ExaCheckGetImage(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 414void 415ExaCheckGetSpans(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 431static void 432ExaSrcValidate(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(®, &box, 1); 459 RegionUnion(dst, dst, ®); 460 RegionUninit(®); 461 462 if (pExaScr->SavedSourceValidate) { 463 swap(pExaScr, pScreen, SourceValidate); 464 pScreen->SourceValidate(pDrawable, x, y, width, height, subWindowMode); 465 swap(pExaScr, pScreen, SourceValidate); 466 } 467} 468 469static Bool 470ExaPrepareCompositeReg(ScreenPtr pScreen, 471 CARD8 op, 472 PicturePtr pSrc, 473 PicturePtr pMask, 474 PicturePtr pDst, 475 INT16 xSrc, 476 INT16 ySrc, 477 INT16 xMask, 478 INT16 yMask, 479 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) 480{ 481 RegionRec region; 482 RegionPtr dstReg = NULL; 483 RegionPtr srcReg = NULL; 484 RegionPtr maskReg = NULL; 485 PixmapPtr pSrcPix = NULL; 486 PixmapPtr pMaskPix = NULL; 487 PixmapPtr pDstPix; 488 489 ExaScreenPriv(pScreen); 490 Bool ret; 491 492 RegionNull(®ion); 493 494 if (pSrc->pDrawable) { 495 pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); 496 RegionNull(&pExaScr->srcReg); 497 srcReg = &pExaScr->srcReg; 498 pExaScr->srcPix = pSrcPix; 499 if (pSrc != pDst) 500 RegionTranslate(pSrc->pCompositeClip, 501 -pSrc->pDrawable->x, -pSrc->pDrawable->y); 502 } else 503 pExaScr->srcPix = NULL; 504 505 if (pMask && pMask->pDrawable) { 506 pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); 507 RegionNull(&pExaScr->maskReg); 508 maskReg = &pExaScr->maskReg; 509 pExaScr->maskPix = pMaskPix; 510 if (pMask != pDst && pMask != pSrc) 511 RegionTranslate(pMask->pCompositeClip, 512 -pMask->pDrawable->x, -pMask->pDrawable->y); 513 } else 514 pExaScr->maskPix = NULL; 515 516 RegionTranslate(pDst->pCompositeClip, 517 -pDst->pDrawable->x, -pDst->pDrawable->y); 518 519 pExaScr->SavedSourceValidate = ExaSrcValidate; 520 swap(pExaScr, pScreen, SourceValidate); 521 ret = miComputeCompositeRegion(®ion, pSrc, pMask, pDst, 522 xSrc, ySrc, xMask, yMask, 523 xDst, yDst, width, height); 524 swap(pExaScr, pScreen, SourceValidate); 525 526 RegionTranslate(pDst->pCompositeClip, 527 pDst->pDrawable->x, pDst->pDrawable->y); 528 if (pSrc->pDrawable && pSrc != pDst) 529 RegionTranslate(pSrc->pCompositeClip, 530 pSrc->pDrawable->x, pSrc->pDrawable->y); 531 if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) 532 RegionTranslate(pMask->pCompositeClip, 533 pMask->pDrawable->x, pMask->pDrawable->y); 534 535 if (!ret) { 536 if (srcReg) 537 RegionUninit(srcReg); 538 if (maskReg) 539 RegionUninit(maskReg); 540 541 return FALSE; 542 } 543 544 /** 545 * Don't limit alphamaps readbacks for now until we've figured out how that 546 * should be done. 547 */ 548 549 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 550 pExaScr-> 551 prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), 552 EXA_PREPARE_AUX_SRC, NULL); 553 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 554 pExaScr-> 555 prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), 556 EXA_PREPARE_AUX_MASK, NULL); 557 558 if (pSrcPix) 559 pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg); 560 561 if (pMaskPix) 562 pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg); 563 564 if (srcReg) 565 RegionUninit(srcReg); 566 if (maskReg) 567 RegionUninit(maskReg); 568 569 pDstPix = exaGetDrawablePixmap(pDst->pDrawable); 570 if (!exaOpReadsDestination(op)) { 571 int xoff; 572 int yoff; 573 574 exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff); 575 RegionTranslate(®ion, pDst->pDrawable->x + xoff, 576 pDst->pDrawable->y + yoff); 577 dstReg = ®ion; 578 } 579 580 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 581 pExaScr-> 582 prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), 583 EXA_PREPARE_AUX_DEST, dstReg); 584 pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); 585 586 RegionUninit(®ion); 587 return TRUE; 588} 589 590void 591ExaCheckComposite(CARD8 op, 592 PicturePtr pSrc, 593 PicturePtr pMask, 594 PicturePtr pDst, 595 INT16 xSrc, 596 INT16 ySrc, 597 INT16 xMask, 598 INT16 yMask, 599 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) 600{ 601 ScreenPtr pScreen = pDst->pDrawable->pScreen; 602 PictureScreenPtr ps = GetPictureScreen(pScreen); 603 604 EXA_PRE_FALLBACK(pScreen); 605 606 if (pExaScr->prepare_access_reg) { 607 if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc, 608 ySrc, xMask, yMask, xDst, yDst, width, 609 height)) 610 goto out_no_clip; 611 } 612 else { 613 614 /* We need to prepare access to any separate alpha maps first, 615 * in case the driver doesn't support EXA_PREPARE_AUX*, 616 * in which case EXA_PREPARE_SRC may be used for moving them out. 617 */ 618 619 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 620 exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); 621 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 622 exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); 623 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 624 exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); 625 626 exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST); 627 628 EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst)); 629 630 if (pSrc->pDrawable != NULL) 631 exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC); 632 if (pMask && pMask->pDrawable != NULL) 633 exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK); 634 } 635 636 swap(pExaScr, ps, Composite); 637 ps->Composite(op, 638 pSrc, 639 pMask, 640 pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); 641 swap(pExaScr, ps, Composite); 642 if (pMask && pMask->pDrawable != NULL) 643 exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK); 644 if (pSrc->pDrawable != NULL) 645 exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC); 646 exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST); 647 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 648 exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); 649 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 650 exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); 651 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 652 exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); 653 654 out_no_clip: 655 EXA_POST_FALLBACK(pScreen); 656} 657 658/** 659 * Avoid migration ping-pong when using a mask. 660 */ 661void 662ExaCheckGlyphs(CARD8 op, 663 PicturePtr pSrc, 664 PicturePtr pDst, 665 PictFormatPtr maskFormat, 666 INT16 xSrc, 667 INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) 668{ 669 ScreenPtr pScreen = pDst->pDrawable->pScreen; 670 671 EXA_PRE_FALLBACK(pScreen); 672 673 miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 674 675 EXA_POST_FALLBACK(pScreen); 676} 677 678void 679ExaCheckAddTraps(PicturePtr pPicture, 680 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) 681{ 682 ScreenPtr pScreen = pPicture->pDrawable->pScreen; 683 PictureScreenPtr ps = GetPictureScreen(pScreen); 684 685 EXA_PRE_FALLBACK(pScreen); 686 687 EXA_FALLBACK(("to pict %p (%c)\n", pPicture, 688 exaDrawableLocation(pPicture->pDrawable))); 689 exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 690 swap(pExaScr, ps, AddTraps); 691 ps->AddTraps(pPicture, x_off, y_off, ntrap, traps); 692 swap(pExaScr, ps, AddTraps); 693 exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 694 EXA_POST_FALLBACK(pScreen); 695} 696 697/** 698 * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps 699 * that happen to be 1x1. Pixmap must be at least 8bpp. 700 */ 701CARD32 702exaGetPixmapFirstPixel(PixmapPtr pPixmap) 703{ 704 switch (pPixmap->drawable.bitsPerPixel) { 705 case 32: 706 { 707 CARD32 pixel; 708 709 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 710 ZPixmap, ~0, (char *) &pixel); 711 return pixel; 712 } 713 case 16: 714 { 715 CARD16 pixel; 716 717 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 718 ZPixmap, ~0, (char *) &pixel); 719 return pixel; 720 } 721 case 8: 722 case 4: 723 case 1: 724 { 725 CARD8 pixel; 726 727 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 728 ZPixmap, ~0, (char *) &pixel); 729 return pixel; 730 } 731 default: 732 FatalError("%s called for invalid bpp %d\n", __func__, 733 pPixmap->drawable.bitsPerPixel); 734 } 735} 736