diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-10 00:41:05 +0000 | 
|---|---|---|
| committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-10 00:41:05 +0000 | 
| commit | c1d403266a611a68081690d19f6debb8e343095f (patch) | |
| tree | a4057fc3595abaecf8cea0a56705e90ee9f43d4d | |
| parent | 406776cd955c3c384d4a537300e21eebe4413666 (diff) | |
sna: Allow for xRGB uploads to replace their target bo
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| -rw-r--r-- | src/sna/sna.h | 5 | ||||
| -rw-r--r-- | src/sna/sna_blt.c | 98 | ||||
| -rw-r--r-- | src/sna/sna_io.c | 45 | 
3 files changed, 124 insertions, 24 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 42906598..07ae683b 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -665,6 +665,11 @@ struct kgem_bo *sna_replace(struct sna *sna,  			    PixmapPtr pixmap,  			    struct kgem_bo *bo,  			    const void *src, int stride); +struct kgem_bo *sna_replace__xor(struct sna *sna, +				 PixmapPtr pixmap, +				 struct kgem_bo *bo, +				 const void *src, int stride, +				 uint32_t and, uint32_t or);  Bool  sna_compute_composite_extents(BoxPtr extents, diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c index 64fcd061..2c503d26 100644 --- a/src/sna/sna_blt.c +++ b/src/sna/sna_blt.c @@ -1289,18 +1289,34 @@ blt_put_composite_with_alpha(struct sna *sna,  	int16_t dst_y = r->dst.y + op->dst.y;  	int16_t src_x = r->src.x + op->u.blt.sx;  	int16_t src_y = r->src.y + op->u.blt.sy; -	BoxRec box; -	box.x1 = dst_x; -	box.y1 = dst_y; -	box.x2 = dst_x + r->width; -	box.y2 = dst_y + r->height; +	if (!dst_priv->pinned && +	    dst_x <= 0 && dst_y <= 0 && +	    dst_x + r->width >= op->dst.width && +	    dst_y + r->height >= op->dst.height) { +		int bpp = dst->drawable.bitsPerPixel / 8; + +		data += (src_x - dst_x) * bpp; +		data += (src_y - dst_y) * pitch; + +		dst_priv->gpu_bo = +			sna_replace__xor(sna, op->dst.pixmap, dst_priv->gpu_bo, +					 data, pitch, +					 0xffffffff, op->u.blt.pixel); +	} else { +		BoxRec box; + +		box.x1 = dst_x; +		box.y1 = dst_y; +		box.x2 = dst_x + r->width; +		box.y2 = dst_y + r->height; -	sna_write_boxes__xor(sna, dst, -			     dst_priv->gpu_bo, 0, 0, -			     data, pitch, src_x, src_y, -			     &box, 1, -			     0xffffffff, op->u.blt.pixel); +		sna_write_boxes__xor(sna, dst, +				     dst_priv->gpu_bo, 0, 0, +				     data, pitch, src_x, src_y, +				     &box, 1, +				     0xffffffff, op->u.blt.pixel); +	}  }  fastcall static void @@ -1309,18 +1325,35 @@ blt_put_composite_box_with_alpha(struct sna *sna,  				 const BoxRec *box)  {  	PixmapPtr src = op->u.blt.src_pixmap; +	struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap);  	DBG(("%s: src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__,  	     op->u.blt.sx, op->u.blt.sy,  	     op->dst.x, op->dst.y)); -	sna_write_boxes__xor(sna, op->dst.pixmap, -			     op->dst.bo, op->dst.x, op->dst.y, -			     src->devPrivate.ptr, -			     src->devKind, -			     op->u.blt.sx, op->u.blt.sy, -			     box, 1, -			     0xffffffff, op->u.blt.pixel); +	if (!dst_priv->pinned && +	    box->x2 - box->x1 == op->dst.width && +	    box->y2 - box->y1 == op->dst.height) { +		int pitch = src->devKind; +		int bpp = src->drawable.bitsPerPixel / 8; +		char *data = src->devPrivate.ptr; + +		data += (box->y1 + op->u.blt.sy) * pitch; +		data += (box->x1 + op->u.blt.sx) * bpp; + +		dst_priv->gpu_bo = +			sna_replace__xor(sna, op->dst.pixmap, op->dst.bo, +					 data, pitch, +					 0xffffffff, op->u.blt.pixel); +	} else { +		sna_write_boxes__xor(sna, op->dst.pixmap, +				     op->dst.bo, op->dst.x, op->dst.y, +				     src->devPrivate.ptr, +				     src->devKind, +				     op->u.blt.sx, op->u.blt.sy, +				     box, 1, +				     0xffffffff, op->u.blt.pixel); +	}  }  static void @@ -1329,19 +1362,36 @@ blt_put_composite_boxes_with_alpha(struct sna *sna,  				   const BoxRec *box, int n)  {  	PixmapPtr src = op->u.blt.src_pixmap; +	struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap);  	DBG(("%s: src=(%d, %d), dst=(%d, %d), [(%d, %d), (%d, %d) x %d]\n", __FUNCTION__,  	     op->u.blt.sx, op->u.blt.sy,  	     op->dst.x, op->dst.y,  	     box->x1, box->y1, box->x2, box->y2, n)); -	sna_write_boxes__xor(sna, op->dst.pixmap, -			     op->dst.bo, op->dst.x, op->dst.y, -			     src->devPrivate.ptr, -			     src->devKind, -			     op->u.blt.sx, op->u.blt.sy, -			     box, n, -			     0xffffffff, op->u.blt.pixel); +	if (n == 1 && !dst_priv->pinned && +	    box->x2 - box->x1 == op->dst.width && +	    box->y2 - box->y1 == op->dst.height) { +		int pitch = src->devKind; +		int bpp = src->drawable.bitsPerPixel / 8; +		char *data = src->devPrivate.ptr; + +		data += (box->y1 + op->u.blt.sy) * pitch; +		data += (box->x1 + op->u.blt.sx) * bpp; + +		dst_priv->gpu_bo = +			sna_replace__xor(sna, op->dst.pixmap, op->dst.bo, +					 data, pitch, +					 0xffffffff, op->u.blt.pixel); +	} else { +		sna_write_boxes__xor(sna, op->dst.pixmap, +				     op->dst.bo, op->dst.x, op->dst.y, +				     src->devPrivate.ptr, +				     src->devKind, +				     op->u.blt.sx, op->u.blt.sy, +				     box, n, +				     0xffffffff, op->u.blt.pixel); +	}  }  static Bool diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index dbf17745..50fae258 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -824,3 +824,48 @@ struct kgem_bo *sna_replace(struct sna *sna,  	return bo;  } + +struct kgem_bo *sna_replace__xor(struct sna *sna, +				 PixmapPtr pixmap, +				 struct kgem_bo *bo, +				 const void *src, int stride, +				 uint32_t and, uint32_t or) +{ +	struct kgem *kgem = &sna->kgem; +	void *dst; + +	DBG(("%s(handle=%d, %dx%d, bpp=%d, tiling=%d)\n", +	     __FUNCTION__, bo->handle, +	     pixmap->drawable.width, +	     pixmap->drawable.height, +	     pixmap->drawable.bitsPerPixel, +	     bo->tiling)); + +	if (kgem_bo_is_busy(bo)) { +		struct kgem_bo *new_bo; + +		new_bo = kgem_create_2d(kgem, +					pixmap->drawable.width, +					pixmap->drawable.height, +					pixmap->drawable.bitsPerPixel, +					bo->tiling, +					CREATE_GTT_MAP | CREATE_INACTIVE); +		if (new_bo) { +			kgem_bo_destroy(kgem, bo); +			bo = new_bo; +		} +	} + +	dst = kgem_bo_map(kgem, bo, PROT_READ | PROT_WRITE); +	if (dst) { +		memcpy_xor(src, dst, pixmap->drawable.bitsPerPixel, +			   stride, bo->pitch, +			   0, 0, +			   0, 0, +			   pixmap->drawable.width, +			   pixmap->drawable.height, +			   and, or); +	} + +	return bo; +}  | 
