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