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