1d514b0f3Smrg/*
2d514b0f3Smrg *
3d514b0f3Smrg * Copyright © 1999 Keith Packard
4d514b0f3Smrg *
5d514b0f3Smrg * Permission to use, copy, modify, distribute, and sell this software and its
6d514b0f3Smrg * documentation for any purpose is hereby granted without fee, provided that
7d514b0f3Smrg * the above copyright notice appear in all copies and that both that
8d514b0f3Smrg * copyright notice and this permission notice appear in supporting
9d514b0f3Smrg * documentation, and that the name of Keith Packard not be used in
10d514b0f3Smrg * advertising or publicity pertaining to distribution of the software without
11d514b0f3Smrg * specific, written prior permission.  Keith Packard makes no
12d514b0f3Smrg * representations about the suitability of this software for any purpose.  It
13d514b0f3Smrg * is provided "as is" without express or implied warranty.
14d514b0f3Smrg *
15d514b0f3Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16d514b0f3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17d514b0f3Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18d514b0f3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19d514b0f3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20d514b0f3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21d514b0f3Smrg * PERFORMANCE OF THIS SOFTWARE.
22d514b0f3Smrg */
23d514b0f3Smrg
24d514b0f3Smrg#include "uxa-priv.h"
25d514b0f3Smrg#include "uxa-damage.h"
26d514b0f3Smrg
27d514b0f3Smrg#ifdef RENDER
28d514b0f3Smrg#include "mipict.h"
29d514b0f3Smrg#endif
30d514b0f3Smrg
31d514b0f3Smrg/*
32d514b0f3Smrg * These functions wrap the low-level fb rendering functions and
33d514b0f3Smrg * synchronize framebuffer/accelerated drawing by stalling until
34d514b0f3Smrg * the accelerator is idle
35d514b0f3Smrg */
36d514b0f3Smrg
37d514b0f3Smrg/**
38d514b0f3Smrg * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
39d514b0f3Smrg * current fill style.
40d514b0f3Smrg *
41d514b0f3Smrg * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
42d514b0f3Smrg * 1bpp and never in fb, so we don't worry about them.
43d514b0f3Smrg * We should worry about them for completeness sake and going forward.
44d514b0f3Smrg */
45d514b0f3SmrgBool uxa_prepare_access_gc(GCPtr pGC)
46d514b0f3Smrg{
47d514b0f3Smrg	if (pGC->stipple)
48d514b0f3Smrg	    if (!uxa_prepare_access(&pGC->stipple->drawable, NULL, UXA_ACCESS_RO))
49d514b0f3Smrg			return FALSE;
50d514b0f3Smrg	if (pGC->fillStyle == FillTiled)
51d514b0f3Smrg		if (!uxa_prepare_access
52d514b0f3Smrg		    (&pGC->tile.pixmap->drawable, NULL, UXA_ACCESS_RO)) {
53d514b0f3Smrg			if (pGC->stipple)
54d514b0f3Smrg				uxa_finish_access(&pGC->stipple->drawable);
55d514b0f3Smrg			return FALSE;
56d514b0f3Smrg		}
57d514b0f3Smrg	return TRUE;
58d514b0f3Smrg}
59d514b0f3Smrg
60d514b0f3Smrg/**
61d514b0f3Smrg * Finishes access to the tile in the GC, if used.
62d514b0f3Smrg */
63d514b0f3Smrgvoid uxa_finish_access_gc(GCPtr pGC)
64d514b0f3Smrg{
65d514b0f3Smrg	if (pGC->fillStyle == FillTiled)
66d514b0f3Smrg		uxa_finish_access(&pGC->tile.pixmap->drawable);
67d514b0f3Smrg	if (pGC->stipple)
68d514b0f3Smrg		uxa_finish_access(&pGC->stipple->drawable);
69d514b0f3Smrg}
70d514b0f3Smrg
71d514b0f3Smrgchar uxa_drawable_location(DrawablePtr pDrawable)
72d514b0f3Smrg{
73d514b0f3Smrg	return uxa_drawable_is_offscreen(pDrawable) ? 's' : 'm';
74d514b0f3Smrg}
75d514b0f3Smrg
76d514b0f3Smrgvoid
77d514b0f3Smrguxa_check_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
78d514b0f3Smrg		     DDXPointPtr ppt, int *pwidth, int fSorted)
79d514b0f3Smrg{
80d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
81d514b0f3Smrg	RegionRec region;
82d514b0f3Smrg
83d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
84d514b0f3Smrg	uxa_damage_fill_spans (&region, pDrawable, pGC, nspans,
85d514b0f3Smrg			       ppt, pwidth, fSorted);
86d514b0f3Smrg
87d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
88d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
89d514b0f3Smrg	if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
90d514b0f3Smrg		if (uxa_prepare_access_gc(pGC)) {
91d514b0f3Smrg			fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth,
92d514b0f3Smrg				    fSorted);
93d514b0f3Smrg			uxa_finish_access_gc(pGC);
94d514b0f3Smrg		}
95d514b0f3Smrg		uxa_finish_access(pDrawable);
96d514b0f3Smrg	}
97d514b0f3Smrg
98d514b0f3Smrg	REGION_UNINIT (screen, &region);
99d514b0f3Smrg}
100d514b0f3Smrg
101d514b0f3Smrgvoid
102d514b0f3Smrguxa_check_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
103d514b0f3Smrg		    DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
104d514b0f3Smrg{
105d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
106d514b0f3Smrg
107d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
108d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
109d514b0f3Smrg	if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
110d514b0f3Smrg		fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
111d514b0f3Smrg		uxa_finish_access(pDrawable);
112d514b0f3Smrg	}
113d514b0f3Smrg}
114d514b0f3Smrg
115d514b0f3Smrgvoid
116d514b0f3Smrguxa_check_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth,
117d514b0f3Smrg		    int x, int y, int w, int h, int leftPad, int format,
118d514b0f3Smrg		    char *bits)
119d514b0f3Smrg{
120d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
121d514b0f3Smrg
122d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
123d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
124d514b0f3Smrg	if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
125d514b0f3Smrg		fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
126d514b0f3Smrg			   bits);
127d514b0f3Smrg		uxa_finish_access(pDrawable);
128d514b0f3Smrg	}
129d514b0f3Smrg}
130d514b0f3Smrg
131d514b0f3SmrgRegionPtr
132d514b0f3Smrguxa_check_copy_area(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
133d514b0f3Smrg		    int srcx, int srcy, int w, int h, int dstx, int dsty)
134d514b0f3Smrg{
135d514b0f3Smrg	ScreenPtr screen = pSrc->pScreen;
136d514b0f3Smrg	RegionPtr ret = NULL;
137d514b0f3Smrg	RegionRec src_region;
138d514b0f3Smrg	RegionRec dst_region;
139d514b0f3Smrg	BoxRec src_box = { srcx, srcy, srcx + w, srcy + h };
140d514b0f3Smrg	BoxRec dst_box = { dstx, dsty, dstx + w, dsty + h };
141d514b0f3Smrg
142d514b0f3Smrg	REGION_INIT (screen, &src_region, &src_box, 1);
143d514b0f3Smrg	REGION_INIT (screen, &dst_region, &dst_box, 1);
144d514b0f3Smrg
145d514b0f3Smrg	/* FIXME: Hmm, it's not totally clear what to do in this case. In fact,
146d514b0f3Smrg	 * all cases where more than one drawable can get prepare_access() called
147d514b0f3Smrg	 * on it multiple times is kinda bad.
148d514b0f3Smrg	 */
149d514b0f3Smrg
150d514b0f3Smrg	UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
151d514b0f3Smrg		      uxa_drawable_location(pSrc),
152d514b0f3Smrg		      uxa_drawable_location(pDst)));
153d514b0f3Smrg	if (uxa_prepare_access(pDst, &dst_region, UXA_ACCESS_RW)) {
154d514b0f3Smrg	    if (uxa_prepare_access(pSrc, &src_region, UXA_ACCESS_RO)) {
155d514b0f3Smrg			ret =
156d514b0f3Smrg			    fbCopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx,
157d514b0f3Smrg				       dsty);
158d514b0f3Smrg			uxa_finish_access(pSrc);
159d514b0f3Smrg		}
160d514b0f3Smrg		uxa_finish_access(pDst);
161d514b0f3Smrg	}
162d514b0f3Smrg
163d514b0f3Smrg	REGION_UNINIT (screen, &src_region);
164d514b0f3Smrg	REGION_UNINIT (screen, &dst_region);
165d514b0f3Smrg
166d514b0f3Smrg	return ret;
167d514b0f3Smrg}
168d514b0f3Smrg
169d514b0f3SmrgRegionPtr
170d514b0f3Smrguxa_check_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
171d514b0f3Smrg		     int srcx, int srcy, int w, int h, int dstx, int dsty,
172d514b0f3Smrg		     unsigned long bitPlane)
173d514b0f3Smrg{
174d514b0f3Smrg	ScreenPtr screen = pSrc->pScreen;
175d514b0f3Smrg	RegionPtr ret = NULL;
176d514b0f3Smrg
177d514b0f3Smrg	UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
178d514b0f3Smrg		      uxa_drawable_location(pSrc),
179d514b0f3Smrg		      uxa_drawable_location(pDst)));
180d514b0f3Smrg	if (uxa_prepare_access(pDst, NULL, UXA_ACCESS_RW)) {
181d514b0f3Smrg	    if (uxa_prepare_access(pSrc, NULL, UXA_ACCESS_RO)) {
182d514b0f3Smrg			ret =
183d514b0f3Smrg			    fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx,
184d514b0f3Smrg					dsty, bitPlane);
185d514b0f3Smrg			uxa_finish_access(pSrc);
186d514b0f3Smrg		}
187d514b0f3Smrg		uxa_finish_access(pDst);
188d514b0f3Smrg	}
189d514b0f3Smrg	return ret;
190d514b0f3Smrg}
191d514b0f3Smrg
192d514b0f3Smrgvoid
193d514b0f3Smrguxa_check_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
194d514b0f3Smrg		     DDXPointPtr pptInit)
195d514b0f3Smrg{
196d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
197d514b0f3Smrg
198d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
199d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
200d514b0f3Smrg	if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
201d514b0f3Smrg		fbPolyPoint(pDrawable, pGC, mode, npt, pptInit);
202d514b0f3Smrg		uxa_finish_access(pDrawable);
203d514b0f3Smrg	}
204d514b0f3Smrg}
205d514b0f3Smrg
206d514b0f3Smrgvoid
207d514b0f3Smrguxa_check_poly_lines(DrawablePtr pDrawable, GCPtr pGC,
208d514b0f3Smrg		     int mode, int npt, DDXPointPtr ppt)
209d514b0f3Smrg{
210d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
211d514b0f3Smrg	RegionRec region;
212d514b0f3Smrg
213d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
214d514b0f3Smrg	uxa_damage_poly_lines (&region, pDrawable, pGC, mode, npt, ppt);
215d514b0f3Smrg
216d514b0f3Smrg	UXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
217d514b0f3Smrg		      pDrawable, uxa_drawable_location(pDrawable),
218d514b0f3Smrg		      pGC->lineWidth, mode, npt));
219d514b0f3Smrg
220d514b0f3Smrg	if (pGC->lineWidth == 0) {
221d514b0f3Smrg		if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
222d514b0f3Smrg			if (uxa_prepare_access_gc(pGC)) {
223d514b0f3Smrg				fbPolyLine(pDrawable, pGC, mode, npt, ppt);
224d514b0f3Smrg				uxa_finish_access_gc(pGC);
225d514b0f3Smrg			}
226d514b0f3Smrg			uxa_finish_access(pDrawable);
227d514b0f3Smrg		}
228d514b0f3Smrg		goto out;
229d514b0f3Smrg	}
230d514b0f3Smrg	/* fb calls mi functions in the lineWidth != 0 case. */
231d514b0f3Smrg	fbPolyLine(pDrawable, pGC, mode, npt, ppt);
232d514b0f3Smrg
233d514b0f3Smrg out:
234d514b0f3Smrg	REGION_UNINIT (screen, &region);
235d514b0f3Smrg}
236d514b0f3Smrg
237d514b0f3Smrgvoid
238d514b0f3Smrguxa_check_poly_segment(DrawablePtr pDrawable, GCPtr pGC,
239d514b0f3Smrg		       int nsegInit, xSegment * pSegInit)
240d514b0f3Smrg{
241d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
242d514b0f3Smrg	RegionRec region;
243d514b0f3Smrg
244d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
245d514b0f3Smrg	uxa_damage_poly_segment (&region, pDrawable, pGC, nsegInit, pSegInit);
246d514b0f3Smrg
247d514b0f3Smrg	UXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
248d514b0f3Smrg		      uxa_drawable_location(pDrawable), pGC->lineWidth,
249d514b0f3Smrg		      nsegInit));
250d514b0f3Smrg	if (pGC->lineWidth == 0) {
251d514b0f3Smrg	    if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
252d514b0f3Smrg			if (uxa_prepare_access_gc(pGC)) {
253d514b0f3Smrg				fbPolySegment(pDrawable, pGC, nsegInit,
254d514b0f3Smrg					      pSegInit);
255d514b0f3Smrg				uxa_finish_access_gc(pGC);
256d514b0f3Smrg			}
257d514b0f3Smrg			uxa_finish_access(pDrawable);
258d514b0f3Smrg		}
259d514b0f3Smrg	    goto out;
260d514b0f3Smrg	}
261d514b0f3Smrg
262d514b0f3Smrg	/* fb calls mi functions in the lineWidth != 0 case. */
263d514b0f3Smrg	fbPolySegment(pDrawable, pGC, nsegInit, pSegInit);
264d514b0f3Smrg
265d514b0f3Smrgout:
266d514b0f3Smrg	REGION_UNINIT (screen, &region);
267d514b0f3Smrg}
268d514b0f3Smrg
269d514b0f3Smrgvoid
270d514b0f3Smrguxa_check_poly_arc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs)
271d514b0f3Smrg{
272d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
273d514b0f3Smrg
274d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
275d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
276d514b0f3Smrg
277d514b0f3Smrg	/* Disable this as fbPolyArc can call miZeroPolyArc which in turn
278d514b0f3Smrg	 * can call accelerated functions, that as yet, haven't been notified
279d514b0f3Smrg	 * with uxa_finish_access().
280d514b0f3Smrg	 */
281d514b0f3Smrg#if 0
282d514b0f3Smrg	if (pGC->lineWidth == 0) {
283d514b0f3Smrg		if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
284d514b0f3Smrg			if (uxa_prepare_access_gc(pGC)) {
285d514b0f3Smrg				fbPolyArc(pDrawable, pGC, narcs, pArcs);
286d514b0f3Smrg				uxa_finish_access_gc(pGC);
287d514b0f3Smrg			}
288d514b0f3Smrg			uxa_finish_access(pDrawable);
289d514b0f3Smrg		}
290d514b0f3Smrg		return;
291d514b0f3Smrg	}
292d514b0f3Smrg#endif
293d514b0f3Smrg	miPolyArc(pDrawable, pGC, narcs, pArcs);
294d514b0f3Smrg}
295d514b0f3Smrg
296d514b0f3Smrgvoid
297d514b0f3Smrguxa_check_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC,
298d514b0f3Smrg			 int nrect, xRectangle * prect)
299d514b0f3Smrg{
300d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
301d514b0f3Smrg	RegionRec region;
302d514b0f3Smrg
303d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
304d514b0f3Smrg	uxa_damage_poly_fill_rect (&region, pDrawable, pGC, nrect, prect);
305d514b0f3Smrg
306d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
307d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
308d514b0f3Smrg
309d514b0f3Smrg	if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
310d514b0f3Smrg		if (uxa_prepare_access_gc(pGC)) {
311d514b0f3Smrg			fbPolyFillRect(pDrawable, pGC, nrect, prect);
312d514b0f3Smrg			uxa_finish_access_gc(pGC);
313d514b0f3Smrg		}
314d514b0f3Smrg		uxa_finish_access(pDrawable);
315d514b0f3Smrg	}
316d514b0f3Smrg
317d514b0f3Smrg	REGION_UNINIT (screen, &region);
318d514b0f3Smrg}
319d514b0f3Smrg
320d514b0f3Smrgvoid
321d514b0f3Smrguxa_check_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
322d514b0f3Smrg			  int x, int y, unsigned int nglyph,
323d514b0f3Smrg			  CharInfoPtr * ppci, pointer pglyphBase)
324d514b0f3Smrg{
325d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
326d514b0f3Smrg	RegionRec region;
327d514b0f3Smrg
328d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
329d514b0f3Smrg	uxa_damage_image_glyph_blt (&region, pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
330d514b0f3Smrg
331d514b0f3Smrg	UXA_FALLBACK(("to %p (%c)\n", pDrawable,
332d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
333d514b0f3Smrg	if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
334d514b0f3Smrg		if (uxa_prepare_access_gc(pGC)) {
335d514b0f3Smrg			fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
336d514b0f3Smrg					pglyphBase);
337d514b0f3Smrg			uxa_finish_access_gc(pGC);
338d514b0f3Smrg		}
339d514b0f3Smrg		uxa_finish_access(pDrawable);
340d514b0f3Smrg	}
341d514b0f3Smrg
342d514b0f3Smrg	REGION_UNINIT (screen, &region);
343d514b0f3Smrg}
344d514b0f3Smrg
345d514b0f3Smrgvoid
346d514b0f3Smrguxa_check_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
347d514b0f3Smrg			 int x, int y, unsigned int nglyph,
348d514b0f3Smrg			 CharInfoPtr * ppci, pointer pglyphBase)
349d514b0f3Smrg{
350d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
351d514b0f3Smrg	RegionRec region;
352d514b0f3Smrg
353d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
354d514b0f3Smrg	uxa_damage_poly_glyph_blt (&region, pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
355d514b0f3Smrg
356d514b0f3Smrg	UXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
357d514b0f3Smrg		      uxa_drawable_location(pDrawable), pGC->fillStyle,
358d514b0f3Smrg		      pGC->alu));
359d514b0f3Smrg	if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
360d514b0f3Smrg		if (uxa_prepare_access_gc(pGC)) {
361d514b0f3Smrg			fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
362d514b0f3Smrg				       pglyphBase);
363d514b0f3Smrg			uxa_finish_access_gc(pGC);
364d514b0f3Smrg		}
365d514b0f3Smrg		uxa_finish_access(pDrawable);
366d514b0f3Smrg	}
367d514b0f3Smrg
368d514b0f3Smrg	REGION_UNINIT (screen, &region);
369d514b0f3Smrg}
370d514b0f3Smrg
371d514b0f3Smrgvoid
372d514b0f3Smrguxa_check_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
373d514b0f3Smrg		      DrawablePtr pDrawable, int w, int h, int x, int y)
374d514b0f3Smrg{
375d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
376d514b0f3Smrg	RegionRec region;
377d514b0f3Smrg
378d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
379d514b0f3Smrg	uxa_damage_push_pixels (&region, pGC, pBitmap, pDrawable, w, h, x, y);
380d514b0f3Smrg
381d514b0f3Smrg	UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
382d514b0f3Smrg		      uxa_drawable_location(&pBitmap->drawable),
383d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
384d514b0f3Smrg	if (uxa_prepare_access(pDrawable, &region, UXA_ACCESS_RW)) {
385d514b0f3Smrg	    if (uxa_prepare_access(&pBitmap->drawable, NULL, UXA_ACCESS_RO)) {
386d514b0f3Smrg			if (uxa_prepare_access_gc(pGC)) {
387d514b0f3Smrg				fbPushPixels(pGC, pBitmap, pDrawable, w, h, x,
388d514b0f3Smrg					     y);
389d514b0f3Smrg				uxa_finish_access_gc(pGC);
390d514b0f3Smrg			}
391d514b0f3Smrg			uxa_finish_access(&pBitmap->drawable);
392d514b0f3Smrg		}
393d514b0f3Smrg		uxa_finish_access(pDrawable);
394d514b0f3Smrg	}
395d514b0f3Smrg
396d514b0f3Smrg	REGION_UNINIT (screen, &region);
397d514b0f3Smrg}
398d514b0f3Smrg
399d514b0f3Smrgvoid
400d514b0f3Smrguxa_check_get_spans(DrawablePtr pDrawable,
401d514b0f3Smrg		    int wMax,
402d514b0f3Smrg		    DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
403d514b0f3Smrg{
404d514b0f3Smrg	ScreenPtr screen = pDrawable->pScreen;
405d514b0f3Smrg
406d514b0f3Smrg	UXA_FALLBACK(("from %p (%c)\n", pDrawable,
407d514b0f3Smrg		      uxa_drawable_location(pDrawable)));
408d514b0f3Smrg	if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RO)) {
409d514b0f3Smrg		fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
410d514b0f3Smrg		uxa_finish_access(pDrawable);
411d514b0f3Smrg	}
412d514b0f3Smrg}
413d514b0f3Smrg
414d514b0f3Smrgvoid
415d514b0f3Smrguxa_check_composite(CARD8 op,
416d514b0f3Smrg		    PicturePtr pSrc,
417d514b0f3Smrg		    PicturePtr pMask,
418d514b0f3Smrg		    PicturePtr pDst,
419d514b0f3Smrg		    INT16 xSrc, INT16 ySrc,
420d514b0f3Smrg		    INT16 xMask, INT16 yMask,
421d514b0f3Smrg		    INT16 xDst, INT16 yDst,
422d514b0f3Smrg		    CARD16 width, CARD16 height)
423d514b0f3Smrg{
424d514b0f3Smrg	ScreenPtr screen = pDst->pDrawable->pScreen;
425d514b0f3Smrg	RegionRec region;
426d514b0f3Smrg
427d514b0f3Smrg	UXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));
428d514b0f3Smrg
429d514b0f3Smrg	REGION_INIT (screen, &region, (BoxPtr)NULL, 0);
430d514b0f3Smrg	uxa_damage_composite (&region, op, pSrc, pMask, pDst,
431d514b0f3Smrg			      xSrc, ySrc, xMask, yMask, xDst, yDst,
432d514b0f3Smrg			      width, height);
433d514b0f3Smrg
434d514b0f3Smrg#if 0
435d514b0f3Smrg	ErrorF ("destination: %p\n", pDst->pDrawable);
436d514b0f3Smrg	ErrorF ("source: %p\n", pSrc->pDrawable);
437d514b0f3Smrg	ErrorF ("mask: %p\n", pMask? pMask->pDrawable : NULL);
438d514b0f3Smrg#endif
439d514b0f3Smrg	if (uxa_prepare_access(pDst->pDrawable, &region, UXA_ACCESS_RW)) {
440d514b0f3Smrg		if (pSrc->pDrawable == NULL ||
441d514b0f3Smrg		    uxa_prepare_access(pSrc->pDrawable, NULL, UXA_ACCESS_RO)) {
442d514b0f3Smrg			if (!pMask || pMask->pDrawable == NULL ||
443d514b0f3Smrg			    uxa_prepare_access(pMask->pDrawable, NULL, UXA_ACCESS_RO))
444d514b0f3Smrg			{
445d514b0f3Smrg				fbComposite(op, pSrc, pMask, pDst,
446d514b0f3Smrg					    xSrc, ySrc,
447d514b0f3Smrg					    xMask, yMask,
448d514b0f3Smrg					    xDst, yDst,
449d514b0f3Smrg					    width, height);
450d514b0f3Smrg				if (pMask && pMask->pDrawable != NULL)
451d514b0f3Smrg					uxa_finish_access(pMask->pDrawable);
452d514b0f3Smrg			}
453d514b0f3Smrg			if (pSrc->pDrawable != NULL)
454d514b0f3Smrg				uxa_finish_access(pSrc->pDrawable);
455d514b0f3Smrg		}
456d514b0f3Smrg		uxa_finish_access(pDst->pDrawable);
457d514b0f3Smrg	}
458d514b0f3Smrg}
459d514b0f3Smrg
460d514b0f3Smrgvoid
461d514b0f3Smrguxa_check_add_traps(PicturePtr pPicture,
462d514b0f3Smrg		    INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
463d514b0f3Smrg{
464d514b0f3Smrg	ScreenPtr screen = pPicture->pDrawable->pScreen;
465d514b0f3Smrg
466d514b0f3Smrg	UXA_FALLBACK(("to pict %p (%c)\n", pPicture,
467d514b0f3Smrg		      uxa_drawable_location(pPicture->pDrawable)));
468d514b0f3Smrg	if (uxa_prepare_access(pPicture->pDrawable, NULL, UXA_ACCESS_RW)) {
469d514b0f3Smrg		fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
470d514b0f3Smrg		uxa_finish_access(pPicture->pDrawable);
471d514b0f3Smrg	}
472d514b0f3Smrg}
473d514b0f3Smrg
474d514b0f3Smrg/**
475d514b0f3Smrg * Gets the 0,0 pixel of a pixmap.  Used for doing solid fills of tiled pixmaps
476d514b0f3Smrg * that happen to be 1x1.  Pixmap must be at least 8bpp.
477d514b0f3Smrg *
478d514b0f3Smrg * XXX This really belongs in fb, so it can be aware of tiling and etc.
479d514b0f3Smrg */
480d514b0f3SmrgCARD32 uxa_get_pixmap_first_pixel(PixmapPtr pPixmap)
481d514b0f3Smrg{
482d514b0f3Smrg	CARD32 pixel;
483d514b0f3Smrg	void *fb;
484d514b0f3Smrg
485d514b0f3Smrg	if (!uxa_prepare_access(&pPixmap->drawable, NULL, UXA_ACCESS_RO))
486d514b0f3Smrg		return 0;
487d514b0f3Smrg
488d514b0f3Smrg	fb = pPixmap->devPrivate.ptr;
489d514b0f3Smrg
490d514b0f3Smrg	switch (pPixmap->drawable.bitsPerPixel) {
491d514b0f3Smrg	case 32:
492d514b0f3Smrg		pixel = *(CARD32 *) fb;
493d514b0f3Smrg		break;
494d514b0f3Smrg	case 16:
495d514b0f3Smrg		pixel = *(CARD16 *) fb;
496d514b0f3Smrg		break;
497d514b0f3Smrg	default:
498d514b0f3Smrg		pixel = *(CARD8 *) fb;
499d514b0f3Smrg		break;
500d514b0f3Smrg	}
501d514b0f3Smrg	uxa_finish_access(&pPixmap->drawable);
502d514b0f3Smrg
503d514b0f3Smrg	return pixel;
504d514b0f3Smrg}
505