summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast/s_readpix.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2006-10-12 23:17:02 +0000
committerBrian Paul <[email protected]>2006-10-12 23:17:02 +0000
commit76e778dce59aa6f290db50242df945943fc47b05 (patch)
tree07ad7bf3d7a54f49e86ff650fc7a9d4ce5d40338 /src/mesa/swrast/s_readpix.c
parent4bb9f4115c4b1930a140da78feff953e80f8a4f5 (diff)
Lots of changes to support runtime renderbuffer depths.
_swrast_read_rgba_span() now takes a datatype parameter. New optimization for glReadPixels(format=GL_RGB). New glCopyPixels optimization for the simple, common cases.
Diffstat (limited to 'src/mesa/swrast/s_readpix.c')
-rw-r--r--src/mesa/swrast/s_readpix.c128
1 files changed, 74 insertions, 54 deletions
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index a73bb81aacb..334dc02918d 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.2
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
@@ -197,7 +197,7 @@ read_stencil_pixels( GLcontext *ctx,
* scaling, biasing, mapping, etc. are disabled.
*/
static GLboolean
-read_fast_rgba_pixels( GLcontext *ctx,
+fast_read_rgba_pixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
@@ -206,53 +206,59 @@ read_fast_rgba_pixels( GLcontext *ctx,
{
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
+ ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
+
/* clipping should have already been done */
ASSERT(x + width <= rb->Width);
ASSERT(y + height <= rb->Height);
- /* can't do scale, bias, mapping, etc */
- if (ctx->_ImageTransferState)
- return GL_FALSE;
-
- /* can't do fancy pixel packing */
- if (packing->Alignment != 1 || packing->SwapBytes || packing->LsbFirst)
+ /* check for things we can't handle here */
+ if (ctx->_ImageTransferState ||
+ packing->SwapBytes ||
+ packing->LsbFirst) {
return GL_FALSE;
+ }
- /* if the pixel format exactly matches the renderbuffer format */
if (format == GL_RGBA && rb->DataType == type) {
- GLint rowLength = (packing->RowLength > 0) ? packing->RowLength : width;
- GLint pixelSize, row;
- GLubyte *dest;
-
- if (type == GL_UNSIGNED_BYTE)
- pixelSize = 4 * sizeof(GLubyte);
- else if (type == GL_UNSIGNED_SHORT)
- pixelSize = 4 * sizeof(GLushort);
- else {
- ASSERT(type == GL_FLOAT);
- pixelSize = 4 * sizeof(GLfloat);
- }
-
- dest = (GLubyte *) pixels
- + (packing->SkipRows * rowLength + packing->SkipPixels) * pixelSize;
-
- if (packing->Invert) {
- /* start at top and go down */
- dest += (height - 1) * rowLength * pixelSize;
- rowLength = -rowLength;
- }
-
+ const GLint dstStride = _mesa_image_row_stride(packing, width,
+ format, type);
+ GLubyte *dest = _mesa_image_address2d(packing, pixels, width, height,
+ format, type, 0, 0);
+ GLint row;
ASSERT(rb->GetRow);
for (row = 0; row < height; row++) {
rb->GetRow(ctx, rb, width, x, y + row, dest);
- dest += rowLength * pixelSize;
+ dest += dstStride;
}
return GL_TRUE;
}
- else {
- /* can't do this format/type combination */
- return GL_FALSE;
+
+ if (format == GL_RGB &&
+ rb->DataType == GL_UNSIGNED_BYTE &&
+ type == GL_UNSIGNED_BYTE) {
+ const GLint dstStride = _mesa_image_row_stride(packing, width,
+ format, type);
+ GLubyte *dest = _mesa_image_address2d(packing, pixels, width, height,
+ format, type, 0, 0);
+ GLint row;
+ ASSERT(rb->GetRow);
+ for (row = 0; row < height; row++) {
+ GLubyte tempRow[MAX_WIDTH][4];
+ GLint col;
+ rb->GetRow(ctx, rb, width, x, y + row, tempRow);
+ /* convert RGBA to RGB */
+ for (col = 0; col < width; col++) {
+ dest[col * 3 + 0] = tempRow[col][0];
+ dest[col * 3 + 1] = tempRow[col][1];
+ dest[col * 3 + 2] = tempRow[col][2];
+ }
+ dest += dstStride;
+ }
+ return GL_TRUE;
}
+
+ /* not handled */
+ return GL_FALSE;
}
@@ -267,14 +273,15 @@ read_rgba_pixels( GLcontext *ctx,
GLenum format, GLenum type, GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
ASSERT(rb);
/* Try optimized path first */
- if (read_fast_rgba_pixels( ctx, x, y, width, height,
- format, type, pixels, packing )) {
+ if (fast_read_rgba_pixels(ctx, x, y, width, height,
+ format, type, pixels, packing)) {
return; /* done! */
}
@@ -301,9 +308,8 @@ read_rgba_pixels( GLcontext *ctx,
/* read full RGBA, FLOAT image */
dest = tmpImage;
for (row = 0; row < height; row++, y++) {
- GLchan rgba[MAX_WIDTH][4];
if (fb->Visual.rgbMode) {
- _swrast_read_rgba_span(ctx, rb, width, x, y, rgba);
+ _swrast_read_rgba_span(ctx, rb, width, x, y, GL_FLOAT, dest);
}
else {
GLuint index[MAX_WIDTH];
@@ -312,11 +318,11 @@ read_rgba_pixels( GLcontext *ctx,
if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset !=0 ) {
_mesa_map_ci(ctx, width, index);
}
- _mesa_map_ci_to_rgba_chan(ctx, width, index, rgba);
+ _mesa_map_ci_to_rgba(ctx, width, index, (GLfloat (*)[4]) dest);
}
- _mesa_pack_rgba_span_chan(ctx, width, (const GLchan (*)[4]) rgba,
- GL_RGBA, GL_FLOAT, dest, &ctx->DefaultPacking,
- transferOps & IMAGE_PRE_CONVOLUTION_BITS);
+ _mesa_apply_rgba_transfer_ops(ctx,
+ transferOps & IMAGE_PRE_CONVOLUTION_BITS,
+ width, (GLfloat (*)[4]) dest);
dest += width * 4;
}
@@ -346,24 +352,35 @@ read_rgba_pixels( GLcontext *ctx,
}
else {
/* no convolution */
+ const GLint dstStride
+ = _mesa_image_row_stride(packing, width, format, type);
+ GLfloat (*rgba)[4] = swrast->SpanArrays->color.sz4.rgba;
GLint row;
+ GLubyte *dst = _mesa_image_address2d(packing, pixels, width, height,
+ format, type, 0, 0);
+
for (row = 0; row < height; row++, y++) {
- GLchan rgba[MAX_WIDTH][4];
- GLvoid *dst;
+
+ /* Get float rgba pixels */
if (fb->Visual.rgbMode) {
- _swrast_read_rgba_span(ctx, rb, width, x, y, rgba);
+ _swrast_read_rgba_span(ctx, rb, width, x, y, GL_FLOAT, rgba);
}
else {
+ /* read CI and convert to RGBA */
GLuint index[MAX_WIDTH];
ASSERT(rb->DataType == GL_UNSIGNED_INT);
rb->GetRow(ctx, rb, width, x, y, index);
if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
_mesa_map_ci(ctx, width, index);
}
- _mesa_map_ci_to_rgba_chan(ctx, width, index, rgba);
+ _mesa_map_ci_to_rgba(ctx, width, index, rgba);
}
- dst = _mesa_image_address2d(packing, pixels, width, height,
- format, type, row, 0);
+
+ /* pack the row of RGBA pixels into user's buffer */
+#if 0
+ /* XXX may need to rejuvinate this code if we get conformance
+ * falures on 16bpp displays (i.e. 5/6/5).
+ */
if (fb->Visual.redBits < CHAN_BITS ||
fb->Visual.greenBits < CHAN_BITS ||
fb->Visual.blueBits < CHAN_BITS) {
@@ -379,12 +396,15 @@ read_rgba_pixels( GLcontext *ctx,
format, type, dst, packing,
ctx->_ImageTransferState);
}
- else {
- /* GLubytes are fine */
- _mesa_pack_rgba_span_chan(ctx, width, (CONST GLchan (*)[4]) rgba,
- format, type, dst, packing,
- ctx->_ImageTransferState);
+ else
+#endif
+ {
+ _mesa_pack_rgba_span_float(ctx, width, (CONST GLfloat (*)[4]) rgba,
+ format, type, dst,
+ packing, ctx->_ImageTransferState);
}
+
+ dst += dstStride;
}
}
}