summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-10 00:41:05 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-10 00:41:05 +0000
commitc1d403266a611a68081690d19f6debb8e343095f (patch)
treea4057fc3595abaecf8cea0a56705e90ee9f43d4d
parent406776cd955c3c384d4a537300e21eebe4413666 (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.h5
-rw-r--r--src/sna/sna_blt.c98
-rw-r--r--src/sna/sna_io.c45
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;
+}