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.
27 * These functions wrap the low-level fb rendering functions and
28 * synchronize framebuffer/accelerated drawing by stalling until
29 * the accelerator is idle
33 * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
36 * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
37 * 1bpp and never in fb, so we don't worry about them.
40 exaPrepareAccessGC(GCPtr pGC
)
42 if (pGC
->fillStyle
== FillTiled
)
43 exaPrepareAccess(&pGC
->tile
.pixmap
->drawable
, EXA_PREPARE_SRC
);
47 * Finishes access to the tile in the GC, if used.
50 exaFinishAccessGC(GCPtr pGC
)
52 if (pGC
->fillStyle
== FillTiled
)
53 exaFinishAccess(&pGC
->tile
.pixmap
->drawable
, EXA_PREPARE_SRC
);
58 exaDrawableLocation(DrawablePtr pDrawable
)
60 return exaDrawableIsOffscreen(pDrawable
) ? 's' : 'm';
62 #endif /* DEBUG_TRACE_FALL */
65 ExaCheckFillSpans (DrawablePtr pDrawable
, GCPtr pGC
, int nspans
,
66 DDXPointPtr ppt
, int *pwidth
, int fSorted
)
68 EXA_FALLBACK(("to %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
69 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
70 exaPrepareAccessGC (pGC
);
71 fbFillSpans (pDrawable
, pGC
, nspans
, ppt
, pwidth
, fSorted
);
72 exaFinishAccessGC (pGC
);
73 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
77 ExaCheckSetSpans (DrawablePtr pDrawable
, GCPtr pGC
, char *psrc
,
78 DDXPointPtr ppt
, int *pwidth
, int nspans
, int fSorted
)
80 EXA_FALLBACK(("to %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
81 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
82 fbSetSpans (pDrawable
, pGC
, psrc
, ppt
, pwidth
, nspans
, fSorted
);
83 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
87 ExaCheckPutImage (DrawablePtr pDrawable
, GCPtr pGC
, int depth
,
88 int x
, int y
, int w
, int h
, int leftPad
, int format
,
91 PixmapPtr pPixmap
= exaGetDrawablePixmap(pDrawable
);
94 EXA_FALLBACK(("to %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
95 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
96 fbPutImage (pDrawable
, pGC
, depth
, x
, y
, w
, h
, leftPad
, format
, bits
);
97 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
98 exaGetDrawableDeltas(pDrawable
, pPixmap
, &xoff
, &yoff
);
99 exaPixmapDirty(pPixmap
, x
+ xoff
, y
+ yoff
, x
+ xoff
+ w
, y
+ yoff
+ h
);
103 ExaCheckCopyArea (DrawablePtr pSrc
, DrawablePtr pDst
, GCPtr pGC
,
104 int srcx
, int srcy
, int w
, int h
, int dstx
, int dsty
)
108 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc
, pDst
,
109 exaDrawableLocation(pSrc
), exaDrawableLocation(pDst
)));
110 exaPrepareAccess (pDst
, EXA_PREPARE_DEST
);
111 exaPrepareAccess (pSrc
, EXA_PREPARE_SRC
);
112 ret
= fbCopyArea (pSrc
, pDst
, pGC
, srcx
, srcy
, w
, h
, dstx
, dsty
);
113 exaFinishAccess (pSrc
, EXA_PREPARE_SRC
);
114 exaFinishAccess (pDst
, EXA_PREPARE_DEST
);
120 ExaCheckCopyPlane (DrawablePtr pSrc
, DrawablePtr pDst
, GCPtr pGC
,
121 int srcx
, int srcy
, int w
, int h
, int dstx
, int dsty
,
122 unsigned long bitPlane
)
126 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc
, pDst
,
127 exaDrawableLocation(pSrc
), exaDrawableLocation(pDst
)));
128 exaPrepareAccess (pDst
, EXA_PREPARE_DEST
);
129 exaPrepareAccess (pSrc
, EXA_PREPARE_SRC
);
130 ret
= fbCopyPlane (pSrc
, pDst
, pGC
, srcx
, srcy
, w
, h
, dstx
, dsty
,
132 exaFinishAccess (pSrc
, EXA_PREPARE_SRC
);
133 exaFinishAccess (pDst
, EXA_PREPARE_DEST
);
139 ExaCheckPolyPoint (DrawablePtr pDrawable
, GCPtr pGC
, int mode
, int npt
,
142 EXA_FALLBACK(("to %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
143 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
144 fbPolyPoint (pDrawable
, pGC
, mode
, npt
, pptInit
);
145 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
149 ExaCheckPolylines (DrawablePtr pDrawable
, GCPtr pGC
,
150 int mode
, int npt
, DDXPointPtr ppt
)
152 EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
153 pDrawable
, exaDrawableLocation(pDrawable
),
154 pGC
->lineWidth
, mode
, npt
));
156 if (pGC
->lineWidth
== 0) {
157 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
158 exaPrepareAccessGC (pGC
);
159 fbPolyLine (pDrawable
, pGC
, mode
, npt
, ppt
);
160 exaFinishAccessGC (pGC
);
161 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
164 /* fb calls mi functions in the lineWidth != 0 case. */
165 fbPolyLine (pDrawable
, pGC
, mode
, npt
, ppt
);
169 ExaCheckPolySegment (DrawablePtr pDrawable
, GCPtr pGC
,
170 int nsegInit
, xSegment
*pSegInit
)
172 EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable
,
173 exaDrawableLocation(pDrawable
), pGC
->lineWidth
, nsegInit
));
174 if (pGC
->lineWidth
== 0) {
175 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
176 exaPrepareAccessGC (pGC
);
177 fbPolySegment (pDrawable
, pGC
, nsegInit
, pSegInit
);
178 exaFinishAccessGC (pGC
);
179 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
182 /* fb calls mi functions in the lineWidth != 0 case. */
183 fbPolySegment (pDrawable
, pGC
, nsegInit
, pSegInit
);
187 ExaCheckPolyArc (DrawablePtr pDrawable
, GCPtr pGC
,
188 int narcs
, xArc
*pArcs
)
190 EXA_FALLBACK(("to %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
191 if (pGC
->lineWidth
== 0)
193 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
194 exaPrepareAccessGC (pGC
);
195 fbPolyArc (pDrawable
, pGC
, narcs
, pArcs
);
196 exaFinishAccessGC (pGC
);
197 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
200 miPolyArc (pDrawable
, pGC
, narcs
, pArcs
);
204 ExaCheckPolyFillRect (DrawablePtr pDrawable
, GCPtr pGC
,
205 int nrect
, xRectangle
*prect
)
207 EXA_FALLBACK(("to %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
209 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
210 exaPrepareAccessGC (pGC
);
211 fbPolyFillRect (pDrawable
, pGC
, nrect
, prect
);
212 exaFinishAccessGC (pGC
);
213 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
217 ExaCheckImageGlyphBlt (DrawablePtr pDrawable
, GCPtr pGC
,
218 int x
, int y
, unsigned int nglyph
,
219 CharInfoPtr
*ppci
, pointer pglyphBase
)
221 EXA_FALLBACK(("to %p (%c)\n", pDrawable
,
222 exaDrawableLocation(pDrawable
)));
223 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
224 exaPrepareAccessGC (pGC
);
225 fbImageGlyphBlt (pDrawable
, pGC
, x
, y
, nglyph
, ppci
, pglyphBase
);
226 exaFinishAccessGC (pGC
);
227 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
231 ExaCheckPolyGlyphBlt (DrawablePtr pDrawable
, GCPtr pGC
,
232 int x
, int y
, unsigned int nglyph
,
233 CharInfoPtr
*ppci
, pointer pglyphBase
)
235 EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable
,
236 exaDrawableLocation(pDrawable
), pGC
->fillStyle
, pGC
->alu
));
237 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
238 exaPrepareAccessGC (pGC
);
239 fbPolyGlyphBlt (pDrawable
, pGC
, x
, y
, nglyph
, ppci
, pglyphBase
);
240 exaFinishAccessGC (pGC
);
241 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
245 ExaCheckPushPixels (GCPtr pGC
, PixmapPtr pBitmap
,
246 DrawablePtr pDrawable
,
247 int w
, int h
, int x
, int y
)
249 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap
, pDrawable
,
250 exaDrawableLocation(&pBitmap
->drawable
),
251 exaDrawableLocation(pDrawable
)));
252 exaPrepareAccess (pDrawable
, EXA_PREPARE_DEST
);
253 exaPrepareAccessGC (pGC
);
254 fbPushPixels (pGC
, pBitmap
, pDrawable
, w
, h
, x
, y
);
255 exaFinishAccessGC (pGC
);
256 exaFinishAccess (pDrawable
, EXA_PREPARE_DEST
);
260 ExaCheckGetImage (DrawablePtr pDrawable
,
261 int x
, int y
, int w
, int h
,
262 unsigned int format
, unsigned long planeMask
,
265 EXA_FALLBACK(("from %p (%c)\n", pDrawable
,
266 exaDrawableLocation(pDrawable
)));
267 exaPrepareAccess (pDrawable
, EXA_PREPARE_SRC
);
268 fbGetImage (pDrawable
, x
, y
, w
, h
, format
, planeMask
, d
);
269 exaFinishAccess (pDrawable
, EXA_PREPARE_SRC
);
273 ExaCheckGetSpans (DrawablePtr pDrawable
,
280 EXA_FALLBACK(("from %p (%c)\n", pDrawable
, exaDrawableLocation(pDrawable
)));
281 exaPrepareAccess (pDrawable
, EXA_PREPARE_SRC
);
282 fbGetSpans (pDrawable
, wMax
, ppt
, pwidth
, nspans
, pdstStart
);
283 exaFinishAccess (pDrawable
, EXA_PREPARE_SRC
);
287 ExaCheckSaveAreas (PixmapPtr pPixmap
,
293 EXA_FALLBACK(("from %p (%c)\n", &pPixmap
->drawable
,
294 exaDrawableLocation(&pPixmap
->drawable
)));
295 exaPrepareAccess ((DrawablePtr
)pPixmap
, EXA_PREPARE_DEST
);
296 fbSaveAreas (pPixmap
, prgnSave
, xorg
, yorg
, pWin
);
297 exaFinishAccess ((DrawablePtr
)pPixmap
, EXA_PREPARE_DEST
);
301 ExaCheckRestoreAreas (PixmapPtr pPixmap
,
307 EXA_FALLBACK(("to %p (%c)\n", &pPixmap
->drawable
,
308 exaDrawableLocation(&pPixmap
->drawable
)));
309 exaPrepareAccess ((DrawablePtr
)pPixmap
, EXA_PREPARE_DEST
);
310 fbRestoreAreas (pPixmap
, prgnSave
, xorg
, yorg
, pWin
);
311 exaFinishAccess ((DrawablePtr
)pPixmap
, EXA_PREPARE_DEST
);
314 /* XXX: Note the lack of a prepare on the tile, if the window has a tiled
315 * background. This function happens to only be called if pExaScr->swappedOut,
316 * so we actually end up not having to do it since the tile won't be in fb.
317 * That doesn't make this not dirty, though.
320 ExaCheckPaintWindow (WindowPtr pWin
, RegionPtr pRegion
, int what
)
322 EXA_FALLBACK(("from %p (%c)\n", pWin
,
323 exaDrawableLocation(&pWin
->drawable
)));
324 exaPrepareAccess (&pWin
->drawable
, EXA_PREPARE_DEST
);
325 fbPaintWindow (pWin
, pRegion
, what
);
326 exaFinishAccess (&pWin
->drawable
, EXA_PREPARE_DEST
);
330 ExaCheckComposite (CARD8 op
,
343 EXA_FALLBACK(("from picts %p/%p to pict %p\n",
345 exaPrepareAccess (pDst
->pDrawable
, EXA_PREPARE_DEST
);
346 if (pSrc
->pDrawable
!= NULL
)
347 exaPrepareAccess (pSrc
->pDrawable
, EXA_PREPARE_SRC
);
348 if (pMask
&& pMask
->pDrawable
!= NULL
)
349 exaPrepareAccess (pMask
->pDrawable
, EXA_PREPARE_MASK
);
362 if (pMask
&& pMask
->pDrawable
!= NULL
)
363 exaFinishAccess (pMask
->pDrawable
, EXA_PREPARE_MASK
);
364 if (pSrc
->pDrawable
!= NULL
)
365 exaFinishAccess (pSrc
->pDrawable
, EXA_PREPARE_SRC
);
366 exaFinishAccess (pDst
->pDrawable
, EXA_PREPARE_DEST
);
370 * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
371 * that happen to be 1x1. Pixmap must be at least 8bpp.
373 * XXX This really belongs in fb, so it can be aware of tiling and etc.
376 exaGetPixmapFirstPixel (PixmapPtr pPixmap
)
380 Bool need_finish
= FALSE
;
382 ExaMigrationRec pixmaps
[1];
383 ExaPixmapPriv (pPixmap
);
385 fb
= pExaPixmap
->sys_ptr
;
387 /* Try to avoid framebuffer readbacks */
388 if (exaPixmapIsOffscreen(pPixmap
) &&
389 miPointInRegion(DamageRegion(pExaPixmap
->pDamage
), 0, 0, &box
))
392 pixmaps
[0].as_dst
= FALSE
;
393 pixmaps
[0].as_src
= TRUE
;
394 pixmaps
[0].pPix
= pPixmap
;
395 exaDoMigration (pixmaps
, 1, FALSE
);
396 exaPrepareAccess(&pPixmap
->drawable
, EXA_PREPARE_SRC
);
397 fb
= pPixmap
->devPrivate
.ptr
;
400 switch (pPixmap
->drawable
.bitsPerPixel
) {
402 pixel
= *(CARD32
*)fb
;
405 pixel
= *(CARD16
*)fb
;
408 pixel
= *(CARD8
*)fb
;
413 exaFinishAccess(&pPixmap
->drawable
, EXA_PREPARE_SRC
);