diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-10-12 23:14:19 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-10-12 23:14:19 +0000 | 
| commit | 4bb9f4115c4b1930a140da78feff953e80f8a4f5 (patch) | |
| tree | b0ac4132a5f4052ba06b36f9df7435d763636e0e | |
| parent | 57d719afb1663da1c0b8272d01036be6816e4402 (diff) | |
don't use temp storage in _mesa_convert_colors() when possible
| -rw-r--r-- | src/mesa/main/image.c | 107 | 
1 files changed, 60 insertions, 47 deletions
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index f79f402388..59d50dd57d 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -1064,7 +1064,7 @@ _mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,   * Used to pack an array [][4] of RGBA float colors as specified   * by the dstFormat, dstType and dstPacking.  Used by glReadPixels,   * glGetConvolutionFilter(), etc. - * NOTE: it's assumed the incoming float colors are all in [0,1]. + * Incoming colors will be clamped to [0,1] if needed.   */  void  _mesa_pack_rgba_span_float( GLcontext *ctx, @@ -1075,13 +1075,17 @@ _mesa_pack_rgba_span_float( GLcontext *ctx,                              GLuint transferOps )  {     const GLint comps = _mesa_components_in_format(dstFormat); -   GLfloat luminance[MAX_WIDTH]; +   GLfloat rgbaCopy[MAX_WIDTH][4], luminance[MAX_WIDTH];     const GLfloat (*rgba)[4];     GLuint i; +   if (dstType != GL_FLOAT) { +      /* need to clamp to [0, 1] */ +      transferOps |= IMAGE_CLAMP_BIT; +   } +     if (transferOps) {        /* make copy of incoming data */ -      GLfloat rgbaCopy[MAX_WIDTH][4];        _mesa_memcpy(rgbaCopy, rgbaIn, n * 4 * sizeof(GLfloat));        _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgbaCopy);        rgba = (const GLfloat (*)[4]) rgbaCopy; @@ -1097,7 +1101,7 @@ _mesa_pack_rgba_span_float( GLcontext *ctx,     if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {        /* compute luminance values */ -      if (ctx->Color.ClampReadColor == GL_TRUE) { +      if (ctx->Color.ClampReadColor == GL_TRUE || dstType != GL_FLOAT) {           for (i = 0; i < n; i++) {              GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];              luminance[i] = CLAMP(sum, 0.0F, 1.0F); @@ -4246,107 +4250,116 @@ _mesa_unpack_image( GLuint dimensions,  /**   * Convert an array of RGBA colors from one datatype to another. - * NOTE: we assume that src may equal dst. + * NOTE: src may equal dst.  In that case, we use a temporary buffer.   */  void  _mesa_convert_colors(GLenum srcType, const GLvoid *src,                       GLenum dstType, GLvoid *dst,                       GLuint count, const GLubyte mask[])  { +   GLuint tempBuffer[MAX_WIDTH][4]; +   const GLboolean useTemp = (src == dst); +     ASSERT(srcType != dstType);     switch (srcType) {     case GL_UNSIGNED_BYTE:        if (dstType == GL_UNSIGNED_SHORT) { -         const GLubyte (*rgba1)[4] = (const GLubyte (*)[4]) src; -         GLushort newVals[MAX_WIDTH][4]; +         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; +         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);           GLuint i;           for (i = 0; i < count; i++) {              if (!mask || mask[i]) { -               newVals[i][RCOMP] = UBYTE_TO_USHORT(rgba1[i][RCOMP]); -               newVals[i][GCOMP] = UBYTE_TO_USHORT(rgba1[i][GCOMP]); -               newVals[i][BCOMP] = UBYTE_TO_USHORT(rgba1[i][BCOMP]); -               newVals[i][ACOMP] = UBYTE_TO_USHORT(rgba1[i][ACOMP]); +               dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]); +               dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]); +               dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]); +               dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]);              }           } -         _mesa_memcpy(dst, newVals, count * 4 * sizeof(GLushort)); +         if (useTemp) +            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));        }        else { -         const GLubyte (*rgba1)[4] = (const GLubyte (*)[4]) src; -         GLfloat newVals[MAX_WIDTH][4]; +         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; +         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);           GLuint i;           ASSERT(dstType == GL_FLOAT);           for (i = 0; i < count; i++) {              if (!mask || mask[i]) { -               newVals[i][RCOMP] = UBYTE_TO_FLOAT(rgba1[i][RCOMP]); -               newVals[i][GCOMP] = UBYTE_TO_FLOAT(rgba1[i][GCOMP]); -               newVals[i][BCOMP] = UBYTE_TO_FLOAT(rgba1[i][BCOMP]); -               newVals[i][ACOMP] = UBYTE_TO_FLOAT(rgba1[i][ACOMP]); +               dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]); +               dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]); +               dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]); +               dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]);              }           } -         _mesa_memcpy(dst, newVals, count * 4 * sizeof(GLfloat)); +         if (useTemp) +            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));        }        break;     case GL_UNSIGNED_SHORT:        if (dstType == GL_UNSIGNED_BYTE) { -         const GLushort (*rgba2)[4] = (const GLushort (*)[4]) src; -         GLubyte newVals[MAX_WIDTH][4]; +         const GLushort (*src2)[4] = (const GLushort (*)[4]) src; +         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);           GLuint i;           for (i = 0; i < count; i++) {              if (!mask || mask[i]) { -               newVals[i][RCOMP] = USHORT_TO_UBYTE(rgba2[i][RCOMP]); -               newVals[i][GCOMP] = USHORT_TO_UBYTE(rgba2[i][GCOMP]); -               newVals[i][BCOMP] = USHORT_TO_UBYTE(rgba2[i][BCOMP]); -               newVals[i][ACOMP] = USHORT_TO_UBYTE(rgba2[i][ACOMP]); +               dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]); +               dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]); +               dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]); +               dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]);              }           } -         _mesa_memcpy(dst, newVals, count * 4 * sizeof(GLubyte)); +         if (useTemp) +            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));        }        else { -         const GLushort (*rgba2)[4] = (const GLushort (*)[4]) src; -         GLfloat newVals[MAX_WIDTH][4]; +         const GLushort (*src2)[4] = (const GLushort (*)[4]) src; +         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);           GLuint i;           ASSERT(dstType == GL_FLOAT);           for (i = 0; i < count; i++) {              if (!mask || mask[i]) { -               newVals[i][RCOMP] = USHORT_TO_FLOAT(rgba2[i][RCOMP]); -               newVals[i][GCOMP] = USHORT_TO_FLOAT(rgba2[i][GCOMP]); -               newVals[i][BCOMP] = USHORT_TO_FLOAT(rgba2[i][BCOMP]); -               newVals[i][ACOMP] = USHORT_TO_FLOAT(rgba2[i][ACOMP]); +               dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]); +               dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]); +               dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]); +               dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]);              }           } -         _mesa_memcpy(dst, newVals, count * 4 * sizeof(GLfloat)); +         if (useTemp) +            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));        }        break;     case GL_FLOAT:        if (dstType == GL_UNSIGNED_BYTE) { -         const GLfloat (*rgba4)[4] = (const GLfloat (*)[4]) src; -         GLubyte newVals[MAX_WIDTH][4]; +         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; +         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);           GLuint i;           for (i = 0; i < count; i++) {              if (!mask || mask[i]) { -               UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][RCOMP], rgba4[i][RCOMP]); -               UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][GCOMP], rgba4[i][GCOMP]); -               UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][BCOMP], rgba4[i][BCOMP]); -               UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][ACOMP], rgba4[i][ACOMP]); +               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][RCOMP], src4[i][RCOMP]); +               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][GCOMP], src4[i][GCOMP]); +               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][BCOMP], src4[i][BCOMP]); +               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][ACOMP], src4[i][ACOMP]);              }           } -         _mesa_memcpy(dst, newVals, count * 4 * sizeof(GLubyte)); +         if (useTemp) +            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));        }        else { -         const GLfloat (*rgba4)[4] = (const GLfloat (*)[4]) src; -         GLushort newVals[MAX_WIDTH][4]; +         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; +         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);           GLuint i;           ASSERT(dstType == GL_UNSIGNED_SHORT);           for (i = 0; i < count; i++) {              if (!mask || mask[i]) { -               UNCLAMPED_FLOAT_TO_USHORT(newVals[i][RCOMP], rgba4[i][RCOMP]); -               UNCLAMPED_FLOAT_TO_USHORT(newVals[i][GCOMP], rgba4[i][GCOMP]); -               UNCLAMPED_FLOAT_TO_USHORT(newVals[i][BCOMP], rgba4[i][BCOMP]); -               UNCLAMPED_FLOAT_TO_USHORT(newVals[i][ACOMP], rgba4[i][ACOMP]); +               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]); +               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]); +               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]); +               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]);              }           } -         _mesa_memcpy(dst, newVals, count * 4 * sizeof(GLushort)); +         if (useTemp) +            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));        }        break;     default:  | 
