diff options
author | Adam Jackson <ajax@redhat.com> | 2016-09-26 13:28:42 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2016-09-26 14:18:16 -0400 |
commit | 2f7f7892b9e2fd8e50182cddd44c61931e233f0b (patch) | |
tree | 0c36edb2e7b2ca0d666004a0fa65f8db2fcdcdd3 | |
parent | 453f813bb4afd39eb5b6b3c4a822894e04b6b11b (diff) |
glamor: Semi-accelerate GetImage with non-trivial planemaskglamor-getimage-planemask
Just always do the download, and if the planemask isn't trivial mask the
returned data by the planemask on the CPU side.
This assumes that the image scanlines are padded to 32 bits, and that
bpp for the format is an even divisor of 32. This is true of fb if you
haven't forced 24bpp, which glamor doesn't support, and honestly neither
should fb.
This is a pretty decent speedup! With Xephyr, before and after this
change, with x11perf -pm 0x123456:
before after Operation
------------ -------------------- -------------------------
10100.0 89900.0 (8.901) ShmGetImage 10x10 square
6940.0 48500.0 (6.988) ShmGetImage 100x100 square
1190.0 4300.0 (3.613) ShmGetImage 500x500 square
9020.0 79600.0 (8.825) GetImage 10x10 square
6700.0 30600.0 (4.567) GetImage 100x100 square
395.0 2080.0 (5.266) GetImage 500x500 square
For comparison, after this change, with planemask, glamor is if anything
a little faster than fb for large images:
glamor fb Operation
------------ -------------------- -------------------------
89900.0 101000.0 (1.123) ShmGetImage 10x10 square
48500.0 42800.0 (0.882) ShmGetImage 100x100 square
4300.0 3090.0 (0.719) ShmGetImage 500x500 square
79600.0 97900.0 (1.230) GetImage 10x10 square
30600.0 29400.0 (0.961) GetImage 100x100 square
2080.0 2060.0 (0.990) GetImage 500x500 square
With no planemask, fb is still appreciably faster:
glamor fb Operation
------------ -------------------- -------------------------
88400.0 104000.0 (1.176) ShmGetImage 10x10 square
58300.0 80400.0 (1.379) ShmGetImage 100x100 square
8270.0 14800.0 (1.790) ShmGetImage 500x500 square
77900.0 96900.0 (1.244) GetImage 10x10 square
35400.0 44500.0 (1.257) GetImage 100x100 square
2600.0 4150.0 (1.596) GetImage 500x500 square
Which is fair enough. fb is very nearly memcpy in this path, and there's
still some overhead in glamor itself.
Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | glamor/glamor_image.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 315874995..62ac7dc9a 100644 --- a/glamor/glamor_image.c +++ b/glamor/glamor_image.c @@ -116,7 +116,7 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h, if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; - if (format != ZPixmap || !glamor_pm_is_solid(drawable->depth, plane_mask)) + if (format != ZPixmap) goto bail; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); @@ -128,6 +128,17 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h, drawable->x + off_x, drawable->y + off_y, -x, -y, (uint8_t *) d, byte_stride); + + if (!glamor_pm_is_solid(drawable->depth, plane_mask)) { + int i; + uint32_t *dest = (void *)d; + plane_mask = fbReplicatePixel(plane_mask, + BitsPerPixel(drawable->depth)); + + for (i = 0; i < w * h; i++) + dest[i] &= plane_mask; + } + return TRUE; bail: return FALSE; |