summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-07-18 16:21:27 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-07-19 14:04:48 +0100
commit6921abd81017c9ed7f3b2413784068fbc609a0ea (patch)
tree2470a6b0af4eaefaa2d44c84a1dfc662f24a528e /src
parent4da830864983ffe482388e4e4cfee02d106c895e (diff)
sna: Add a fast path for the most common fallback for CPU-CPU blits
This path will mostly be upload for individual glyph uploads, for which the malloc overhead is significant. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna_blt.c7
-rw-r--r--src/sna/sna_composite.c39
-rw-r--r--src/sna/sna_render.h7
3 files changed, 46 insertions, 7 deletions
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index beef9a65..b4ef083f 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1953,13 +1953,6 @@ prepare_blt_put(struct sna *sna,
return true;
}
-#define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format), \
- PICT_FORMAT_TYPE(format), \
- 0, \
- PICT_FORMAT_R(format), \
- PICT_FORMAT_G(format), \
- PICT_FORMAT_B(format))
-
static bool
is_clear(PixmapPtr pixmap)
{
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index ea4a1003..36e2bdee 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -470,6 +470,7 @@ sna_composite_fb(CARD8 op,
int src_xoff, src_yoff;
int msk_xoff, msk_yoff;
int dst_xoff, dst_yoff;
+ int16_t tx, ty;
unsigned flags;
DBG(("%s -- op=%d, fallback dst=(%d, %d)+(%d, %d), size=(%d, %d): region=((%d,%d), (%d, %d))\n",
@@ -519,6 +520,44 @@ sna_composite_fb(CARD8 op,
if (mask)
validate_source(mask);
+ if (mask == NULL &&
+ src->pDrawable &&
+ src->filter != PictFilterConvolution &&
+ (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(src->format))) &&
+ (dst->format == src->format || dst->format == alphaless(src->format)) &&
+ sna_transform_is_integer_translation(src->transform, &tx, &ty) &&
+ region->extents.x1 + src_x + tx >= 0 &&
+ region->extents.y1 + src_y + ty >= 0 &&
+ region->extents.x2 + src_x + tx <= src->pDrawable->width &&
+ region->extents.x2 + src_y + ty <= src->pDrawable->height) {
+ PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable);
+ int nbox = RegionNumRects(region);
+ BoxPtr box = RegionRects(region);
+
+ src_x += tx; src_y += ty;
+
+ get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty);
+ src_x += tx; src_y += ty;
+
+ get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
+ dst_x += tx; dst_y += ty;
+
+ do {
+ memcpy_blt(src_pixmap->devPrivate.ptr,
+ dst_pixmap->devPrivate.ptr,
+ dst_pixmap->drawable.bitsPerPixel,
+ src_pixmap->devKind,
+ dst_pixmap->devKind,
+ box->x1 + src_x, box->y1 + src_y,
+ box->x1 + dst_x, box->y1 + dst_y,
+ box->x2 - box->x1, box->y2 - box->y1);
+ box++;
+ } while (--nbox);
+
+ return;
+ }
+
src_image = image_from_pict(src, FALSE, &src_xoff, &src_yoff);
mask_image = image_from_pict(mask, FALSE, &msk_xoff, &msk_yoff);
dest_image = image_from_pict(dst, TRUE, &dst_xoff, &dst_yoff);
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index aace869e..26363945 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -775,4 +775,11 @@ static inline bool sna_vertex_wait__locked(struct sna_render *r)
return was_active;
}
+#define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format), \
+ PICT_FORMAT_TYPE(format), \
+ 0, \
+ PICT_FORMAT_R(format), \
+ PICT_FORMAT_G(format), \
+ PICT_FORMAT_B(format))
+
#endif /* SNA_RENDER_H */