Пример #1
0
void
uxa_check_composite(CARD8 op,
		    PicturePtr pSrc,
		    PicturePtr pMask,
		    PicturePtr pDst,
		    INT16 xSrc, INT16 ySrc,
		    INT16 xMask, INT16 yMask,
		    INT16 xDst, INT16 yDst,
		    CARD16 width, CARD16 height)
{
	ScreenPtr screen = pDst->pDrawable->pScreen;

	UXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));

	if (uxa_picture_prepare_access(pDst, UXA_ACCESS_RW)) {
		if (uxa_picture_prepare_access(pSrc, UXA_ACCESS_RO)) {
			if (!pMask || uxa_picture_prepare_access(pMask, UXA_ACCESS_RO)) {
				fbComposite(op, pSrc, pMask, pDst,
					    xSrc, ySrc,
					    xMask, yMask,
					    xDst, yDst,
					    width, height);
				if (pMask)
					uxa_picture_finish_access(pMask, UXA_ACCESS_RO);
			}
			uxa_picture_finish_access(pSrc, UXA_ACCESS_RO);
		}
		uxa_picture_finish_access(pDst, UXA_ACCESS_RW);
	}
}
Пример #2
0
void
KdCheckComposite (CARD8      op,
		  PicturePtr pSrc,
		  PicturePtr pMask,
		  PicturePtr pDst,
		  INT16      xSrc,
		  INT16      ySrc,
		  INT16      xMask,
		  INT16      yMask,
		  INT16      xDst,
		  INT16      yDst,
		  CARD16     width,
		  CARD16     height)
{
    KdCheckSync (pDst->pDrawable->pScreen);
    fbComposite (op,
		 pSrc,
		 pMask,
		 pDst,
		 xSrc,
		 ySrc,
		 xMask,
		 yMask,
		 xDst,
		 yDst,
		 width,
		 height);
}
Пример #3
0
/**
 * Does an fbComposite to complete the requested drawing operation.
 */
static void
ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
	       int dstX, int dstY, int w, int h)
{
    KdScreenPriv(pDst->drawable.pScreen);
    KdScreenInfo *screen = pScreenPriv->screen;
    EphyrScrPriv *scrpriv = screen->driver;
    EphyrFakexaPriv *fakexa = scrpriv->fakexa;

    fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture,
		fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY,
		w, h);
}
Пример #4
0
void
fbCompositeGeneral (CARD8	op,
                    PicturePtr	pSrc,
                    PicturePtr	pMask,
                    PicturePtr	pDst,
                    INT16	xSrc,
                    INT16	ySrc,
                    INT16	xMask,
                    INT16	yMask,
                    INT16	xDst,
                    INT16	yDst,
                    CARD16	width,
                    CARD16	height)
{
    fbComposite (op, pSrc, pMask, pDst,
                 xSrc, ySrc, xMask, yMask, xDst, yDst,
                 width, height);
}
Пример #5
0
fastcall static void
sna_tiling_composite_spans_done(struct sna *sna,
				const struct sna_composite_spans_op *op)
{
	struct sna_tile_state *tile = op->base.priv;
	struct sna_composite_spans_op tmp;
	int x, y, n, step;
	bool force_fallback = false;

	/* Use a small step to accommodate enlargement through tile alignment */
	step = sna->render.max_3d_size;
	if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) ||
	    tile->dst_y & 63)
		step /= 2;
	while (step * step * 4 > sna->kgem.max_copy_tile_size)
		step /= 2;

	DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__,
	     tile->width, tile->height, tile->rect_count, step));

	if (tile->rect_count == 0)
		goto done;

	for (y = 0; y < tile->height; y += step) {
		int height = step;
		if (y + height > tile->height)
			height = tile->height - y;
		for (x = 0; x < tile->width; x += step) {
			const struct sna_tile_span *r = (void *)tile->rects;
			int width = step;
			if (x + width > tile->width)
				width = tile->width - x;
			if (!force_fallback &&
			    sna->render.composite_spans(sna, tile->op,
							tile->src, tile->dst,
							tile->src_x + x,  tile->src_y + y,
							tile->dst_x + x,  tile->dst_y + y,
							width, height, tile->flags,
							memset(&tmp, 0, sizeof(tmp)))) {
				for (n = 0; n < tile->rect_count; n++) {
					BoxRec b;

					b.x1 = r->box.x1 - tile->dst_x;
					if (b.x1 < x)
						b.x1 = x;

					b.y1 = r->box.y1 - tile->dst_y;
					if (b.y1 < y)
						b.y1 = y;

					b.x2 = r->box.x2 - tile->dst_x;
					if (b.x2 > x + width)
						b.x2 = x + width;

					b.y2 = r->box.y2 - tile->dst_y;
					if (b.y2 > y + height)
						b.y2 = y + height;

					DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d)\n",
					     __FUNCTION__, n,
					     r->box.x1, r->box.y1,
					     r->box.x2-r->box.x1, r->box.y2-r->box.y1,
					     x, y, width, height,
					     b.x1, b.y1, b.x2, b.y2));

					if (b.y2 > b.y1 && b.x2 > b.x1)
						tmp.box(sna, &tmp, &b, r->opacity);
					r++;
				}
				tmp.done(sna, &tmp);
			} else {
				unsigned int flags;

				DBG(("%s -- falback\n", __FUNCTION__));

				if (tile->op <= PictOpSrc)
					flags = MOVE_WRITE;
				else
					flags = MOVE_WRITE | MOVE_READ;
				if (!sna_drawable_move_to_cpu(tile->dst->pDrawable,
							      flags))
					goto done;
				if (tile->dst->alphaMap &&
				    !sna_drawable_move_to_cpu(tile->dst->alphaMap->pDrawable,
							      flags))
					goto done;

				if (tile->src->pDrawable &&
				    !sna_drawable_move_to_cpu(tile->src->pDrawable,
							      MOVE_READ))
					goto done;
				if (tile->src->alphaMap &&
				    !sna_drawable_move_to_cpu(tile->src->alphaMap->pDrawable,
							      MOVE_READ))
					goto done;

				for (n = 0; n < tile->rect_count; n++) {
					BoxRec b;

					b.x1 = r->box.x1 - tile->dst_x;
					if (b.x1 < x)
						b.x1 = x;

					b.y1 = r->box.y1 - tile->dst_y;
					if (b.y1 < y)
						b.y1 = y;

					b.x2 = r->box.x2 - tile->dst_x;
					if (b.x2 > x + width)
						b.x2 = x + width;

					b.y2 = r->box.y2 - tile->dst_y;
					if (b.y2 > y + height)
						b.y2 = y + height;

					DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d)\n",
					     __FUNCTION__, n,
					     r->box.x1, r->box.y1,
					     r->box.x2-r->box.x1, r->box.y2-r->box.y1,
					     x, y, width, height,
					     b.x1, b.y1, b.x2, b.y2));

					if (b.y2 > b.y1 && b.x2 > b.x1) {
						xRenderColor alpha;
						PicturePtr mask;
						int error;

						alpha.red = alpha.green = alpha.blue = 0;
						alpha.alpha = r->opacity * 0xffff;

						mask = CreateSolidPicture(0, &alpha, &error);
						if (!mask)
							goto done;

						if (sigtrap_get() == 0) {
							fbComposite(tile->op,
								    tile->src, mask, tile->dst,
								    tile->src_x + x,  tile->src_y + y,
								    0, 0,
								    tile->dst_x + x,  tile->dst_y + y,
								    width, height);
							sigtrap_put();
						}

						FreePicture(mask, 0);
					}
					r++;
				}

				force_fallback = true;
			}
		}
	}

done:
	if (tile->rects != tile->rects_embedded)
		free(tile->rects);
	free(tile);
}
Пример #6
0
static void
sna_tiling_composite_done(struct sna *sna,
			  const struct sna_composite_op *op)
{
	struct sna_tile_state *tile = op->priv;
	struct sna_composite_op tmp;
	int x, y, n, step;

	/* Use a small step to accommodate enlargement through tile alignment */
	step = sna->render.max_3d_size;
	if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) ||
	    tile->dst_y & 63)
		step /= 2;
	while (step * step * 4 > sna->kgem.max_copy_tile_size)
		step /= 2;

	DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__,
	     tile->width, tile->height, tile->rect_count, step));

	if (tile->rect_count == 0)
		goto done;

	for (y = 0; y < tile->height; y += step) {
		int height = step;
		if (y + height > tile->height)
			height = tile->height - y;
		for (x = 0; x < tile->width; x += step) {
			int width = step;
			if (x + width > tile->width)
				width = tile->width - x;
			if (sna->render.composite(sna, tile->op,
						  tile->src, tile->mask, tile->dst,
						  tile->src_x + x,  tile->src_y + y,
						  tile->mask_x + x, tile->mask_y + y,
						  tile->dst_x + x,  tile->dst_y + y,
						  width, height,
						  COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) {
				for (n = 0; n < tile->rect_count; n++) {
					const struct sna_composite_rectangles *r = &tile->rects[n];
					int x1, x2, dx, y1, y2, dy;

					x1 = r->dst.x - tile->dst_x, dx = 0;
					if (x1 < x)
						dx = x - x1, x1 = x;
					y1 = r->dst.y - tile->dst_y, dy = 0;
					if (y1 < y)
						dy = y - y1, y1 = y;

					x2 = r->dst.x + r->width - tile->dst_x;
					if (x2 > x + width)
						x2 = x + width;
					y2 = r->dst.y + r->height - tile->dst_y;
					if (y2 > y + height)
						y2 = y + height;

					DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d), delta=(%d,%d)\n",
					     __FUNCTION__, n,
					     r->dst.x, r->dst.y,
					     r->width, r->height,
					     x, y, width, height,
					     x1, y1, x2, y2,
					     dx, dy));

					if (y2 > y1 && x2 > x1) {
						struct sna_composite_rectangles rr;
						rr.src.x = dx + r->src.x;
						rr.src.y = dy + r->src.y;

						rr.mask.x = dx + r->mask.x;
						rr.mask.y = dy + r->mask.y;

						rr.dst.x = dx + r->dst.x;
						rr.dst.y = dy + r->dst.y;

						rr.width  = x2 - x1;
						rr.height = y2 - y1;

						tmp.blt(sna, &tmp, &rr);
					}
				}
				tmp.done(sna, &tmp);
			} else {
				unsigned int flags;
				DBG(("%s -- falback\n", __FUNCTION__));

				if (tile->op <= PictOpSrc)
					flags = MOVE_WRITE;
				else
					flags = MOVE_WRITE | MOVE_READ;
				if (!sna_drawable_move_to_cpu(tile->dst->pDrawable,
							      flags))
					goto done;
				if (tile->dst->alphaMap &&
				    !sna_drawable_move_to_cpu(tile->dst->alphaMap->pDrawable,
							      flags))
					goto done;

				if (tile->src->pDrawable &&
				    !sna_drawable_move_to_cpu(tile->src->pDrawable,
							      MOVE_READ))
					goto done;
				if (tile->src->alphaMap &&
				    !sna_drawable_move_to_cpu(tile->src->alphaMap->pDrawable,
							      MOVE_READ))
					goto done;

				if (tile->mask && tile->mask->pDrawable &&
				    !sna_drawable_move_to_cpu(tile->mask->pDrawable,
							      MOVE_READ))
					goto done;

				if (tile->mask && tile->mask->alphaMap &&
				    !sna_drawable_move_to_cpu(tile->mask->alphaMap->pDrawable,
							      MOVE_READ))
					goto done;

				if (sigtrap_get() == 0) {
					fbComposite(tile->op,
						    tile->src, tile->mask, tile->dst,
						    tile->src_x + x,  tile->src_y + y,
						    tile->mask_x + x, tile->mask_y + y,
						    tile->dst_x + x,  tile->dst_y + y,
						    width, height);
					sigtrap_put();
				}
			}
		}
	}

done:
	if (tile->rects != tile->rects_embedded)
		free(tile->rects);
	free(tile);
}
Пример #7
0
static void
radeon_glamor_composite(CARD8 op,
		    PicturePtr pSrc,
		    PicturePtr pMask,
		    PicturePtr pDst,
		    INT16 xSrc, INT16 ySrc,
		    INT16 xMask, INT16 yMask,
		    INT16 xDst, INT16 yDst,
		    CARD16 width, CARD16 height)
{
	ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pDrawable->pScreen);
	RADEONInfoPtr info;
	PixmapPtr pixmap;
	struct radeon_pixmap *dst_priv, *src_priv = NULL, *mask_priv = NULL;
	Bool gpu_done = FALSE;

	if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
		goto fallback;

	pixmap = get_drawable_pixmap(pDst->pDrawable);
	if (&pixmap->drawable != pDst->pDrawable ||
	    pixmap->usage_hint != RADEON_CREATE_PIXMAP_SCANOUT)
		goto fallback;

	dst_priv = radeon_get_pixmap_private(pixmap);
	if (!radeon_glamor_prepare_access_gpu(dst_priv))
		goto fallback;

	info = RADEONPTR(scrn);
	if (!pSrc->pDrawable ||
	    ((pixmap = get_drawable_pixmap(pSrc->pDrawable)) &&
	     (src_priv = radeon_get_pixmap_private(pixmap)) &&
	     radeon_glamor_prepare_access_gpu(src_priv))) {
		if (!pMask || !pMask->pDrawable ||
		    ((pixmap = get_drawable_pixmap(pMask->pDrawable)) &&
		     (mask_priv = radeon_get_pixmap_private(pixmap)) &&
		     radeon_glamor_prepare_access_gpu(mask_priv))) {
			info->glamor.SavedComposite(op, pSrc, pMask, pDst,
						    xSrc, ySrc, xMask, yMask,
						    xDst, yDst, width, height);
			gpu_done = TRUE;

			if (mask_priv)
				radeon_glamor_finish_access_gpu_ro(info, mask_priv);
		}

		if (src_priv)
			radeon_glamor_finish_access_gpu_ro(info, src_priv);
	}
	radeon_glamor_finish_access_gpu_rw(info, dst_priv);

	if (gpu_done)
		return;

fallback:
	if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, pDst)) {
		if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, pSrc)) {
			if (!pMask ||
			    radeon_glamor_picture_prepare_access_cpu_ro(scrn, pMask)) {
				fbComposite(op, pSrc, pMask, pDst,
					    xSrc, ySrc,
					    xMask, yMask,
					    xDst, yDst,
					    width, height);
				if (pMask)
					radeon_glamor_picture_finish_access_cpu(pMask);
			}
			radeon_glamor_picture_finish_access_cpu(pSrc);
		}
		radeon_glamor_picture_finish_access_cpu(pDst);
	}
}