Exemple #1
0
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, &region);
				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);
}
Exemple #2
0
/**
 * 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);
}
Exemple #3
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
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);
	}
}
Exemple #8
0
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);
}
Exemple #9
0
/**
 * 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;
}
Exemple #10
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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);
	}
}
Exemple #14
0
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);
	}
}
Exemple #15
0
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);
	}
}
Exemple #16
0
/**
 * 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;
}
Exemple #17
0
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);
	}
}
Exemple #18
0
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);
	}
}
Exemple #19
0
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;
}
Exemple #20
0
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);
	}
}
Exemple #21
0
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);
	}
}
Exemple #22
0
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);
	}
}
Exemple #23
0
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;
}
Exemple #25
0
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);
}
Exemple #26
0
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);
}
Exemple #27
0
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);
}
Exemple #28
0
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;
}
Exemple #30
0
/**
 * 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);
}