xwayland: Add xdg-system-bell support
[xserver.git] / exa / exa_unaccel.c
blobed1401a989f5f534341dbf21faf7df006f78782a
1 /*
3 * Copyright © 1999 Keith Packard
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.
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.
24 #include "exa_priv.h"
26 #include "mipict.h"
29 * These functions wrap the low-level fb rendering functions and
30 * synchronize framebuffer/accelerated drawing by stalling until
31 * the accelerator is idle
34 /**
35 * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
36 * current fill style.
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.
42 void
43 exaPrepareAccessGC(GCPtr pGC)
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);
51 /**
52 * Finishes access to the tile in the GC, if used.
54 void
55 exaFinishAccessGC(GCPtr pGC)
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);
63 #if DEBUG_TRACE_FALL
64 char
65 exaDrawableLocation(DrawablePtr pDrawable)
67 return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
69 #endif /* DEBUG_TRACE_FALL */
71 void
72 ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
73 DDXPointPtr ppt, int *pwidth, int fSorted)
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);
85 void
86 ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
87 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
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);
97 void
98 ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
99 int x, int y, int w, int h, int leftPad, int format,
100 char *bits)
102 PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
104 ExaPixmapPriv(pPixmap);
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);
121 void
122 ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
123 BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
124 Bool upsidedown, Pixel bitplane, void *closure)
126 RegionRec reg;
127 int xoff, yoff;
129 EXA_PRE_FALLBACK_GC(pGC);
130 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
131 exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
133 if (pExaScr->prepare_access_reg && RegionInitBoxes(&reg, pbox, nbox)) {
134 PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
136 exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
137 RegionTranslate(&reg, xoff + dx, yoff + dy);
138 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
139 RegionUninit(&reg);
141 else
142 exaPrepareAccess(pSrc, EXA_PREPARE_SRC);
144 if (pExaScr->prepare_access_reg &&
145 !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
146 pGC->alu, pGC->clientClip != NULL) &&
147 RegionInitBoxes(&reg, pbox, nbox)) {
148 PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
150 exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
151 RegionTranslate(&reg, xoff, yoff);
152 pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
153 RegionUninit(&reg);
155 else
156 exaPrepareAccess(pDst, EXA_PREPARE_DEST);
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++;
166 exaFinishAccess(pSrc, EXA_PREPARE_SRC);
167 exaFinishAccess(pDst, EXA_PREPARE_DEST);
168 EXA_POST_FALLBACK_GC(pGC);
171 static void
172 ExaFallbackPrepareReg(DrawablePtr pDrawable,
173 GCPtr pGC,
174 int x, int y, int width, int height,
175 int index, Bool checkReads)
177 ScreenPtr pScreen = pDrawable->pScreen;
179 ExaScreenPriv(pScreen);
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);
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;
196 RegionInit(&reg, &box, 1);
197 pExaScr->prepare_access_reg(pPixmap, index, &reg);
198 RegionUninit(&reg);
200 else
201 exaPrepareAccess(pDrawable, index);
204 RegionPtr
205 ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
206 int srcx, int srcy, int w, int h, int dstx, int dsty)
208 RegionPtr ret;
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);
220 return ret;
223 RegionPtr
224 ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
225 int srcx, int srcy, int w, int h, int dstx, int dsty,
226 unsigned long bitPlane)
228 RegionPtr ret;
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);
241 return ret;
244 void
245 ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
246 DDXPointPtr pptInit)
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);
256 void
257 ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
258 int mode, int npt, DDXPointPtr ppt)
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));
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);
273 void
274 ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
275 int nsegInit, xSegment * pSegInit)
277 EXA_PRE_FALLBACK_GC(pGC);
278 EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
279 exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
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);
289 void
290 ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs)
292 EXA_PRE_FALLBACK_GC(pGC);
293 EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
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);
303 void
304 ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
305 int nrect, xRectangle *prect)
307 EXA_PRE_FALLBACK_GC(pGC);
308 EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
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);
318 void
319 ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
320 int x, int y, unsigned int nglyph,
321 CharInfoPtr * ppci, void *pglyphBase)
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);
333 void
334 ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
335 int x, int y, unsigned int nglyph,
336 CharInfoPtr * ppci, void *pglyphBase)
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);
349 void
350 ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap,
351 DrawablePtr pDrawable, int w, int h, int x, int y)
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);
368 void
369 ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
371 DrawablePtr pDrawable = &pWin->drawable;
372 ScreenPtr pScreen = pDrawable->pScreen;
374 EXA_PRE_FALLBACK(pScreen);
375 EXA_FALLBACK(("from %p\n", pWin));
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;
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);
387 else
388 exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
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);
397 void
398 ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
399 unsigned int format, unsigned long planeMask, char *d)
401 ScreenPtr pScreen = pDrawable->pScreen;
403 EXA_PRE_FALLBACK(pScreen);
404 EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
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);
414 void
415 ExaCheckGetSpans(DrawablePtr pDrawable,
416 int wMax,
417 DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
419 ScreenPtr pScreen = pDrawable->pScreen;
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);
431 static void
432 ExaSrcValidate(DrawablePtr pDrawable,
433 int x, int y, int width, int height, unsigned int subWindowMode)
435 ScreenPtr pScreen = pDrawable->pScreen;
437 ExaScreenPriv(pScreen);
438 PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
439 BoxRec box;
440 RegionRec reg;
441 RegionPtr dst;
442 int xoff, yoff;
444 if (pExaScr->srcPix == pPix)
445 dst = &pExaScr->srcReg;
446 else if (pExaScr->maskPix == pPix)
447 dst = &pExaScr->maskReg;
448 else
449 return;
451 exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
453 box.x1 = x + xoff;
454 box.y1 = y + yoff;
455 box.x2 = box.x1 + width;
456 box.y2 = box.y1 + height;
458 RegionInit(&reg, &box, 1);
459 RegionUnion(dst, dst, &reg);
460 RegionUninit(&reg);
462 swap(pExaScr, pScreen, SourceValidate);
463 pScreen->SourceValidate(pDrawable, x, y, width, height, subWindowMode);
464 swap(pExaScr, pScreen, SourceValidate);
467 static Bool
468 ExaPrepareCompositeReg(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)
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;
487 ExaScreenPriv(pScreen);
488 Bool ret;
490 RegionNull(&region);
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;
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;
514 RegionTranslate(pDst->pCompositeClip,
515 -pDst->pDrawable->x, -pDst->pDrawable->y);
517 pExaScr->SavedSourceValidate = ExaSrcValidate;
518 swap(pExaScr, pScreen, SourceValidate);
519 ret = miComputeCompositeRegion(&region, pSrc, pMask, pDst,
520 xSrc, ySrc, xMask, yMask,
521 xDst, yDst, width, height);
522 swap(pExaScr, pScreen, SourceValidate);
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);
533 if (!ret) {
534 if (srcReg)
535 RegionUninit(srcReg);
536 if (maskReg)
537 RegionUninit(maskReg);
539 return FALSE;
543 * Don't limit alphamaps readbacks for now until we've figured out how that
544 * should be done.
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);
556 if (pSrcPix)
557 pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg);
559 if (pMaskPix)
560 pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg);
562 if (srcReg)
563 RegionUninit(srcReg);
564 if (maskReg)
565 RegionUninit(maskReg);
567 pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
568 if (!exaOpReadsDestination(op)) {
569 int xoff;
570 int yoff;
572 exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff);
573 RegionTranslate(&region, pDst->pDrawable->x + xoff,
574 pDst->pDrawable->y + yoff);
575 dstReg = &region;
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);
584 RegionUninit(&region);
585 return TRUE;
588 void
589 ExaCheckComposite(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)
599 ScreenPtr pScreen = pDst->pDrawable->pScreen;
600 PictureScreenPtr ps = GetPictureScreen(pScreen);
602 EXA_PRE_FALLBACK(pScreen);
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;
610 else {
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.
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);
624 exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST);
626 EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));
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);
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);
652 out_no_clip:
653 EXA_POST_FALLBACK(pScreen);
657 * Avoid migration ping-pong when using a mask.
659 void
660 ExaCheckGlyphs(CARD8 op,
661 PicturePtr pSrc,
662 PicturePtr pDst,
663 PictFormatPtr maskFormat,
664 INT16 xSrc,
665 INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
667 ScreenPtr pScreen = pDst->pDrawable->pScreen;
669 EXA_PRE_FALLBACK(pScreen);
671 miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
673 EXA_POST_FALLBACK(pScreen);
676 void
677 ExaCheckAddTraps(PicturePtr pPicture,
678 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
680 ScreenPtr pScreen = pPicture->pDrawable->pScreen;
681 PictureScreenPtr ps = GetPictureScreen(pScreen);
683 EXA_PRE_FALLBACK(pScreen);
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);
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.
699 CARD32
700 exaGetPixmapFirstPixel(PixmapPtr pPixmap)
702 switch (pPixmap->drawable.bitsPerPixel) {
703 case 32:
705 CARD32 pixel;
707 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
708 ZPixmap, ~0, (char *) &pixel);
709 return pixel;
711 case 16:
713 CARD16 pixel;
715 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
716 ZPixmap, ~0, (char *) &pixel);
717 return pixel;
719 case 8:
720 case 4:
721 case 1:
723 CARD8 pixel;
725 pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
726 ZPixmap, ~0, (char *) &pixel);
727 return pixel;
729 default:
730 FatalError("%s called for invalid bpp %d\n", __func__,
731 pPixmap->drawable.bitsPerPixel);