From 2dc2066b90581ae3878ef7846f961bcb5bd07651 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 14 Mar 2013 13:15:54 +0100 Subject: [PATCH] mesa: add a common function returning transfer ops for ReadPixels I'll need both new functions for later. For now, it consolidates the code for determining what the transfer ops should be and makes it a little bit smarter. v2: added "const" Reviewed-by: Brian Paul Tested-by: Brian Paul --- src/mesa/main/readpix.c | 94 ++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-) diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index 2f130ae9a2e..1b3b31e417b 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -40,6 +40,73 @@ #include "fbobject.h" +/** + * Return true if the conversion L=R+G+B is needed. + */ +static GLboolean +need_rgb_to_luminance_conversion(gl_format texFormat, GLenum format) +{ + GLenum baseTexFormat = _mesa_get_format_base_format(texFormat); + + return (baseTexFormat == GL_RG || + baseTexFormat == GL_RGB || + baseTexFormat == GL_RGBA) && + (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA); +} + + +/** + * Return transfer op flags for this ReadPixels operation. + */ +static GLbitfield +get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat, + GLenum format, GLenum type, GLboolean uses_blit) +{ + GLbitfield transferOps = ctx->_ImageTransferState; + + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL || + format == GL_STENCIL_INDEX) { + return 0; + } + + /* Pixel transfer ops (scale, bias, table lookup) do not apply + * to integer formats. + */ + if (_mesa_is_enum_format_integer(format)) { + return 0; + } + + if (uses_blit) { + /* For blit-based ReadPixels packing, the clamping is done automatically + * unless the type is float. */ + if (ctx->Color._ClampReadColor == GL_TRUE && + (type == GL_FLOAT || type == GL_HALF_FLOAT)) { + transferOps |= IMAGE_CLAMP_BIT; + } + } + else { + /* For CPU-based ReadPixels packing, the clamping must always be done + * for non-float types, */ + if (ctx->Color._ClampReadColor == GL_TRUE || + (type != GL_FLOAT && type != GL_HALF_FLOAT)) { + transferOps |= IMAGE_CLAMP_BIT; + } + } + + /* If the format is unsigned normalized, we can ignore clamping + * because the values are already in the range [0,1] so it won't + * have any effect anyway. + */ + if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED && + !need_rgb_to_luminance_conversion(texFormat, format)) { + transferOps &= ~IMAGE_CLAMP_BIT; + } + + return transferOps; +} + + /** * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the * mapping. @@ -221,8 +288,7 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - GLbitfield transferOps ) + const struct gl_pixelstore_attrib *packing) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; GLubyte *dst, *map; @@ -246,16 +312,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, ctx->Pack.SwapBytes)) return GL_FALSE; - /* If the format is unsigned normalized then we can ignore clamping - * because the values are already in the range [0,1] so it won't - * have any effect anyway. - */ - if (_mesa_get_format_datatype(rb->Format) == GL_UNSIGNED_NORMALIZED) - transferOps &= ~IMAGE_CLAMP_BIT; - - if (transferOps) - 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); @@ -379,22 +435,20 @@ read_rgba_pixels( struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { - GLbitfield transferOps = ctx->_ImageTransferState; + GLbitfield transferOps; struct gl_framebuffer *fb = ctx->ReadBuffer; struct gl_renderbuffer *rb = fb->_ColorReadBuffer; if (!rb) return; - if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) && - !_mesa_is_enum_format_integer(format)) { - transferOps |= IMAGE_CLAMP_BIT; - } + transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, + GL_FALSE); /* Try the optimized paths first. */ - if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height, - format, type, pixels, packing, - transferOps)) { + if (!transferOps && + fast_read_rgba_pixels_memcpy(ctx, x, y, width, height, + format, type, pixels, packing)) { return; } -- 2.30.2