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; +} |