[Mesa-dev] [PATCH 08/17] swrast: Add a readpixels fast-path based on memcpy and MapRenderbuffer.

Eric Anholt eric at anholt.net
Tue Nov 1 16:17:33 PDT 2011


v2: Move _mesa_get_format_bytes out of the loop.
---
 src/mesa/swrast/s_readpix.c |   57 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index 30c0c92..5f42202 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -270,6 +270,47 @@ fast_read_rgba_pixels( struct gl_context *ctx,
    return GL_FALSE;
 }
 
+static GLboolean
+fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
+			      GLint x, GLint y,
+			      GLsizei width, GLsizei height,
+			      GLenum format, GLenum type,
+			      GLvoid *pixels,
+			      const struct gl_pixelstore_attrib *packing,
+			      GLbitfield transferOps )
+{
+   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))
+      return GL_FALSE;
+
+   /* check for things we can't handle here */
+   if (packing->SwapBytes ||
+       packing->LsbFirst) {
+      return GL_FALSE;
+   }
+
+   dstStride = _mesa_image_row_stride(packing, width, format, type);
+   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
+					   format, type, 0, 0);
+
+   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
+			       &map, &stride);
+
+   texelBytes = _mesa_get_format_bytes(rb->Format);
+   for (j = 0; j < height; j++) {
+      memcpy(dst, map, width * texelBytes);
+      dst += dstStride;
+      map += stride;
+   }
+
+   ctx->Driver.UnmapRenderbuffer(ctx, rb);
+
+   return GL_TRUE;
+}
+
 
 /**
  * When we're using a low-precision color buffer (like 16-bit 5/6/5)
@@ -338,10 +379,18 @@ read_rgba_pixels( struct gl_context *ctx,
       transferOps |= IMAGE_CLAMP_BIT;
    }
 
-   /* Try the optimized path first. */
-   if (fast_read_rgba_pixels(ctx, x, y, width, height,
-                             format, type, pixels, packing, transferOps)) {
-      return; /* done! */
+   if (!transferOps) {
+      /* Try the optimized paths first. */
+      if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height,
+				       format, type, pixels, packing,
+				       transferOps)) {
+	 return;
+      }
+
+      if (fast_read_rgba_pixels(ctx, x, y, width, height,
+				format, type, pixels, packing, transferOps)) {
+	 return;
+      }
    }
 
    /* width should never be > MAX_WIDTH since we did clipping earlier */
-- 
1.7.7



More information about the mesa-dev mailing list