exa_unaccel.c revision 8223e2f2
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 ExaPixmapPriv(pPixmap); 104 105 EXA_PRE_FALLBACK_GC(pGC); 106 EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); 107 if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage || 108 exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, 109 pGC->alu, pGC->clientClipType)) 110 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 111 else 112 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, 113 DamagePendingRegion(pExaPixmap->pDamage)); 114 pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); 115 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 116 EXA_POST_FALLBACK_GC(pGC); 117} 118 119void 120ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 121 BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, 122 Bool upsidedown, Pixel bitplane, void *closure) 123{ 124 RegionRec reg; 125 int xoff, yoff; 126 EXA_PRE_FALLBACK_GC(pGC); 127 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, 128 exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); 129 130 if (pExaScr->prepare_access_reg) { 131 PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc); 132 133 exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); 134 RegionInit(®, pbox, nbox); 135 RegionTranslate(®, xoff + dx, yoff + dy); 136 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); 137 RegionUninit(®); 138 } else 139 exaPrepareAccess (pSrc, EXA_PREPARE_SRC); 140 141 if (pExaScr->prepare_access_reg && 142 !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle, 143 pGC->alu, pGC->clientClipType)) { 144 PixmapPtr pPixmap = exaGetDrawablePixmap(pDst); 145 146 exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); 147 RegionInit(®, pbox, nbox); 148 RegionTranslate(®, xoff, yoff); 149 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); 150 RegionUninit(®); 151 } else 152 exaPrepareAccess (pDst, EXA_PREPARE_DEST); 153 154 /* This will eventually call fbCopyNtoN, with some calculation overhead. */ 155 while (nbox--) { 156 pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, 157 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y); 158 pbox++; 159 } 160 exaFinishAccess (pSrc, EXA_PREPARE_SRC); 161 exaFinishAccess (pDst, EXA_PREPARE_DEST); 162 EXA_POST_FALLBACK_GC(pGC); 163} 164 165static void 166ExaFallbackPrepareReg(DrawablePtr pDrawable, 167 GCPtr pGC, 168 int x, int y, int width, int height, 169 int index, Bool checkReads) 170{ 171 ScreenPtr pScreen = pDrawable->pScreen; 172 ExaScreenPriv(pScreen); 173 174 if (pExaScr->prepare_access_reg && 175 !(checkReads && exaGCReadsDestination(pDrawable, 176 pGC->planemask, 177 pGC->fillStyle, 178 pGC->alu, 179 pGC->clientClipType))) { 180 BoxRec box; 181 RegionRec reg; 182 int xoff, yoff; 183 PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); 184 185 exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); 186 box.x1 = pDrawable->x + x + xoff; 187 box.y1 = pDrawable->y + y + yoff; 188 box.x2 = box.x1 + width; 189 box.y2 = box.y1 + height; 190 191 RegionInit(®, &box, 1); 192 pExaScr->prepare_access_reg(pPixmap, index, ®); 193 RegionUninit(®); 194 } else 195 exaPrepareAccess(pDrawable, index); 196} 197 198 199RegionPtr 200ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 201 int srcx, int srcy, int w, int h, int dstx, int dsty) 202{ 203 RegionPtr ret; 204 205 EXA_PRE_FALLBACK_GC(pGC); 206 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, 207 exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); 208 ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, 209 EXA_PREPARE_SRC, FALSE); 210 ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, 211 EXA_PREPARE_DEST, TRUE); 212 ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); 213 exaFinishAccess (pSrc, EXA_PREPARE_SRC); 214 exaFinishAccess (pDst, EXA_PREPARE_DEST); 215 EXA_POST_FALLBACK_GC(pGC); 216 217 return ret; 218} 219 220RegionPtr 221ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 222 int srcx, int srcy, int w, int h, int dstx, int dsty, 223 unsigned long bitPlane) 224{ 225 RegionPtr ret; 226 227 EXA_PRE_FALLBACK_GC(pGC); 228 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, 229 exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); 230 ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, 231 EXA_PREPARE_SRC, FALSE); 232 ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, 233 EXA_PREPARE_DEST, TRUE); 234 ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, 235 bitPlane); 236 exaFinishAccess (pSrc, EXA_PREPARE_SRC); 237 exaFinishAccess (pDst, EXA_PREPARE_DEST); 238 EXA_POST_FALLBACK_GC(pGC); 239 240 return ret; 241} 242 243void 244ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 245 DDXPointPtr pptInit) 246{ 247 EXA_PRE_FALLBACK_GC(pGC); 248 EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); 249 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 250 pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit); 251 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 252 EXA_POST_FALLBACK_GC(pGC); 253} 254 255void 256ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, 257 int mode, int npt, DDXPointPtr ppt) 258{ 259 EXA_PRE_FALLBACK_GC(pGC); 260 EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", 261 pDrawable, exaDrawableLocation(pDrawable), 262 pGC->lineWidth, mode, npt)); 263 264 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 265 exaPrepareAccessGC (pGC); 266 pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt); 267 exaFinishAccessGC (pGC); 268 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 269 EXA_POST_FALLBACK_GC(pGC); 270} 271 272void 273ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, 274 int nsegInit, xSegment *pSegInit) 275{ 276 EXA_PRE_FALLBACK_GC(pGC); 277 EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, 278 exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit)); 279 280 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 281 exaPrepareAccessGC (pGC); 282 pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit); 283 exaFinishAccessGC (pGC); 284 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 285 EXA_POST_FALLBACK_GC(pGC); 286} 287 288void 289ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, 290 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, pointer pglyphBase) 322{ 323 EXA_PRE_FALLBACK_GC(pGC); 324 EXA_FALLBACK(("to %p (%c)\n", pDrawable, 325 exaDrawableLocation(pDrawable))); 326 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 327 exaPrepareAccessGC (pGC); 328 pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); 329 exaFinishAccessGC (pGC); 330 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 331 EXA_POST_FALLBACK_GC(pGC); 332} 333 334void 335ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, 336 int x, int y, unsigned int nglyph, 337 CharInfoPtr *ppci, pointer pglyphBase) 338{ 339 EXA_PRE_FALLBACK_GC(pGC); 340 EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, 341 exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu)); 342 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 343 exaPrepareAccessGC (pGC); 344 pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); 345 exaFinishAccessGC (pGC); 346 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 347 EXA_POST_FALLBACK_GC(pGC); 348} 349 350void 351ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, 352 DrawablePtr pDrawable, 353 int w, int h, int x, int y) 354{ 355 EXA_PRE_FALLBACK_GC(pGC); 356 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, 357 exaDrawableLocation(&pBitmap->drawable), 358 exaDrawableLocation(pDrawable))); 359 ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, 360 EXA_PREPARE_DEST, TRUE); 361 ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h, 362 EXA_PREPARE_SRC, FALSE); 363 exaPrepareAccessGC (pGC); 364 pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y); 365 exaFinishAccessGC (pGC); 366 exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC); 367 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 368 EXA_POST_FALLBACK_GC(pGC); 369} 370 371void 372ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 373{ 374 DrawablePtr pDrawable = &pWin->drawable; 375 ScreenPtr pScreen = pDrawable->pScreen; 376 EXA_PRE_FALLBACK(pScreen); 377 EXA_FALLBACK(("from %p\n", pWin)); 378 379 /* Only need the source bits, the destination region will be overwritten */ 380 if (pExaScr->prepare_access_reg) { 381 PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin); 382 int xoff, yoff; 383 384 exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff); 385 RegionTranslate(prgnSrc, xoff, yoff); 386 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc); 387 RegionTranslate(prgnSrc, -xoff, -yoff); 388 } else 389 exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); 390 391 swap(pExaScr, pScreen, CopyWindow); 392 pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc); 393 swap(pExaScr, pScreen, CopyWindow); 394 exaFinishAccess (pDrawable, EXA_PREPARE_SRC); 395 EXA_POST_FALLBACK(pScreen); 396} 397 398void 399ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, 400 unsigned int format, unsigned long planeMask, char *d) 401{ 402 ScreenPtr pScreen = pDrawable->pScreen; 403 EXA_PRE_FALLBACK(pScreen); 404 EXA_FALLBACK(("from %p (%c)\n", pDrawable, 405 exaDrawableLocation(pDrawable))); 406 407 ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, 408 EXA_PREPARE_SRC, FALSE); 409 swap(pExaScr, pScreen, GetImage); 410 pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d); 411 swap(pExaScr, pScreen, GetImage); 412 exaFinishAccess (pDrawable, EXA_PREPARE_SRC); 413 EXA_POST_FALLBACK(pScreen); 414} 415 416void 417ExaCheckGetSpans (DrawablePtr pDrawable, 418 int wMax, 419 DDXPointPtr ppt, 420 int *pwidth, 421 int nspans, 422 char *pdstStart) 423{ 424 ScreenPtr pScreen = pDrawable->pScreen; 425 426 EXA_PRE_FALLBACK(pScreen); 427 EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); 428 exaPrepareAccess (pDrawable, EXA_PREPARE_SRC); 429 swap(pExaScr, pScreen, GetSpans); 430 pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 431 swap(pExaScr, pScreen, GetSpans); 432 exaFinishAccess (pDrawable, EXA_PREPARE_SRC); 433 EXA_POST_FALLBACK(pScreen); 434} 435 436static void 437ExaSrcValidate(DrawablePtr pDrawable, 438 int x, 439 int y, 440 int width, 441 int height) 442{ 443 ScreenPtr pScreen = pDrawable->pScreen; 444 ExaScreenPriv(pScreen); 445 PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); 446 BoxRec box; 447 RegionRec reg; 448 RegionPtr dst; 449 int xoff, yoff; 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 dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg : 459 &pExaScr->maskReg; 460 461 RegionInit(®, &box, 1); 462 RegionUnion(dst, dst, ®); 463 RegionUninit(®); 464 465 if (pExaScr->SavedSourceValidate) { 466 swap(pExaScr, pScreen, SourceValidate); 467 pScreen->SourceValidate(pDrawable, x, y, width, height); 468 swap(pExaScr, pScreen, SourceValidate); 469 } 470} 471 472static Bool 473ExaPrepareCompositeReg(ScreenPtr pScreen, 474 CARD8 op, 475 PicturePtr pSrc, 476 PicturePtr pMask, 477 PicturePtr pDst, 478 INT16 xSrc, 479 INT16 ySrc, 480 INT16 xMask, 481 INT16 yMask, 482 INT16 xDst, 483 INT16 yDst, 484 CARD16 width, 485 CARD16 height) 486{ 487 RegionRec region; 488 RegionPtr dstReg = NULL; 489 RegionPtr srcReg = NULL; 490 RegionPtr maskReg = NULL; 491 PixmapPtr pSrcPix = NULL; 492 PixmapPtr pMaskPix = NULL; 493 PixmapPtr pDstPix; 494 ExaScreenPriv(pScreen); 495 Bool ret; 496 497 498 RegionNull(®ion); 499 500 if (pSrc->pDrawable) { 501 pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); 502 RegionNull(&pExaScr->srcReg); 503 srcReg = &pExaScr->srcReg; 504 pExaScr->srcPix = pSrcPix; 505 if (pSrc != pDst) 506 RegionTranslate(pSrc->pCompositeClip, 507 -pSrc->pDrawable->x, 508 -pSrc->pDrawable->y); 509 } 510 511 if (pMask && pMask->pDrawable) { 512 pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); 513 RegionNull(&pExaScr->maskReg); 514 maskReg = &pExaScr->maskReg; 515 if (pMask != pDst && pMask != pSrc) 516 RegionTranslate(pMask->pCompositeClip, 517 -pMask->pDrawable->x, 518 -pMask->pDrawable->y); 519 } 520 521 RegionTranslate(pDst->pCompositeClip, 522 -pDst->pDrawable->x, 523 -pDst->pDrawable->y); 524 525 pExaScr->SavedSourceValidate = ExaSrcValidate; 526 swap(pExaScr, pScreen, SourceValidate); 527 ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 528 xSrc, ySrc, xMask, yMask, 529 xDst, 530 yDst, 531 width, height); 532 swap(pExaScr, pScreen, SourceValidate); 533 534 RegionTranslate(pDst->pCompositeClip, 535 pDst->pDrawable->x, 536 pDst->pDrawable->y); 537 if (pSrc->pDrawable && pSrc != pDst) 538 RegionTranslate(pSrc->pCompositeClip, 539 pSrc->pDrawable->x, 540 pSrc->pDrawable->y); 541 if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) 542 RegionTranslate(pMask->pCompositeClip, 543 pMask->pDrawable->x, 544 pMask->pDrawable->y); 545 546 if (!ret) { 547 if (srcReg) 548 RegionUninit(srcReg); 549 if (maskReg) 550 RegionUninit(maskReg); 551 552 return FALSE; 553 } 554 555 /** 556 * Don't limit alphamaps readbacks for now until we've figured out how that 557 * should be done. 558 */ 559 560 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 561 pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), 562 EXA_PREPARE_AUX_SRC, 563 NULL); 564 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 565 pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), 566 EXA_PREPARE_AUX_MASK, 567 NULL); 568 569 if (pSrcPix) 570 pExaScr->prepare_access_reg(pSrcPix, 571 EXA_PREPARE_SRC, 572 srcReg); 573 574 if (pMaskPix) 575 pExaScr->prepare_access_reg(pMaskPix, 576 EXA_PREPARE_MASK, 577 maskReg); 578 579 if (srcReg) 580 RegionUninit(srcReg); 581 if (maskReg) 582 RegionUninit(maskReg); 583 584 pDstPix = exaGetDrawablePixmap(pDst->pDrawable); 585 if (!exaOpReadsDestination(op)) { 586 int xoff; 587 int yoff; 588 589 exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff); 590 RegionTranslate(®ion, pDst->pDrawable->x + xoff, 591 pDst->pDrawable->y + yoff); 592 dstReg = ®ion; 593 } 594 595 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 596 pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), 597 EXA_PREPARE_AUX_DEST, 598 dstReg); 599 pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); 600 601 RegionUninit(®ion); 602 return TRUE; 603} 604 605void 606ExaCheckComposite (CARD8 op, 607 PicturePtr pSrc, 608 PicturePtr pMask, 609 PicturePtr pDst, 610 INT16 xSrc, 611 INT16 ySrc, 612 INT16 xMask, 613 INT16 yMask, 614 INT16 xDst, 615 INT16 yDst, 616 CARD16 width, 617 CARD16 height) 618{ 619 ScreenPtr pScreen = pDst->pDrawable->pScreen; 620 PictureScreenPtr ps = GetPictureScreen(pScreen); 621 EXA_PRE_FALLBACK(pScreen); 622 623 if (pExaScr->prepare_access_reg) { 624 if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc, 625 ySrc, xMask, yMask, xDst, yDst, width, 626 height)) 627 goto out_no_clip; 628 } else { 629 630 /* We need to prepare access to any separate alpha maps first, 631 * in case the driver doesn't support EXA_PREPARE_AUX*, 632 * in which case EXA_PREPARE_SRC may be used for moving them out. 633 */ 634 635 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 636 exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); 637 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 638 exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); 639 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 640 exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); 641 642 exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST); 643 644 EXA_FALLBACK(("from picts %p/%p to pict %p\n", 645 pSrc, pMask, pDst)); 646 647 if (pSrc->pDrawable != NULL) 648 exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC); 649 if (pMask && pMask->pDrawable != NULL) 650 exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK); 651 } 652 653 swap(pExaScr, ps, Composite); 654 ps->Composite (op, 655 pSrc, 656 pMask, 657 pDst, 658 xSrc, 659 ySrc, 660 xMask, 661 yMask, 662 xDst, 663 yDst, 664 width, 665 height); 666 swap(pExaScr, ps, Composite); 667 if (pMask && pMask->pDrawable != NULL) 668 exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK); 669 if (pSrc->pDrawable != NULL) 670 exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); 671 exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); 672 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 673 exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); 674 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 675 exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); 676 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 677 exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); 678 679out_no_clip: 680 EXA_POST_FALLBACK(pScreen); 681} 682 683/** 684 * Avoid migration ping-pong when using a mask. 685 */ 686void 687ExaCheckGlyphs (CARD8 op, 688 PicturePtr pSrc, 689 PicturePtr pDst, 690 PictFormatPtr maskFormat, 691 INT16 xSrc, 692 INT16 ySrc, 693 int nlist, 694 GlyphListPtr list, 695 GlyphPtr *glyphs) 696{ 697 ScreenPtr pScreen = pDst->pDrawable->pScreen; 698 EXA_PRE_FALLBACK(pScreen); 699 700 miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 701 702 EXA_POST_FALLBACK(pScreen); 703} 704 705void 706ExaCheckAddTraps (PicturePtr pPicture, 707 INT16 x_off, 708 INT16 y_off, 709 int ntrap, 710 xTrap *traps) 711{ 712 ScreenPtr pScreen = pPicture->pDrawable->pScreen; 713 PictureScreenPtr ps = GetPictureScreen(pScreen); 714 EXA_PRE_FALLBACK(pScreen); 715 716 EXA_FALLBACK(("to pict %p (%c)\n", 717 exaDrawableLocation(pPicture->pDrawable))); 718 exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 719 swap(pExaScr, ps, AddTraps); 720 ps->AddTraps (pPicture, x_off, y_off, ntrap, traps); 721 swap(pExaScr, ps, AddTraps); 722 exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 723 EXA_POST_FALLBACK(pScreen); 724} 725 726/** 727 * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps 728 * that happen to be 1x1. Pixmap must be at least 8bpp. 729 */ 730CARD32 731exaGetPixmapFirstPixel (PixmapPtr pPixmap) 732{ 733 switch (pPixmap->drawable.bitsPerPixel) { 734 case 32: 735 { 736 CARD32 pixel; 737 738 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 739 ZPixmap, ~0, (char*)&pixel); 740 return pixel; 741 } 742 case 16: 743 { 744 CARD16 pixel; 745 746 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 747 ZPixmap, ~0, (char*)&pixel); 748 return pixel; 749 } 750 case 8: 751 case 4: 752 case 1: 753 { 754 CARD8 pixel; 755 756 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 757 ZPixmap, ~0, (char*)&pixel); 758 return pixel; 759 } 760 default: 761 FatalError("%s called for invalid bpp %d\n", __func__, 762 pPixmap->drawable.bitsPerPixel); 763 } 764} 765