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