diff options
| author | Brian Paul <brianp@vmware.com> | 2010-12-02 14:18:31 -0700 | 
|---|---|---|
| committer | Brian Paul <brianp@vmware.com> | 2010-12-02 14:29:07 -0700 | 
| commit | aa28efe60dee4570730538ef091d1c79f42fa1cd (patch) | |
| tree | e57f5b90f74447c7019577048cd76b253dc03543 /src/mesa | |
| parent | 25662f878ea5f3a8c55506d0becafe2c0a6370f2 (diff) | |
swrast: avoid large stack allocations in tex combine code
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/swrast/s_texcombine.c | 45 | 
1 files changed, 39 insertions, 6 deletions
| diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 1836d074ae..99c44413fb 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -86,10 +86,28 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,     const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA);     const GLuint numArgsRGB = combine->_NumArgsRGB;     const GLuint numArgsA = combine->_NumArgsA; -   GLfloat ccolor[MAX_COMBINER_TERMS][MAX_WIDTH][4]; /* temp color buffers */ -   GLfloat rgba[MAX_WIDTH][4]; +   float4_array ccolor[4], rgba;     GLuint i, term; +   /* alloc temp pixel buffers */ +   rgba = (float4_array) malloc(4 * n * sizeof(GLfloat)); +   if (!rgba) { +      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); +      return; +   } + +   for (i = 0; i < numArgsRGB || i < numArgsA; i++) { +      ccolor[i] = (float4_array) malloc(4 * n * sizeof(GLfloat)); +      if (!ccolor[i]) { +         while (i) { +            free(ccolor[i]); +            i--; +         } +         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); +         return; +      } +   } +     for (i = 0; i < n; i++) {        rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);        rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]); @@ -163,7 +181,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,                 const GLuint srcUnit = srcRGB - GL_TEXTURE0;                 ASSERT(srcUnit < ctx->Const.MaxTextureUnits);                 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) -                  return; +                  goto end;                 argRGB[term] = get_texel_array(swrast, srcUnit);              }        } @@ -253,7 +271,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,                 const GLuint srcUnit = srcA - GL_TEXTURE0;                 ASSERT(srcUnit < ctx->Const.MaxTextureUnits);                 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) -                  return; +                  goto end;                 argA[term] = get_texel_array(swrast, srcUnit);              }        } @@ -411,7 +429,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,              rgba[i][BCOMP] = 0.0;              rgba[i][ACOMP] = 1.0;  	 } -         return; /* no alpha processing */ +         goto end; /* no alpha processing */        default:           _mesa_problem(ctx, "invalid combine mode");        } @@ -519,6 +537,12 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,        UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);        UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);     } + +end: +   for (i = 0; i < numArgsRGB || i < numArgsA; i++) { +      free(ccolor[i]); +   } +   free(rgba);  } @@ -559,9 +583,16 @@ void  _swrast_texture_span( struct gl_context *ctx, SWspan *span )  {     SWcontext *swrast = SWRAST_CONTEXT(ctx); -   GLfloat primary_rgba[MAX_WIDTH][4]; +   float4_array primary_rgba;     GLuint unit; +   primary_rgba = (float4_array) malloc(span->end * 4 * sizeof(GLfloat)); + +   if (!primary_rgba) { +      _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span"); +      return; +   } +     ASSERT(span->end <= MAX_WIDTH);     /* @@ -706,4 +737,6 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )                            span->array->rgba );        }     } + +   free(primary_rgba);  } | 
