exa_unaccel.c revision 05b261ec
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/* 27 * These functions wrap the low-level fb rendering functions and 28 * synchronize framebuffer/accelerated drawing by stalling until 29 * the accelerator is idle 30 */ 31 32/** 33 * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the 34 * current fill style. 35 * 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. 38 */ 39void 40exaPrepareAccessGC(GCPtr pGC) 41{ 42 if (pGC->fillStyle == FillTiled) 43 exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); 44} 45 46/** 47 * Finishes access to the tile in the GC, if used. 48 */ 49void 50exaFinishAccessGC(GCPtr pGC) 51{ 52 if (pGC->fillStyle == FillTiled) 53 exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); 54} 55 56#if DEBUG_TRACE_FALL 57char 58exaDrawableLocation(DrawablePtr pDrawable) 59{ 60 return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm'; 61} 62#endif /* DEBUG_TRACE_FALL */ 63 64void 65ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, 66 DDXPointPtr ppt, int *pwidth, int fSorted) 67{ 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); 74} 75 76void 77ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, 78 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) 79{ 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); 84} 85 86void 87ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, 88 int x, int y, int w, int h, int leftPad, int format, 89 char *bits) 90{ 91 PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); 92 int xoff, yoff; 93 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); 100} 101 102RegionPtr 103ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 104 int srcx, int srcy, int w, int h, int dstx, int dsty) 105{ 106 RegionPtr ret; 107 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); 115 116 return ret; 117} 118 119RegionPtr 120ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 121 int srcx, int srcy, int w, int h, int dstx, int dsty, 122 unsigned long bitPlane) 123{ 124 RegionPtr ret; 125 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, 131 bitPlane); 132 exaFinishAccess (pSrc, EXA_PREPARE_SRC); 133 exaFinishAccess (pDst, EXA_PREPARE_DEST); 134 135 return ret; 136} 137 138void 139ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 140 DDXPointPtr pptInit) 141{ 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); 146} 147 148void 149ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, 150 int mode, int npt, DDXPointPtr ppt) 151{ 152 EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", 153 pDrawable, exaDrawableLocation(pDrawable), 154 pGC->lineWidth, mode, npt)); 155 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); 162 return; 163 } 164 /* fb calls mi functions in the lineWidth != 0 case. */ 165 fbPolyLine (pDrawable, pGC, mode, npt, ppt); 166} 167 168void 169ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, 170 int nsegInit, xSegment *pSegInit) 171{ 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); 180 return; 181 } 182 /* fb calls mi functions in the lineWidth != 0 case. */ 183 fbPolySegment (pDrawable, pGC, nsegInit, pSegInit); 184} 185 186void 187ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, 188 int narcs, xArc *pArcs) 189{ 190 EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); 191 if (pGC->lineWidth == 0) 192 { 193 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 194 exaPrepareAccessGC (pGC); 195 fbPolyArc (pDrawable, pGC, narcs, pArcs); 196 exaFinishAccessGC (pGC); 197 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 198 return; 199 } 200 miPolyArc (pDrawable, pGC, narcs, pArcs); 201} 202 203void 204ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, 205 int nrect, xRectangle *prect) 206{ 207 EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); 208 209 exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); 210 exaPrepareAccessGC (pGC); 211 fbPolyFillRect (pDrawable, pGC, nrect, prect); 212 exaFinishAccessGC (pGC); 213 exaFinishAccess (pDrawable, EXA_PREPARE_DEST); 214} 215 216void 217ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, 218 int x, int y, unsigned int nglyph, 219 CharInfoPtr *ppci, pointer pglyphBase) 220{ 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); 228} 229 230void 231ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, 232 int x, int y, unsigned int nglyph, 233 CharInfoPtr *ppci, pointer pglyphBase) 234{ 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); 242} 243 244void 245ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, 246 DrawablePtr pDrawable, 247 int w, int h, int x, int y) 248{ 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); 257} 258 259void 260ExaCheckGetImage (DrawablePtr pDrawable, 261 int x, int y, int w, int h, 262 unsigned int format, unsigned long planeMask, 263 char *d) 264{ 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); 270} 271 272void 273ExaCheckGetSpans (DrawablePtr pDrawable, 274 int wMax, 275 DDXPointPtr ppt, 276 int *pwidth, 277 int nspans, 278 char *pdstStart) 279{ 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); 284} 285 286void 287ExaCheckSaveAreas (PixmapPtr pPixmap, 288 RegionPtr prgnSave, 289 int xorg, 290 int yorg, 291 WindowPtr pWin) 292{ 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); 298} 299 300void 301ExaCheckRestoreAreas (PixmapPtr pPixmap, 302 RegionPtr prgnSave, 303 int xorg, 304 int yorg, 305 WindowPtr pWin) 306{ 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); 312} 313 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. 318 */ 319void 320ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what) 321{ 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); 327} 328 329void 330ExaCheckComposite (CARD8 op, 331 PicturePtr pSrc, 332 PicturePtr pMask, 333 PicturePtr pDst, 334 INT16 xSrc, 335 INT16 ySrc, 336 INT16 xMask, 337 INT16 yMask, 338 INT16 xDst, 339 INT16 yDst, 340 CARD16 width, 341 CARD16 height) 342{ 343 EXA_FALLBACK(("from picts %p/%p to pict %p\n", 344 pSrc, pMask, pDst)); 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); 350 fbComposite (op, 351 pSrc, 352 pMask, 353 pDst, 354 xSrc, 355 ySrc, 356 xMask, 357 yMask, 358 xDst, 359 yDst, 360 width, 361 height); 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); 367} 368 369/** 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. 372 * 373 * XXX This really belongs in fb, so it can be aware of tiling and etc. 374 */ 375CARD32 376exaGetPixmapFirstPixel (PixmapPtr pPixmap) 377{ 378 CARD32 pixel; 379 void *fb; 380 Bool need_finish = FALSE; 381 BoxRec box; 382 ExaMigrationRec pixmaps[1]; 383 ExaPixmapPriv (pPixmap); 384 385 fb = pExaPixmap->sys_ptr; 386 387 /* Try to avoid framebuffer readbacks */ 388 if (exaPixmapIsOffscreen(pPixmap) && 389 miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) 390 { 391 need_finish = TRUE; 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; 398 } 399 400 switch (pPixmap->drawable.bitsPerPixel) { 401 case 32: 402 pixel = *(CARD32 *)fb; 403 break; 404 case 16: 405 pixel = *(CARD16 *)fb; 406 break; 407 default: 408 pixel = *(CARD8 *)fb; 409 break; 410 } 411 412 if (need_finish) 413 exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); 414 415 return pixel; 416} 417