Exemplo n.º 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);
}
Exemplo n.º 2
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_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
		}
		if (!ok)
			goto fallback;
		return;
	}

fallback:
	uxa_check_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y);
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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);
	}
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
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);
}
Exemplo n.º 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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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);
	}
}
Exemplo n.º 13
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;
}
Exemplo n.º 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);
	}
}
Exemplo n.º 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);
	}
}
Exemplo n.º 16
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);
	}
}
Exemplo n.º 17
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);
	}
}
Exemplo n.º 18
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);
	}
}
Exemplo n.º 19
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);
	}
}
Exemplo n.º 20
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);
	}
}
Exemplo n.º 21
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);
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
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);
}
Exemplo n.º 24
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);
}
Exemplo n.º 25
0
void
uxa_copy_n_to_n(DrawablePtr pSrcDrawable,
		DrawablePtr pDstDrawable,
		GCPtr pGC,
		BoxPtr pbox,
		int nbox,
		int dx,
		int dy,
		Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
{
	ScreenPtr screen = pDstDrawable->pScreen;
	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
	int src_off_x, src_off_y;
	int dst_off_x, dst_off_y;
	PixmapPtr pSrcPixmap, pDstPixmap;

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok = 0;

		if (uxa_prepare_access(pSrcDrawable, UXA_GLAMOR_ACCESS_RO)) {
			if (uxa_prepare_access(pDstDrawable, UXA_GLAMOR_ACCESS_RW)) {
				ok = glamor_copy_n_to_n_nf(pSrcDrawable, pDstDrawable,
							   pGC, pbox, nbox, dx, dy,
							   reverse, upsidedown, bitplane,
							   closure);
				uxa_finish_access(pDstDrawable, UXA_GLAMOR_ACCESS_RW);
			}
			uxa_finish_access(pSrcDrawable, UXA_GLAMOR_ACCESS_RO);
		}

		if (!ok)
			goto fallback;

		return;
	}

	if (uxa_screen->force_fallback)
		goto fallback;

	pSrcPixmap = uxa_get_drawable_pixmap(pSrcDrawable);
	pDstPixmap = uxa_get_drawable_pixmap(pDstDrawable);
	if (!pSrcPixmap || !pDstPixmap)
		goto fallback;

	if (uxa_screen->info->check_copy &&
	    !uxa_screen->info->check_copy(pSrcPixmap, pDstPixmap,
					  pGC ? pGC->alu : GXcopy,
					  pGC ? pGC->planemask : FB_ALLONES))
		goto fallback;

	uxa_get_drawable_deltas(pSrcDrawable, pSrcPixmap, &src_off_x,
				&src_off_y);
	uxa_get_drawable_deltas(pDstDrawable, pDstPixmap, &dst_off_x,
				&dst_off_y);

	/* Mixed directions must be handled specially if the card is lame */
	if ((uxa_screen->info->flags & UXA_TWO_BITBLT_DIRECTIONS) &&
	    reverse != upsidedown) {
		if (uxa_copy_n_to_n_two_dir
		    (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy))
			return;
		goto fallback;
	}

	if (!uxa_pixmap_is_offscreen(pDstPixmap)) {
		int stride, bpp;
		char *dst;

		if (!uxa_pixmap_is_offscreen(pSrcPixmap))
			goto fallback;

		if (!uxa_screen->info->get_image)
			goto fallback;

		/* Don't bother with under 8bpp, XYPixmaps. */
		bpp = pSrcPixmap->drawable.bitsPerPixel;
		if (bpp != pDstDrawable->bitsPerPixel || bpp < 8)
			goto fallback;

		/* Only accelerate copies: no rop or planemask. */
		if (pGC && (!UXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask) || pGC->alu != GXcopy))
			goto fallback;

		dst = pDstPixmap->devPrivate.ptr;
		stride = pDstPixmap->devKind;
		bpp /= 8;
		while (nbox--) {
			if (!uxa_screen->info->get_image(pSrcPixmap,
							 pbox->x1 + dx + src_off_x,
							 pbox->y1 + dy + src_off_y,
							 pbox->x2 - pbox->x1,
							 pbox->y2 - pbox->y1,
							 (char *) dst +
							 (pbox->y1 + dst_off_y) * stride +
							 (pbox->x1 + dst_off_x) * bpp,
							 stride))
				goto fallback;

			pbox++;
		}

		return;
	}

	if (uxa_pixmap_is_offscreen(pSrcPixmap)) {
	    if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap,
						reverse ? -1 : 1,
						upsidedown ? -1 : 1,
						pGC ? pGC->alu : GXcopy,
						pGC ? pGC->
						planemask : FB_ALLONES))
		goto fallback;

	    while (nbox--) {
		(*uxa_screen->info->copy) (pDstPixmap,
					   pbox->x1 + dx + src_off_x,
					   pbox->y1 + dy + src_off_y,
					   pbox->x1 + dst_off_x,
					   pbox->y1 + dst_off_y,
					   pbox->x2 - pbox->x1,
					   pbox->y2 - pbox->y1);
		pbox++;
	    }

	    (*uxa_screen->info->done_copy) (pDstPixmap);
	} else {
	    int stride, bpp;
	    char *src;

	    if (!uxa_screen->info->put_image)
		goto fallback;

	    /* Don't bother with under 8bpp, XYPixmaps. */
	    bpp = pSrcPixmap->drawable.bitsPerPixel;
	    if (bpp != pDstDrawable->bitsPerPixel || bpp < 8)
		goto fallback;

	    /* Only accelerate copies: no rop or planemask. */
	    if (pGC && (!UXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask) || pGC->alu != GXcopy))
		goto fallback;

	    src = pSrcPixmap->devPrivate.ptr;
	    stride = pSrcPixmap->devKind;
	    bpp /= 8;
	    while (nbox--) {
		if (!uxa_screen->info->put_image(pDstPixmap,
						 pbox->x1 + dst_off_x,
						 pbox->y1 + dst_off_y,
						 pbox->x2 - pbox->x1,
						 pbox->y2 - pbox->y1,
						 (char *) src +
						 (pbox->y1 + dy + src_off_y) * stride +
						 (pbox->x1 + dx + src_off_x) * bpp,
						 stride))
		    goto fallback;

		pbox++;
	    }
	}

	return;

fallback:
	UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
		      uxa_drawable_location(pSrcDrawable),
		      uxa_drawable_location(pDstDrawable)));
	if (uxa_prepare_access(pDstDrawable, UXA_ACCESS_RW)) {
		if (pSrcDrawable == pDstDrawable ||
		    uxa_prepare_access(pSrcDrawable, UXA_ACCESS_RO)) {
			fbCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
				   dx, dy, reverse, upsidedown, bitplane,
				   closure);
			if (pSrcDrawable != pDstDrawable)
				uxa_finish_access(pSrcDrawable, UXA_ACCESS_RO);
		}
		uxa_finish_access(pDstDrawable, UXA_ACCESS_RW);
	}
}
Exemplo n.º 26
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);
}
Exemplo n.º 27
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);
}
Exemplo n.º 28
0
static void
uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n,
	       DDXPointPtr ppt, int *pwidth, int fSorted)
{
	ScreenPtr screen = pDrawable->pScreen;
	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
	RegionPtr pClip = fbGetCompositeClip(pGC);
	PixmapPtr dst_pixmap;
	BoxPtr pbox;
	int nbox;
	int x1, x2, y;
	int off_x, off_y;

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok = 0;

		if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) {
			ok = glamor_fill_spans_nf(pDrawable,
						  pGC, n, ppt, pwidth, fSorted);
			uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
		}

		if (!ok)
			goto fallback;

		return;
	}

	if (uxa_screen->force_fallback)
		goto fallback;

	if (pGC->fillStyle != FillSolid)
		goto fallback;

	dst_pixmap = uxa_get_offscreen_pixmap(pDrawable, &off_x, &off_y);
	if (!dst_pixmap)
		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) (dst_pixmap,
						 pGC->alu,
						 pGC->planemask,
						 pGC->fgPixel))
		goto fallback;

	while (n--) {
		x1 = ppt->x;
		y = ppt->y;
		x2 = x1 + (int)*pwidth;
		ppt++;
		pwidth++;

		nbox = REGION_NUM_RECTS(pClip);
		pbox = REGION_RECTS(pClip);
		while (nbox--) {
			int X1 = x1, X2 = x2;
			if (X1 < pbox->x1)
				X1 = pbox->x1;

			if (X2 > pbox->x2)
				X2 = pbox->x2;

			if (X2 > X1 && pbox->y1 <= y && pbox->y2 > y)
				(*uxa_screen->info->solid) (dst_pixmap,
							    X1 + off_x, y + off_y,
							    X2 + off_x, y + 1 + off_y);
			pbox++;
		}
	}
	(*uxa_screen->info->done_solid) (dst_pixmap);

	return;

fallback:
	uxa_check_fill_spans(pDrawable, pGC, n, ppt, pwidth, fSorted);
}
Exemplo n.º 29
0
/**
 * 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;
}
Exemplo n.º 30
0
/**
 * uxa_poly_lines() 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_lines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
	       DDXPointPtr ppt)
{
	xRectangle *prect;
	int x1, x2, y1, y2;
	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_lines_nf(pDrawable, pGC, mode, npt, ppt);
			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_lines(pDrawable, pGC, mode, npt, ppt);
		return;
	}

	prect = malloc(sizeof(xRectangle) * (npt - 1));
	if (!prect)
		return;
	x1 = ppt[0].x;
	y1 = ppt[0].y;
	/* If we have any non-horizontal/vertical, fall back. */
	for (i = 0; i < npt - 1; i++) {
		if (mode == CoordModePrevious) {
			x2 = x1 + ppt[i + 1].x;
			y2 = y1 + ppt[i + 1].y;
		} else {
			x2 = ppt[i + 1].x;
			y2 = ppt[i + 1].y;
		}

		if (x1 != x2 && y1 != y2) {
			free(prect);
			uxa_check_poly_lines(pDrawable, pGC, mode, npt, ppt);
			return;
		}

		if (x1 < x2) {
			prect[i].x = x1;
			prect[i].width = x2 - x1 + 1;
		} else {
			prect[i].x = x2;
			prect[i].width = x1 - x2 + 1;
		}
		if (y1 < y2) {
			prect[i].y = y1;
			prect[i].height = y2 - y1 + 1;
		} else {
			prect[i].y = y2;
			prect[i].height = y1 - y2 + 1;
		}

		x1 = x2;
		y1 = y2;
	}
	pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect);
	free(prect);
}