Mesa (master): mesa: add a common function returning transfer ops for ReadPixels
Marek Olšák
mareko at kemper.freedesktop.org
Sat Mar 23 13:01:57 UTC 2013
Module: Mesa
Branch: master
Commit: 2dc2066b90581ae3878ef7846f961bcb5bd07651
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2dc2066b90581ae3878ef7846f961bcb5bd07651
Author: Marek Olšák <maraeo at gmail.com>
Date: Thu Mar 14 13:15:54 2013 +0100
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 <brianp at vmware.com>
Tested-by: Brian Paul <brianp at vmware.com>
---
src/mesa/main/readpix.c | 94 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 74 insertions(+), 20 deletions(-)
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 2f130ae..1b3b31e 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -41,6 +41,73 @@
/**
+ * 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;
}
More information about the mesa-commit
mailing list