[Mesa-dev] [PATCH] mesa: add a couple fast-paths to fast_read_rgba_pixels_memcpy()
Brian Paul
brianp at vmware.com
Tue Apr 17 09:51:41 PDT 2012
Accelerates a few glReadPixels cases for WebGL.
See https://bugs.freedesktop.org/show_bug.cgi?id=48545
Note: This is a candidate for the 8.0 branch.
---
src/mesa/main/readpix.c | 61 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 4918549..ace1c8e 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -208,6 +208,11 @@ read_stencil_pixels( struct gl_context *ctx,
ctx->Driver.UnmapRenderbuffer(ctx, rb);
}
+
+/**
+ * Try to do glReadPixels of RGBA data using a simple memcpy or swizzle.
+ * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
+ */
static GLboolean
fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
GLint x, GLint y,
@@ -220,9 +225,23 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
GLubyte *dst, *map;
int dstStride, stride, j, texelBytes;
-
- if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
- ctx->Pack.SwapBytes))
+ GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE;
+
+ /* XXX we could check for other swizzle/special cases here as needed */
+ if (rb->Format == MESA_FORMAT_RGBA8888_REV &&
+ format == GL_BGRA &&
+ type == GL_UNSIGNED_INT_8_8_8_8_REV &&
+ !ctx->Pack.SwapBytes) {
+ swizzle_rb = GL_TRUE;
+ }
+ else if (rb->Format == MESA_FORMAT_XRGB8888 &&
+ format == GL_BGRA &&
+ type == GL_UNSIGNED_INT_8_8_8_8_REV &&
+ !ctx->Pack.SwapBytes) {
+ copy_xrgb = GL_TRUE;
+ }
+ else if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
+ ctx->Pack.SwapBytes))
return GL_FALSE;
/* If the format is unsigned normalized then we can ignore clamping
@@ -247,10 +266,38 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
}
texelBytes = _mesa_get_format_bytes(rb->Format);
- for (j = 0; j < height; j++) {
- memcpy(dst, map, width * texelBytes);
- dst += dstStride;
- map += stride;
+
+ if (swizzle_rb) {
+ /* swap R/B */
+ for (j = 0; j < height; j++) {
+ int i;
+ for (i = 0; i < width; i++) {
+ dst[i*4+0] = map[i*4+2];
+ dst[i*4+1] = map[i*4+1];
+ dst[i*4+2] = map[i*4+0];
+ dst[i*4+3] = map[i*4+3];
+ }
+ dst += dstStride;
+ map += stride;
+ }
+ } else if (copy_xrgb) {
+ /* convert xrgb -> argb */
+ for (j = 0; j < height; j++) {
+ GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
+ int i;
+ for (i = 0; i < width; i++) {
+ dst4[i] = map4[i] | 0xff000000; /* set A=0xff */
+ }
+ dst += dstStride;
+ map += stride;
+ }
+ } else {
+ /* just memcpy */
+ for (j = 0; j < height; j++) {
+ memcpy(dst, map, width * texelBytes);
+ dst += dstStride;
+ map += stride;
+ }
}
ctx->Driver.UnmapRenderbuffer(ctx, rb);
--
1.7.3.4
More information about the mesa-dev
mailing list