uxa-unaccel.c revision 03b705cf
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 "uxa-priv.h" 25 26#ifdef RENDER 27#include "mipict.h" 28#endif 29 30/* 31 * These functions wrap the low-level fb rendering functions and 32 * synchronize framebuffer/accelerated drawing by stalling until 33 * the accelerator is idle 34 */ 35 36/** 37 * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the 38 * current fill style. 39 * 40 * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are 41 * 1bpp and never in fb, so we don't worry about them. 42 * We should worry about them for completeness sake and going forward. 43 */ 44Bool uxa_prepare_access_gc(GCPtr pGC) 45{ 46 if (pGC->stipple) 47 if (!uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO)) 48 return FALSE; 49 if (pGC->fillStyle == FillTiled) 50 if (!uxa_prepare_access 51 (&pGC->tile.pixmap->drawable, UXA_ACCESS_RO)) { 52 if (pGC->stipple) 53 uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RO); 54 return FALSE; 55 } 56 return TRUE; 57} 58 59/** 60 * Finishes access to the tile in the GC, if used. 61 */ 62void uxa_finish_access_gc(GCPtr pGC) 63{ 64 if (pGC->fillStyle == FillTiled) 65 uxa_finish_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO); 66 if (pGC->stipple) 67 uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RO); 68} 69 70Bool uxa_picture_prepare_access(PicturePtr picture, int mode) 71{ 72 if (picture->pDrawable == NULL) 73 return TRUE; 74 75 if (!uxa_prepare_access(picture->pDrawable, mode)) 76 return FALSE; 77 78 if (picture->alphaMap && 79 !uxa_prepare_access(picture->alphaMap->pDrawable, mode)) { 80 uxa_finish_access(picture->pDrawable, mode); 81 return FALSE; 82 } 83 84 return TRUE; 85} 86 87void uxa_picture_finish_access(PicturePtr picture, int mode) 88{ 89 if (picture->pDrawable == NULL) 90 return; 91 92 uxa_finish_access(picture->pDrawable, mode); 93 if (picture->alphaMap) 94 uxa_finish_access(picture->alphaMap->pDrawable, mode); 95} 96 97 98char uxa_drawable_location(DrawablePtr pDrawable) 99{ 100 return uxa_drawable_is_offscreen(pDrawable) ? 's' : 'm'; 101} 102 103void 104uxa_check_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans, 105 DDXPointPtr ppt, int *pwidth, int fSorted) 106{ 107 ScreenPtr screen = pDrawable->pScreen; 108 109 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 110 uxa_drawable_location(pDrawable))); 111 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 112 if (uxa_prepare_access_gc(pGC)) { 113 fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth, 114 fSorted); 115 uxa_finish_access_gc(pGC); 116 } 117 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 118 } 119} 120 121void 122uxa_check_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, 123 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) 124{ 125 ScreenPtr screen = pDrawable->pScreen; 126 127 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 128 uxa_drawable_location(pDrawable))); 129 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 130 fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); 131 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 132 } 133} 134 135void 136uxa_check_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, 137 int x, int y, int w, int h, int leftPad, int format, 138 char *bits) 139{ 140 ScreenPtr screen = pDrawable->pScreen; 141 142 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 143 uxa_drawable_location(pDrawable))); 144 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 145 fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, 146 bits); 147 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 148 } 149} 150 151RegionPtr 152uxa_check_copy_area(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 153 int srcx, int srcy, int w, int h, int dstx, int dsty) 154{ 155 ScreenPtr screen = pSrc->pScreen; 156 RegionPtr ret = NULL; 157 158 UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, 159 uxa_drawable_location(pSrc), 160 uxa_drawable_location(pDst))); 161 if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) { 162 if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) { 163 ret = 164 fbCopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, 165 dsty); 166 uxa_finish_access(pSrc, UXA_ACCESS_RO); 167 } 168 uxa_finish_access(pDst, UXA_ACCESS_RW); 169 } 170 return ret; 171} 172 173RegionPtr 174uxa_check_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 175 int srcx, int srcy, int w, int h, int dstx, int dsty, 176 unsigned long bitPlane) 177{ 178 ScreenPtr screen = pSrc->pScreen; 179 RegionPtr ret = NULL; 180 181 UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, 182 uxa_drawable_location(pSrc), 183 uxa_drawable_location(pDst))); 184 if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) { 185 if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) { 186 ret = 187 fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, 188 dsty, bitPlane); 189 uxa_finish_access(pSrc, UXA_ACCESS_RO); 190 } 191 uxa_finish_access(pDst, UXA_ACCESS_RW); 192 } 193 return ret; 194} 195 196void 197uxa_check_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 198 DDXPointPtr pptInit) 199{ 200 ScreenPtr screen = pDrawable->pScreen; 201 202 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 203 uxa_drawable_location(pDrawable))); 204 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 205 fbPolyPoint(pDrawable, pGC, mode, npt, pptInit); 206 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 207 } 208} 209 210void 211uxa_check_poly_lines(DrawablePtr pDrawable, GCPtr pGC, 212 int mode, int npt, DDXPointPtr ppt) 213{ 214 ScreenPtr screen = pDrawable->pScreen; 215 216 UXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", 217 pDrawable, uxa_drawable_location(pDrawable), 218 pGC->lineWidth, mode, npt)); 219 220 if (pGC->lineWidth == 0) { 221 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 222 if (uxa_prepare_access_gc(pGC)) { 223 fbPolyLine(pDrawable, pGC, mode, npt, ppt); 224 uxa_finish_access_gc(pGC); 225 } 226 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 227 } 228 return; 229 } 230 /* fb calls mi functions in the lineWidth != 0 case. */ 231 fbPolyLine(pDrawable, pGC, mode, npt, ppt); 232} 233 234void 235uxa_check_poly_segment(DrawablePtr pDrawable, GCPtr pGC, 236 int nsegInit, xSegment * pSegInit) 237{ 238 ScreenPtr screen = pDrawable->pScreen; 239 240 UXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, 241 uxa_drawable_location(pDrawable), pGC->lineWidth, 242 nsegInit)); 243 if (pGC->lineWidth == 0) { 244 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 245 if (uxa_prepare_access_gc(pGC)) { 246 fbPolySegment(pDrawable, pGC, nsegInit, 247 pSegInit); 248 uxa_finish_access_gc(pGC); 249 } 250 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 251 } 252 return; 253 } 254 /* fb calls mi functions in the lineWidth != 0 case. */ 255 fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); 256} 257 258void 259uxa_check_poly_arc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs) 260{ 261 ScreenPtr screen = pDrawable->pScreen; 262 263 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 264 uxa_drawable_location(pDrawable))); 265 266 /* Disable this as fbPolyArc can call miZeroPolyArc which in turn 267 * can call accelerated functions, that as yet, haven't been notified 268 * with uxa_finish_access(). 269 */ 270#if 0 271 if (pGC->lineWidth == 0) { 272 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 273 if (uxa_prepare_access_gc(pGC)) { 274 fbPolyArc(pDrawable, pGC, narcs, pArcs); 275 uxa_finish_access_gc(pGC); 276 } 277 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 278 } 279 return; 280 } 281#endif 282 miPolyArc(pDrawable, pGC, narcs, pArcs); 283} 284 285void 286uxa_check_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, 287 int nrect, xRectangle * prect) 288{ 289 ScreenPtr screen = pDrawable->pScreen; 290 291 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 292 uxa_drawable_location(pDrawable))); 293 294 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 295 if (uxa_prepare_access_gc(pGC)) { 296 fbPolyFillRect(pDrawable, pGC, nrect, prect); 297 uxa_finish_access_gc(pGC); 298 } 299 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 300 } 301} 302 303void 304uxa_check_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, 305 int x, int y, unsigned int nglyph, 306 CharInfoPtr * ppci, pointer pglyphBase) 307{ 308 ScreenPtr screen = pDrawable->pScreen; 309 310 UXA_FALLBACK(("to %p (%c)\n", pDrawable, 311 uxa_drawable_location(pDrawable))); 312 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 313 if (uxa_prepare_access_gc(pGC)) { 314 fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, 315 pglyphBase); 316 uxa_finish_access_gc(pGC); 317 } 318 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 319 } 320} 321 322void 323uxa_check_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, 324 int x, int y, unsigned int nglyph, 325 CharInfoPtr * ppci, pointer pglyphBase) 326{ 327 ScreenPtr screen = pDrawable->pScreen; 328 329 UXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, 330 uxa_drawable_location(pDrawable), pGC->fillStyle, 331 pGC->alu)); 332 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 333 if (uxa_prepare_access_gc(pGC)) { 334 fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, 335 pglyphBase); 336 uxa_finish_access_gc(pGC); 337 } 338 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 339 } 340} 341 342void 343uxa_check_push_pixels(GCPtr pGC, PixmapPtr pBitmap, 344 DrawablePtr pDrawable, int w, int h, int x, int y) 345{ 346 ScreenPtr screen = pDrawable->pScreen; 347 348 UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, 349 uxa_drawable_location(&pBitmap->drawable), 350 uxa_drawable_location(pDrawable))); 351 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { 352 if (uxa_prepare_access(&pBitmap->drawable, UXA_ACCESS_RO)) { 353 if (uxa_prepare_access_gc(pGC)) { 354 fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, 355 y); 356 uxa_finish_access_gc(pGC); 357 } 358 uxa_finish_access(&pBitmap->drawable, UXA_ACCESS_RO); 359 } 360 uxa_finish_access(pDrawable, UXA_ACCESS_RW); 361 } 362} 363 364void 365uxa_check_get_spans(DrawablePtr pDrawable, 366 int wMax, 367 DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) 368{ 369 ScreenPtr screen = pDrawable->pScreen; 370 371 UXA_FALLBACK(("from %p (%c)\n", pDrawable, 372 uxa_drawable_location(pDrawable))); 373 if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) { 374 fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 375 uxa_finish_access(pDrawable, UXA_ACCESS_RO); 376 } 377} 378 379void 380uxa_check_composite(CARD8 op, 381 PicturePtr pSrc, 382 PicturePtr pMask, 383 PicturePtr pDst, 384 INT16 xSrc, INT16 ySrc, 385 INT16 xMask, INT16 yMask, 386 INT16 xDst, INT16 yDst, 387 CARD16 width, CARD16 height) 388{ 389 ScreenPtr screen = pDst->pDrawable->pScreen; 390 391 UXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst)); 392 393 if (uxa_picture_prepare_access(pDst, UXA_ACCESS_RW)) { 394 if (uxa_picture_prepare_access(pSrc, UXA_ACCESS_RO)) { 395 if (!pMask || uxa_picture_prepare_access(pMask, UXA_ACCESS_RO)) { 396 fbComposite(op, pSrc, pMask, pDst, 397 xSrc, ySrc, 398 xMask, yMask, 399 xDst, yDst, 400 width, height); 401 if (pMask) 402 uxa_picture_finish_access(pMask, UXA_ACCESS_RO); 403 } 404 uxa_picture_finish_access(pSrc, UXA_ACCESS_RO); 405 } 406 uxa_picture_finish_access(pDst, UXA_ACCESS_RW); 407 } 408} 409 410void 411uxa_check_add_traps(PicturePtr pPicture, 412 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) 413{ 414 ScreenPtr screen = pPicture->pDrawable->pScreen; 415 416 UXA_FALLBACK(("to pict %p (%c)\n", pPicture, 417 uxa_drawable_location(pPicture->pDrawable))); 418 if (uxa_picture_prepare_access(pPicture, UXA_ACCESS_RW)) { 419 fbAddTraps(pPicture, x_off, y_off, ntrap, traps); 420 uxa_picture_finish_access(pPicture, UXA_ACCESS_RW); 421 } 422} 423 424/** 425 * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps 426 * that happen to be 1x1. Pixmap must be at least 8bpp. 427 * 428 * XXX This really belongs in fb, so it can be aware of tiling and etc. 429 */ 430CARD32 uxa_get_pixmap_first_pixel(PixmapPtr pPixmap) 431{ 432 CARD32 pixel; 433 void *fb; 434 435 if (!uxa_prepare_access(&pPixmap->drawable, UXA_ACCESS_RO)) 436 return 0; 437 438 fb = pPixmap->devPrivate.ptr; 439 440 switch (pPixmap->drawable.bitsPerPixel) { 441 case 32: 442 pixel = *(CARD32 *) fb; 443 break; 444 case 16: 445 pixel = *(CARD16 *) fb; 446 break; 447 default: 448 pixel = *(CARD8 *) fb; 449 break; 450 } 451 uxa_finish_access(&pPixmap->drawable, UXA_ACCESS_RO); 452 453 return pixel; 454} 455