X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_readpix.c;h=b5ab06e4ba6e5ec3919c85b17f30ca8b791349a0;hb=8ef874f1a543c693cfef9c935bed05903800fbfe;hp=4ca5af4c8f29f790fba8f1888fc3a636ab97a815;hpb=08836341788a9f9d638d9dc8328510ccd18ddeb5;p=mesa.git diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 4ca5af4c8f2..b5ab06e4ba6 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -1,21 +1,19 @@ -/* $Id: s_readpix.c,v 1.8 2001/03/03 20:33:30 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * + * Version: 6.1 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -32,7 +30,7 @@ #include "feedback.h" #include "image.h" #include "macros.h" -#include "mem.h" +#include "imports.h" #include "pixel.h" #include "s_alphabuf.h" @@ -53,6 +51,7 @@ read_index_pixels( GLcontext *ctx, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLint i, readWidth; /* error checking */ @@ -61,9 +60,18 @@ read_index_pixels( GLcontext *ctx, return; } - ASSERT(ctx->Driver.SetReadBuffer); - (*ctx->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer); + if (type != GL_BYTE && + type != GL_UNSIGNED_BYTE && + type != GL_SHORT && + type != GL_UNSIGNED_SHORT && + type != GL_INT && + type != GL_UNSIGNED_INT && + type != GL_FLOAT) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels(index type)"); + return; + } + + _swrast_use_read_buffer(ctx); readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; @@ -72,7 +80,7 @@ read_index_pixels( GLcontext *ctx, GLuint index[MAX_WIDTH]; GLvoid *dest; - (*ctx->Driver.ReadCI32Span)(ctx, readWidth, x, y + i, index); + (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y + i, index); dest = _mesa_image_address(packing, pixels, width, height, GL_COLOR_INDEX, type, 0, i, 0); @@ -81,8 +89,7 @@ read_index_pixels( GLcontext *ctx, &ctx->Pack, ctx->_ImageTransferState); } - (*ctx->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer); + _swrast_use_draw_buffer(ctx); } @@ -128,7 +135,7 @@ read_depth_pixels( GLcontext *ctx, GLushort *dst = (GLushort*) _mesa_image_address( packing, pixels, width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 ); GLint i; - _mesa_read_depth_span(ctx, width, x, y, depth); + _swrast_read_depth_span(ctx, width, x, y, depth); for (i = 0; i < width; i++) dst[i] = depth[i]; } @@ -140,7 +147,7 @@ read_depth_pixels( GLcontext *ctx, for (j=0;jPack); + _mesa_pack_depth_span(ctx, readWidth, (GLdepth *) dest, type, + depth, &ctx->Pack); } } } @@ -196,7 +204,7 @@ read_stencil_pixels( GLcontext *ctx, GLvoid *dest; GLstencil stencil[MAX_WIDTH]; - _mesa_read_stencil_span(ctx, readWidth, x, y, stencil); + _swrast_read_stencil_span(ctx, readWidth, x, y, stencil); dest = _mesa_image_address(packing, pixels, width, height, GL_STENCIL_INDEX, type, 0, j, 0); @@ -220,6 +228,7 @@ read_fast_rgba_pixels( GLcontext *ctx, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); /* can't do scale, bias, mapping, etc */ if (ctx->_ImageTransferState) return GL_FALSE; @@ -243,24 +252,24 @@ read_fast_rgba_pixels( GLcontext *ctx, rowLength = width; /* horizontal clipping */ - if (srcX < ctx->ReadBuffer->_Xmin) { - skipPixels += (ctx->ReadBuffer->_Xmin - srcX); - readWidth -= (ctx->ReadBuffer->_Xmin - srcX); - srcX = ctx->ReadBuffer->_Xmin; + if (srcX < 0) { + skipPixels -= srcX; + readWidth += srcX; + srcX = 0; } - if (srcX + readWidth > ctx->ReadBuffer->_Xmax) - readWidth -= (srcX + readWidth - ctx->ReadBuffer->_Xmax); + if (srcX + readWidth > (GLint) ctx->ReadBuffer->Width) + readWidth -= (srcX + readWidth - (GLint) ctx->ReadBuffer->Width); if (readWidth <= 0) return GL_TRUE; /* vertical clipping */ - if (srcY < ctx->ReadBuffer->_Ymin) { - skipRows += (ctx->ReadBuffer->_Ymin - srcY); - readHeight -= (ctx->ReadBuffer->_Ymin - srcY); - srcY = ctx->ReadBuffer->_Ymin; + if (srcY < 0) { + skipRows -= srcY; + readHeight += srcY; + srcY = 0; } - if (srcY + readHeight > ctx->ReadBuffer->_Ymax) - readHeight -= (srcY + readHeight - ctx->ReadBuffer->_Ymax); + if (srcY + readHeight > (GLint) ctx->ReadBuffer->Height) + readHeight -= (srcY + readHeight - (GLint) ctx->ReadBuffer->Height); if (readHeight <= 0) return GL_TRUE; @@ -279,13 +288,20 @@ read_fast_rgba_pixels( GLcontext *ctx, if (0) { #endif GLchan *dest = (GLchan *) pixels - + (skipRows * rowLength + skipPixels) * 4; + + (skipRows * rowLength + skipPixels) * 4; GLint row; + + if (packing->Invert) { + /* start at top and go down */ + dest += (readHeight - 1) * rowLength * 4; + rowLength = -rowLength; + } + for (row=0; rowDriver.ReadRGBASpan)(ctx, readWidth, srcX, srcY, + (*swrast->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY, (GLchan (*)[4]) dest); if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) { - _mesa_read_alpha_span(ctx, readWidth, srcX, srcY, + _swrast_read_alpha_span(ctx, readWidth, srcX, srcY, (GLchan (*)[4]) dest); } dest += rowLength * 4; @@ -312,15 +328,16 @@ read_rgba_pixels( GLcontext *ctx, GLenum format, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLint readWidth; - (*ctx->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer); + _swrast_use_read_buffer(ctx); /* Try optimized path first */ if (read_fast_rgba_pixels( ctx, x, y, width, height, format, type, pixels, packing )) { - (*ctx->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer); + _swrast_use_draw_buffer(ctx); return; /* done! */ } @@ -365,14 +382,14 @@ read_rgba_pixels( GLcontext *ctx, GLfloat *dest, *src, *tmpImage, *convImage; GLint row; - tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; } - convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); if (!convImage) { - FREE(tmpImage); + _mesa_free(tmpImage); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; } @@ -382,18 +399,18 @@ read_rgba_pixels( GLcontext *ctx, for (row = 0; row < height; row++, y++) { GLchan rgba[MAX_WIDTH][4]; if (ctx->Visual.rgbMode) { - _mesa_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); + _swrast_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); } else { GLuint index[MAX_WIDTH]; - (*ctx->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); + (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset !=0 ) { _mesa_map_ci(ctx, readWidth, index); } _mesa_map_ci_to_rgba_chan(ctx, readWidth, index, rgba); } - _mesa_pack_rgba_span(ctx, readWidth, (const GLchan (*)[4]) rgba, - GL_RGBA, GL_FLOAT, dest, &_mesa_native_packing, + _mesa_pack_rgba_span_chan(ctx, readWidth, (const GLchan (*)[4]) rgba, + GL_RGBA, GL_FLOAT, dest, &ctx->DefaultPacking, transferOps & IMAGE_PRE_CONVOLUTION_BITS); dest += width * 4; } @@ -406,7 +423,7 @@ read_rgba_pixels( GLcontext *ctx, ASSERT(ctx->Pixel.Separable2DEnabled); _mesa_convolve_sep_image(ctx, &readWidth, &height, tmpImage, convImage); } - FREE(tmpImage); + _mesa_free(tmpImage); /* finish transfer ops and pack the resulting image */ src = convImage; @@ -414,7 +431,7 @@ read_rgba_pixels( GLcontext *ctx, GLvoid *dest; dest = _mesa_image_address(packing, pixels, readWidth, height, format, type, 0, row, 0); - _mesa_pack_float_rgba_span(ctx, readWidth, + _mesa_pack_rgba_span_float(ctx, readWidth, (const GLfloat (*)[4]) src, format, type, dest, packing, transferOps & IMAGE_POST_CONVOLUTION_BITS); @@ -428,11 +445,11 @@ read_rgba_pixels( GLcontext *ctx, GLchan rgba[MAX_WIDTH][4]; GLvoid *dst; if (ctx->Visual.rgbMode) { - _mesa_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); + _swrast_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); } else { GLuint index[MAX_WIDTH]; - (*ctx->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); + (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) { _mesa_map_ci(ctx, readWidth, index); } @@ -447,24 +464,26 @@ read_rgba_pixels( GLcontext *ctx, * there. This fixes conformance failures with 16-bit color * buffers, for example. */ - GLfloat rgbaf[MAX_WIDTH][4]; + DEFMARRAY(GLfloat, rgbaf, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgbaf, return); /* mac 32k limitation */ _mesa_chan_to_float_span(ctx, readWidth, (CONST GLchan (*)[4]) rgba, rgbaf); - _mesa_pack_float_rgba_span(ctx, readWidth, + _mesa_pack_rgba_span_float(ctx, readWidth, (CONST GLfloat (*)[4]) rgbaf, format, type, dst, packing, ctx->_ImageTransferState); + UNDEFARRAY(rgbaf); /* mac 32k limitation */ } else { /* GLubytes are fine */ - _mesa_pack_rgba_span(ctx, readWidth, (CONST GLchan (*)[4]) rgba, + _mesa_pack_rgba_span_chan(ctx, readWidth, (CONST GLchan (*)[4]) rgba, format, type, dst, packing, ctx->_ImageTransferState); } } } - (*ctx->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer); + _swrast_use_draw_buffer(ctx); } @@ -472,15 +491,26 @@ read_rgba_pixels( GLcontext *ctx, void _swrast_ReadPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, + GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid *pixels ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); (void) pack; - if (SWRAST_CONTEXT(ctx)->NewState) + if (swrast->NewState) _swrast_validate_derived( ctx ); + pixels = _swrast_validate_pbo_access(pack, width, height, 1, + format, type, (GLvoid *) pixels); + + if (!pixels) { + _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); + return; + } + + RENDER_START(swrast,ctx); + switch (format) { case GL_COLOR_INDEX: read_index_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack); @@ -508,4 +538,6 @@ _swrast_ReadPixels( GLcontext *ctx, default: _mesa_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" ); } + + RENDER_FINISH(swrast,ctx); }