static RegionPtr uxa_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { ScreenPtr screen = pDst->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; RegionPtr region; if (uxa_prepare_access(pDst, UXA_GLAMOR_ACCESS_RW)) { if (uxa_prepare_access(pSrc, UXA_GLAMOR_ACCESS_RO)) { ok = glamor_copy_plane_nf(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane, ®ion); uxa_finish_access(pSrc, UXA_GLAMOR_ACCESS_RO); } uxa_finish_access(pDst, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return region; } fallback: return uxa_check_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); }
/** * Finishes access to the tile in the GC, if used. */ void uxa_finish_access_gc(GCPtr pGC) { if (pGC->fillStyle == FillTiled) uxa_finish_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO); if (pGC->stipple) uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RO); }
static void uxa_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { if (uxa_prepare_access(&pBitmap->drawable, UXA_GLAMOR_ACCESS_RO)) { ok = glamor_push_pixels_nf(pGC, pBitmap, pDrawable, w, h, x, y); uxa_finish_access(&pBitmap->drawable, UXA_GLAMOR_ACCESS_RO); } uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return; } fallback: uxa_check_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y); }
void uxa_finish_access_window(WindowPtr pWin) { if (pWin->backgroundState == BackgroundPixmap) uxa_finish_access(&pWin->background.pixmap->drawable); if (pWin->borderIsPixel == FALSE) uxa_finish_access(&pWin->border.pixmap->drawable); }
void uxa_picture_finish_access(PicturePtr picture, int mode) { if (picture->pDrawable == NULL) return; uxa_finish_access(picture->pDrawable, mode); if (picture->alphaMap) uxa_finish_access(picture->alphaMap->pDrawable, mode); }
static void uxa_set_spans(DrawablePtr pDrawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_set_spans_nf(pDrawable, gc, src, points, widths, n, sorted); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return; } fallback: uxa_check_set_spans(pDrawable, gc, src, points, widths, n, sorted); }
static void uxa_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_put_image_nf(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return; } if (!uxa_do_put_image(pDrawable, pGC, depth, x, y, w, h, format, bits, PixmapBytePad(w, pDrawable->depth))) { fallback: uxa_check_put_image(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); } }
void uxa_check_poly_arc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); /* Disable this as fbPolyArc can call miZeroPolyArc which in turn * can call accelerated functions, that as yet, haven't been notified * with uxa_finish_access(). */ #if 0 if (pGC->lineWidth == 0) { if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyArc(pDrawable, pGC, narcs, pArcs); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } return; } #endif miPolyArc(pDrawable, pGC, narcs, pArcs); }
/** * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps * that happen to be 1x1. Pixmap must be at least 8bpp. * * XXX This really belongs in fb, so it can be aware of tiling and etc. */ CARD32 uxa_get_pixmap_first_pixel(PixmapPtr pPixmap) { CARD32 pixel; void *fb; if (!uxa_prepare_access(&pPixmap->drawable, UXA_ACCESS_RO)) return 0; fb = pPixmap->devPrivate.ptr; switch (pPixmap->drawable.bitsPerPixel) { case 32: pixel = *(CARD32 *) fb; break; case 16: pixel = *(CARD16 *) fb; break; default: pixel = *(CARD8 *) fb; break; } uxa_finish_access(&pPixmap->drawable, UXA_ACCESS_RO); return pixel; }
void uxa_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_get_spans_nf(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return; } fallback: uxa_check_get_spans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); }
static RegionPtr uxa_bitmap_to_region(PixmapPtr pPix) { RegionPtr ret; if (!uxa_prepare_access(&pPix->drawable, NULL, UXA_ACCESS_RO)) return NULL; ret = fbPixmapToRegion(pPix); uxa_finish_access(&pPix->drawable); return ret; }
RegionPtr uxa_check_copy_area(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { ScreenPtr screen = pSrc->pScreen; RegionPtr ret = NULL; UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, uxa_drawable_location(pSrc), uxa_drawable_location(pDst))); if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) { if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) { ret = fbCopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); uxa_finish_access(pSrc, UXA_ACCESS_RO); } uxa_finish_access(pDst, UXA_ACCESS_RW); } return ret; }
void uxa_check_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, uxa_drawable_location(&pBitmap->drawable), uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access(&pBitmap->drawable, UXA_ACCESS_RO)) { if (uxa_prepare_access_gc(pGC)) { fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); uxa_finish_access_gc(pGC); } uxa_finish_access(&pBitmap->drawable, UXA_ACCESS_RO); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
void uxa_check_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
void uxa_check_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { fbPolyPoint(pDrawable, pGC, mode, npt, pptInit); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
/** * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the * current fill style. * * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are * 1bpp and never in fb, so we don't worry about them. * We should worry about them for completeness sake and going forward. */ Bool uxa_prepare_access_gc(GCPtr pGC) { if (pGC->stipple) if (!uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO)) return FALSE; if (pGC->fillStyle == FillTiled) if (!uxa_prepare_access (&pGC->tile.pixmap->drawable, UXA_ACCESS_RO)) { if (pGC->stipple) uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RO); return FALSE; } return TRUE; }
void uxa_check_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("from %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) { fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); uxa_finish_access(pDrawable, UXA_ACCESS_RO); } }
void uxa_check_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
Bool uxa_picture_prepare_access(PicturePtr picture, int mode) { if (picture->pDrawable == NULL) return TRUE; if (!uxa_prepare_access(picture->pDrawable, mode)) return FALSE; if (picture->alphaMap && !uxa_prepare_access(picture->alphaMap->pDrawable, mode)) { uxa_finish_access(picture->pDrawable, mode); return FALSE; } return TRUE; }
void uxa_check_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans, DDXPointPtr ppt, int *pwidth, int fSorted) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth, fSorted); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
void uxa_check_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle * prect) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyFillRect(pDrawable, pGC, nrect, prect); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
void uxa_check_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } }
static void uxa_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { int i; xRectangle *prect; uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_poly_point_nf(pDrawable, pGC, mode, npt, ppt); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (ok) return; } /* If we can't reuse the current GC as is, don't bother accelerating the * points. */ if (pGC->fillStyle != FillSolid) { uxa_check_poly_point(pDrawable, pGC, mode, npt, ppt); return; } prect = malloc(sizeof(xRectangle) * npt); if (!prect) return; for (i = 0; i < npt; i++) { prect[i].x = ppt[i].x; prect[i].y = ppt[i].y; if (i > 0 && mode == CoordModePrevious) { prect[i].x += prect[i - 1].x; prect[i].y += prect[i - 1].y; } prect[i].width = 1; prect[i].height = 1; } pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect); free(prect); }
Bool uxa_prepare_access_window(WindowPtr pWin) { if (pWin->backgroundState == BackgroundPixmap) { if (!uxa_prepare_access (&pWin->background.pixmap->drawable, NULL, UXA_ACCESS_RO)) return FALSE; } if (pWin->borderIsPixel == FALSE) { if (!uxa_prepare_access (&pWin->border.pixmap->drawable, NULL, UXA_ACCESS_RO)) { if (pWin->backgroundState == BackgroundPixmap) uxa_finish_access(&pWin->background.pixmap-> drawable); return FALSE; } } return TRUE; }
static void uxa_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_poly_glyph_blt_nf(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return; } fallback: uxa_check_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); }
void uxa_check_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nsegInit, xSegment * pSegInit) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, uxa_drawable_location(pDrawable), pGC->lineWidth, nsegInit)); if (pGC->lineWidth == 0) { if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } return; } /* fb calls mi functions in the lineWidth != 0 case. */ fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); }
void uxa_check_poly_lines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", pDrawable, uxa_drawable_location(pDrawable), pGC->lineWidth, mode, npt)); if (pGC->lineWidth == 0) { if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyLine(pDrawable, pGC, mode, npt, ppt); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } return; } /* fb calls mi functions in the lineWidth != 0 case. */ fbPolyLine(pDrawable, pGC, mode, npt, ppt); }
static void uxa_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle * prect) { uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap; RegionPtr pReg; BoxPtr pbox; int fullX1, fullX2, fullY1, fullY2; int xoff, yoff; int xorg, yorg; int n; if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_poly_fill_rect_nf(pDrawable, pGC, nrect, prect); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect); return; } /* Compute intersection of rects and clip region */ pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y); REGION_INTERSECT(pScreen, pReg, pClip, pReg); if (!REGION_NUM_RECTS(pReg)) goto out; if (uxa_screen->force_fallback) goto fallback; pPixmap = uxa_get_offscreen_pixmap (pDrawable, &xoff, &yoff); if (!pPixmap) goto fallback; /* For ROPs where overlaps don't matter, convert rectangles to region * and call uxa_fill_region_{solid,tiled}. */ if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) && (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop || pGC->alu == GXcopyInverted || pGC->alu == GXset)) { if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) && uxa_fill_region_solid(pDrawable, pReg, pGC->fillStyle == FillSolid ? pGC->fgPixel : pGC->tile. pixel, pGC->planemask, pGC->alu)) || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && uxa_fill_region_tiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, pGC->planemask, pGC->alu))) { goto out; } } if (pGC->fillStyle != FillSolid && !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) { goto fallback; } if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask)) { goto fallback; } if (!(*uxa_screen->info->prepare_solid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { fallback: uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect); goto out; } xorg = pDrawable->x; yorg = pDrawable->y; while (nrect--) { fullX1 = prect->x + xorg; fullY1 = prect->y + yorg; fullX2 = fullX1 + (int)prect->width; fullY2 = fullY1 + (int)prect->height; prect++; n = REGION_NUM_RECTS(pClip); pbox = REGION_RECTS(pClip); /* * clip the rectangle to each box in the clip region * this is logically equivalent to calling Intersect(), * but rectangles may overlap each other here. */ while (n--) { int x1 = fullX1; int x2 = fullX2; int y1 = fullY1; int y2 = fullY2; if (pbox->x1 > x1) x1 = pbox->x1; if (pbox->x2 < x2) x2 = pbox->x2; if (pbox->y1 > y1) y1 = pbox->y1; if (pbox->y2 < y2) y2 = pbox->y2; pbox++; if (x1 >= x2 || y1 >= y2) continue; (*uxa_screen->info->solid) (pPixmap, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); } } (*uxa_screen->info->done_solid) (pPixmap); out: REGION_UNINIT(pScreen, pReg); REGION_DESTROY(pScreen, pReg); }
/** * uxa_validate_gc() sets the ops to UXA's implementations, which may be * accelerated or may sync the card and fall back to fb. */ static void uxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has * changed. * Preempt fbValidateGC by doing its work and masking the change out, so * that we can do the Prepare/finish_access. */ #ifdef FB_24_32BIT if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); fbGetRotatedPixmap(pGC) = 0; } if (pGC->fillStyle == FillTiled) { PixmapPtr pOldTile, pNewTile; pOldTile = pGC->tile.pixmap; if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { pNewTile = fbGetRotatedPixmap(pGC); if (!pNewTile || pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { if (pNewTile) (*pGC->pScreen-> DestroyPixmap) (pNewTile); /* fb24_32ReformatTile will do direct access * of a newly-allocated pixmap. This isn't a * problem yet, since we don't put pixmaps in * FB until at least one accelerated UXA op. */ if (uxa_prepare_access (&pOldTile->drawable, NULL, UXA_ACCESS_RO)) { pNewTile = fb24_32ReformatTile(pOldTile, pDrawable-> bitsPerPixel); uxa_finish_access(&pOldTile->drawable); } } if (pNewTile) { fbGetRotatedPixmap(pGC) = pOldTile; pGC->tile.pixmap = pNewTile; changes |= GCTile; } } } #endif if (changes & GCTile) { if (!pGC->tileIsPixel && FbEvenTile(pGC->tile.pixmap->drawable.width * pDrawable->bitsPerPixel)) { if (uxa_prepare_access (&pGC->tile.pixmap->drawable, NULL, UXA_ACCESS_RW)) { fbPadPixmap(pGC->tile.pixmap); uxa_finish_access(&pGC->tile.pixmap->drawable); } } /* Mask out the GCTile change notification, now that we've * done FB's job for it. */ changes &= ~GCTile; } if (changes & GCStipple && pGC->stipple) { /* We can't inline stipple handling like we do for GCTile * because it sets fbgc privates. */ if (uxa_prepare_access(&pGC->stipple->drawable, NULL, UXA_ACCESS_RW)) { fbValidateGC(pGC, changes, pDrawable); uxa_finish_access(&pGC->stipple->drawable); } } else { fbValidateGC(pGC, changes, pDrawable); } pGC->ops = (GCOps *) & uxa_ops; }
/** * uxa_poly_segment() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill * acceleration if so. */ static void uxa_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg) { xRectangle *prect; int i; uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); if (uxa_screen->info->flags & UXA_USE_GLAMOR) { int ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_poly_segment_nf(pDrawable, pGC, nseg, pSeg); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (ok) return; } /* Don't try to do wide lines or non-solid fill style. */ if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { uxa_check_poly_segment(pDrawable, pGC, nseg, pSeg); return; } /* If we have any non-horizontal/vertical, fall back. */ for (i = 0; i < nseg; i++) { if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) { uxa_check_poly_segment(pDrawable, pGC, nseg, pSeg); return; } } prect = malloc(sizeof(xRectangle) * nseg); if (!prect) return; for (i = 0; i < nseg; i++) { if (pSeg[i].x1 < pSeg[i].x2) { prect[i].x = pSeg[i].x1; prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1; } else { prect[i].x = pSeg[i].x2; prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1; } if (pSeg[i].y1 < pSeg[i].y2) { prect[i].y = pSeg[i].y1; prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1; } else { prect[i].y = pSeg[i].y2; prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1; } /* don't paint last pixel */ if (pGC->capStyle == CapNotLast) { if (prect[i].width == 1) prect[i].height--; else prect[i].width--; } } pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect); free(prect); }