summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-04 17:41:16 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-04 17:41:16 +0000
commit89739b711f42c3dbed7d3f4e6da0cdd61a5205ae (patch)
tree43fa9a84cd1e6bc30bb6e59ccfa018efec82db1e
parent878fbfe509da0a25dff8515d6d3b38ca3826466e (diff)
sna: Expand small stipples into 8x8 patterns
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna.h5
-rw-r--r--src/sna/sna_accel.c61
2 files changed, 65 insertions, 1 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 32288ca3..b4d109cf 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -703,4 +703,9 @@ memcpy_blt(const void *src, void *dst, int bpp,
#define SNA_CREATE_FB 0x10
#define SNA_CREATE_SCRATCH 0x11
+inline static bool is_power_of_two(unsigned x)
+{
+ return (x & (x-1)) == 0;
+}
+
#endif /* _SNA_H */
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ea178f32..da13efa8 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -7008,6 +7008,58 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
}
static bool
+sna_poly_fill_rect_stippled_nxm_blt(DrawablePtr drawable,
+ struct kgem_bo *bo,
+ struct sna_damage **damage,
+ GCPtr gc, int n, xRectangle *r,
+ const BoxRec *extents, unsigned clipped)
+{
+ PixmapPtr scratch, stipple;
+ uint8_t bytes[8], *dst = bytes;
+ const uint8_t *src, *end;
+ int j, stride;
+ bool ret;
+
+ DBG(("%s: expanding %dx%d stipple to 8x8\n",
+ __FUNCTION__,
+ gc->stipple->drawable.width,
+ gc->stipple->drawable.height));
+
+ scratch = GetScratchPixmapHeader(drawable->pScreen,
+ 8, 8, 1, 1, 1, bytes);
+ if (scratch == NullPixmap)
+ return false;
+
+ stipple = gc->stipple;
+ gc->stipple = scratch;
+
+ stride = stipple->devKind;
+ src = stipple->devPrivate.ptr;
+ end = src + stride * stipple->drawable.height;
+ for(j = 0; j < 8; j++) {
+ switch (stipple->drawable.width) {
+ case 1: *dst = (*src & 1) * 0xff; break;
+ case 2: *dst = (*src & 3) * 0x55; break;
+ case 4: *dst = (*src & 15) * 0x11; break;
+ case 8: *dst = *src; break;
+ default: assert(0); break;
+ }
+ dst++;
+ src += stride;
+ if (src == end)
+ src = stipple->devPrivate.ptr;
+ }
+
+ ret = sna_poly_fill_rect_stippled_8x8_blt(drawable, bo, damage,
+ gc, n, r, extents, clipped);
+
+ gc->stipple = stipple;
+ FreeScratchPixmapHeader(scratch);
+
+ return ret;
+}
+
+static bool
sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
struct kgem_bo *bo,
struct sna_damage **damage,
@@ -7685,11 +7737,18 @@ sna_poly_fill_rect_stippled_blt(DrawablePtr drawable,
extents->y2 - gc->patOrg.y - drawable->y,
stipple->drawable.width, stipple->drawable.height));
- if (stipple->drawable.width == 8 && stipple->drawable.height == 8)
+ if ((stipple->drawable.width | stipple->drawable.height) == 8)
return sna_poly_fill_rect_stippled_8x8_blt(drawable, bo, damage,
gc, n, rect,
extents, clipped);
+ if ((stipple->drawable.width | stipple->drawable.height) <= 0xc &&
+ is_power_of_two(stipple->drawable.width) &&
+ is_power_of_two(stipple->drawable.height))
+ return sna_poly_fill_rect_stippled_nxm_blt(drawable, bo, damage,
+ gc, n, rect,
+ extents, clipped);
+
if (extents->x2 - gc->patOrg.x - drawable->x <= stipple->drawable.width &&
extents->y2 - gc->patOrg.y - drawable->y <= stipple->drawable.height) {
if (stipple->drawable.width <= 8 && stipple->drawable.height <= 8)