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(&reg, pbox, nbox);
135	RegionTranslate(&reg, xoff + dx, yoff + dy);
136	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
137	RegionUninit(&reg);
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(&reg, pbox, nbox);
148	RegionTranslate(&reg, xoff, yoff);
149	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
150	RegionUninit(&reg);
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(&reg, &box, 1);
192	pExaScr->prepare_access_reg(pPixmap, index, &reg);
193	RegionUninit(&reg);
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(&reg, &box, 1);
463    RegionUnion(dst, dst, &reg);
464    RegionUninit(&reg);
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(&region);
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 (&region, 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(&region, pDst->pDrawable->x + xoff,
592			 pDst->pDrawable->y + yoff);
593	dstReg = &region;
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(&region);
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