exa_unaccel.c revision 9ace9065
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 unsigned int subWindowMode) 443{ 444 ScreenPtr pScreen = pDrawable->pScreen; 445 ExaScreenPriv(pScreen); 446 PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); 447 BoxRec box; 448 RegionRec reg; 449 RegionPtr dst; 450 int xoff, yoff; 451 452 exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); 453 454 box.x1 = x + xoff; 455 box.y1 = y + yoff; 456 box.x2 = box.x1 + width; 457 box.y2 = box.y1 + height; 458 459 dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg : 460 &pExaScr->maskReg; 461 462 RegionInit(®, &box, 1); 463 RegionUnion(dst, dst, ®); 464 RegionUninit(®); 465 466 if (pExaScr->SavedSourceValidate) { 467 swap(pExaScr, pScreen, SourceValidate); 468 pScreen->SourceValidate(pDrawable, x, y, width, height, subWindowMode); 469 swap(pExaScr, pScreen, SourceValidate); 470 } 471} 472 473static Bool 474ExaPrepareCompositeReg(ScreenPtr pScreen, 475 CARD8 op, 476 PicturePtr pSrc, 477 PicturePtr pMask, 478 PicturePtr pDst, 479 INT16 xSrc, 480 INT16 ySrc, 481 INT16 xMask, 482 INT16 yMask, 483 INT16 xDst, 484 INT16 yDst, 485 CARD16 width, 486 CARD16 height) 487{ 488 RegionRec region; 489 RegionPtr dstReg = NULL; 490 RegionPtr srcReg = NULL; 491 RegionPtr maskReg = NULL; 492 PixmapPtr pSrcPix = NULL; 493 PixmapPtr pMaskPix = NULL; 494 PixmapPtr pDstPix; 495 ExaScreenPriv(pScreen); 496 Bool ret; 497 498 499 RegionNull(®ion); 500 501 if (pSrc->pDrawable) { 502 pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); 503 RegionNull(&pExaScr->srcReg); 504 srcReg = &pExaScr->srcReg; 505 pExaScr->srcPix = pSrcPix; 506 if (pSrc != pDst) 507 RegionTranslate(pSrc->pCompositeClip, 508 -pSrc->pDrawable->x, 509 -pSrc->pDrawable->y); 510 } 511 512 if (pMask && pMask->pDrawable) { 513 pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); 514 RegionNull(&pExaScr->maskReg); 515 maskReg = &pExaScr->maskReg; 516 if (pMask != pDst && pMask != pSrc) 517 RegionTranslate(pMask->pCompositeClip, 518 -pMask->pDrawable->x, 519 -pMask->pDrawable->y); 520 } 521 522 RegionTranslate(pDst->pCompositeClip, 523 -pDst->pDrawable->x, 524 -pDst->pDrawable->y); 525 526 pExaScr->SavedSourceValidate = ExaSrcValidate; 527 swap(pExaScr, pScreen, SourceValidate); 528 ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 529 xSrc, ySrc, xMask, yMask, 530 xDst, 531 yDst, 532 width, height); 533 swap(pExaScr, pScreen, SourceValidate); 534 535 RegionTranslate(pDst->pCompositeClip, 536 pDst->pDrawable->x, 537 pDst->pDrawable->y); 538 if (pSrc->pDrawable && pSrc != pDst) 539 RegionTranslate(pSrc->pCompositeClip, 540 pSrc->pDrawable->x, 541 pSrc->pDrawable->y); 542 if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) 543 RegionTranslate(pMask->pCompositeClip, 544 pMask->pDrawable->x, 545 pMask->pDrawable->y); 546 547 if (!ret) { 548 if (srcReg) 549 RegionUninit(srcReg); 550 if (maskReg) 551 RegionUninit(maskReg); 552 553 return FALSE; 554 } 555 556 /** 557 * Don't limit alphamaps readbacks for now until we've figured out how that 558 * should be done. 559 */ 560 561 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 562 pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), 563 EXA_PREPARE_AUX_SRC, 564 NULL); 565 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 566 pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), 567 EXA_PREPARE_AUX_MASK, 568 NULL); 569 570 if (pSrcPix) 571 pExaScr->prepare_access_reg(pSrcPix, 572 EXA_PREPARE_SRC, 573 srcReg); 574 575 if (pMaskPix) 576 pExaScr->prepare_access_reg(pMaskPix, 577 EXA_PREPARE_MASK, 578 maskReg); 579 580 if (srcReg) 581 RegionUninit(srcReg); 582 if (maskReg) 583 RegionUninit(maskReg); 584 585 pDstPix = exaGetDrawablePixmap(pDst->pDrawable); 586 if (!exaOpReadsDestination(op)) { 587 int xoff; 588 int yoff; 589 590 exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff); 591 RegionTranslate(®ion, pDst->pDrawable->x + xoff, 592 pDst->pDrawable->y + yoff); 593 dstReg = ®ion; 594 } 595 596 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 597 pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), 598 EXA_PREPARE_AUX_DEST, 599 dstReg); 600 pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); 601 602 RegionUninit(®ion); 603 return TRUE; 604} 605 606void 607ExaCheckComposite (CARD8 op, 608 PicturePtr pSrc, 609 PicturePtr pMask, 610 PicturePtr pDst, 611 INT16 xSrc, 612 INT16 ySrc, 613 INT16 xMask, 614 INT16 yMask, 615 INT16 xDst, 616 INT16 yDst, 617 CARD16 width, 618 CARD16 height) 619{ 620 ScreenPtr pScreen = pDst->pDrawable->pScreen; 621 PictureScreenPtr ps = GetPictureScreen(pScreen); 622 EXA_PRE_FALLBACK(pScreen); 623 624 if (pExaScr->prepare_access_reg) { 625 if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc, 626 ySrc, xMask, yMask, xDst, yDst, width, 627 height)) 628 goto out_no_clip; 629 } else { 630 631 /* We need to prepare access to any separate alpha maps first, 632 * in case the driver doesn't support EXA_PREPARE_AUX*, 633 * in which case EXA_PREPARE_SRC may be used for moving them out. 634 */ 635 636 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 637 exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); 638 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 639 exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); 640 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 641 exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); 642 643 exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST); 644 645 EXA_FALLBACK(("from picts %p/%p to pict %p\n", 646 pSrc, pMask, pDst)); 647 648 if (pSrc->pDrawable != NULL) 649 exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC); 650 if (pMask && pMask->pDrawable != NULL) 651 exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK); 652 } 653 654 swap(pExaScr, ps, Composite); 655 ps->Composite (op, 656 pSrc, 657 pMask, 658 pDst, 659 xSrc, 660 ySrc, 661 xMask, 662 yMask, 663 xDst, 664 yDst, 665 width, 666 height); 667 swap(pExaScr, ps, Composite); 668 if (pMask && pMask->pDrawable != NULL) 669 exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK); 670 if (pSrc->pDrawable != NULL) 671 exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); 672 exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); 673 if (pDst->alphaMap && pDst->alphaMap->pDrawable) 674 exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); 675 if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) 676 exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); 677 if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) 678 exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); 679 680out_no_clip: 681 EXA_POST_FALLBACK(pScreen); 682} 683 684/** 685 * Avoid migration ping-pong when using a mask. 686 */ 687void 688ExaCheckGlyphs (CARD8 op, 689 PicturePtr pSrc, 690 PicturePtr pDst, 691 PictFormatPtr maskFormat, 692 INT16 xSrc, 693 INT16 ySrc, 694 int nlist, 695 GlyphListPtr list, 696 GlyphPtr *glyphs) 697{ 698 ScreenPtr pScreen = pDst->pDrawable->pScreen; 699 EXA_PRE_FALLBACK(pScreen); 700 701 miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 702 703 EXA_POST_FALLBACK(pScreen); 704} 705 706void 707ExaCheckAddTraps (PicturePtr pPicture, 708 INT16 x_off, 709 INT16 y_off, 710 int ntrap, 711 xTrap *traps) 712{ 713 ScreenPtr pScreen = pPicture->pDrawable->pScreen; 714 PictureScreenPtr ps = GetPictureScreen(pScreen); 715 EXA_PRE_FALLBACK(pScreen); 716 717 EXA_FALLBACK(("to pict %p (%c)\n", 718 exaDrawableLocation(pPicture->pDrawable))); 719 exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 720 swap(pExaScr, ps, AddTraps); 721 ps->AddTraps (pPicture, x_off, y_off, ntrap, traps); 722 swap(pExaScr, ps, AddTraps); 723 exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 724 EXA_POST_FALLBACK(pScreen); 725} 726 727/** 728 * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps 729 * that happen to be 1x1. Pixmap must be at least 8bpp. 730 */ 731CARD32 732exaGetPixmapFirstPixel (PixmapPtr pPixmap) 733{ 734 switch (pPixmap->drawable.bitsPerPixel) { 735 case 32: 736 { 737 CARD32 pixel; 738 739 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 740 ZPixmap, ~0, (char*)&pixel); 741 return pixel; 742 } 743 case 16: 744 { 745 CARD16 pixel; 746 747 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 748 ZPixmap, ~0, (char*)&pixel); 749 return pixel; 750 } 751 case 8: 752 case 4: 753 case 1: 754 { 755 CARD8 pixel; 756 757 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, 758 ZPixmap, ~0, (char*)&pixel); 759 return pixel; 760 } 761 default: 762 FatalError("%s called for invalid bpp %d\n", __func__, 763 pPixmap->drawable.bitsPerPixel); 764 } 765} 766