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