diff options
Diffstat (limited to 'src/mesa/swrast/s_blend.c')
-rw-r--r-- | src/mesa/swrast/s_blend.c | 708 |
1 files changed, 566 insertions, 142 deletions
diff --git a/src/mesa/swrast/s_blend.c b/src/mesa/swrast/s_blend.c index 91ec513d5b..4e6c3d909f 100644 --- a/src/mesa/swrast/s_blend.c +++ b/src/mesa/swrast/s_blend.c @@ -51,18 +51,18 @@ #endif -/* +/** * Special case for glBlendFunc(GL_ZERO, GL_ONE) */ static void _BLENDAPI -blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_noop_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType) { GLuint i; - ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendSrcRGB==GL_ZERO); - ASSERT(ctx->Color.BlendDstRGB==GL_ONE); + ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendSrcRGB == GL_ZERO); + ASSERT(ctx->Color.BlendDstRGB == GL_ONE); (void) ctx; for (i = 0; i < n; i++) { @@ -73,17 +73,17 @@ blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[], } -/* +/** * Special case for glBlendFunc(GL_ONE, GL_ZERO) */ static void _BLENDAPI -blend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_replace(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType) { - ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendSrcRGB==GL_ONE); - ASSERT(ctx->Color.BlendDstRGB==GL_ZERO); + ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendSrcRGB == GL_ONE); + ASSERT(ctx->Color.BlendDstRGB == GL_ZERO); (void) ctx; (void) n; (void) mask; @@ -92,18 +92,21 @@ blend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[], } -/* +/** * Common transparency blending mode. */ static void _BLENDAPI -blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_transparency_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], + GLenum chanType) { GLuint i; - ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA); - ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA); + ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA); + ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA); + ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA); (void) ctx; for (i=0;i<n;i++) { @@ -180,18 +183,18 @@ blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[], -/* +/** * Add src and dest. */ static void _BLENDAPI -blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_add_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType) { GLuint i; - ASSERT(ctx->Color.BlendEquationRGB==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendEquationA==GL_FUNC_ADD); - ASSERT(ctx->Color.BlendSrcRGB==GL_ONE); - ASSERT(ctx->Color.BlendDstRGB==GL_ONE); + ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.BlendSrcRGB == GL_ONE); + ASSERT(ctx->Color.BlendDstRGB == GL_ONE); (void) ctx; for (i=0;i<n;i++) { @@ -219,16 +222,16 @@ blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[], -/* +/** * Blend min function (for GL_EXT_blend_minmax) */ static void _BLENDAPI -blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_min_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType) { GLuint i; - ASSERT(ctx->Color.BlendEquationRGB==GL_MIN); - ASSERT(ctx->Color.BlendEquationA==GL_MIN); + ASSERT(ctx->Color.BlendEquationRGB == GL_MIN); + ASSERT(ctx->Color.BlendEquationA == GL_MIN); (void) ctx; for (i=0;i<n;i++) { @@ -248,16 +251,16 @@ blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[], -/* +/** * Blend max function (for GL_EXT_blend_minmax) */ static void _BLENDAPI -blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_max_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType) { GLuint i; - ASSERT(ctx->Color.BlendEquationRGB==GL_MAX); - ASSERT(ctx->Color.BlendEquationA==GL_MAX); + ASSERT(ctx->Color.BlendEquationRGB == GL_MAX); + ASSERT(ctx->Color.BlendEquationA == GL_MAX); (void) ctx; for (i=0;i<n;i++) { @@ -277,12 +280,12 @@ blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[], -/* +/** * Modulate: result = src * dest */ static void _BLENDAPI -blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_modulate_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType) { GLuint i; (void) ctx; @@ -318,17 +321,435 @@ blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[], } - -/* - * General case blend pixels. - * Input: n - number of pixels - * mask - the usual write mask - * In/Out: rgba - the incoming and modified pixels - * Input: dest - the pixels from the dest color buffer +#if 0 +/** + * Do any blending operation, using floating point. + * \param n number of pixels + * \param mask fragment writemask array + * \param src array of incoming (and modified) pixels + * \param dst array of pixels from the dest color buffer */ +static void +blend_general_float(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; + const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; + GLuint i; + + for (i = 0; i < n; i++) { + if (mask[i]) { + /* Incoming/source Color */ + const GLfloat Rs = rgba[i][RCOMP]; + const GLfloat Gs = rgba[i][GCOMP]; + const GLfloat Bs = rgba[i][BCOMP]; + const GLfloat As = rgba[i][ACOMP]; + + /* Frame buffer/dest color */ + const GLfloat Rd = dest[i][RCOMP]; + const GLfloat Gd = dest[i][GCOMP]; + const GLfloat Bd = dest[i][BCOMP]; + const GLfloat Ad = dest[i][ACOMP]; + + GLfloat sR, sG, sB, sA; /* Source factor */ + GLfloat dR, dG, dB, dA; /* Dest factor */ + GLfloat r, g, b, a; /* result color */ + + /* XXX for the case of constant blend terms we could init + * the sX and dX variables just once before the loop. + */ + + /* Source RGB factor */ + switch (ctx->Color.BlendSrcRGB) { + case GL_ZERO: + sR = sG = sB = 0.0F; + break; + case GL_ONE: + sR = sG = sB = 1.0F; + break; + case GL_DST_COLOR: + sR = Rd; + sG = Gd; + sB = Bd; + break; + case GL_ONE_MINUS_DST_COLOR: + sR = 1.0F - Rd; + sG = 1.0F - Gd; + sB = 1.0F - Bd; + break; + case GL_SRC_ALPHA: + sR = sG = sB = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sR = sG = sB = 1.0F - As; + break; + case GL_DST_ALPHA: + sR = sG = sB = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + sR = sG = sB = 1.0F - Ad; + break; + case GL_SRC_ALPHA_SATURATE: + if (As < 1.0F - Ad) { + sR = sG = sB = As; + } + else { + sR = sG = sB = 1.0F - Ad; + } + break; + case GL_CONSTANT_COLOR: + sR = ctx->Color.BlendColor[0]; + sG = ctx->Color.BlendColor[1]; + sB = ctx->Color.BlendColor[2]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + sR = 1.0F - ctx->Color.BlendColor[0]; + sG = 1.0F - ctx->Color.BlendColor[1]; + sB = 1.0F - ctx->Color.BlendColor[2]; + break; + case GL_CONSTANT_ALPHA: + sR = sG = sB = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + sR = sG = sB = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_SRC_COLOR: /* GL_NV_blend_square */ + sR = Rs; + sG = Gs; + sB = Bs; + break; + case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */ + sR = 1.0F - Rs; + sG = 1.0F - Gs; + sB = 1.0F - Bs; + break; + default: + /* this should never happen */ + _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float"); + return; + } + + /* Source Alpha factor */ + switch (ctx->Color.BlendSrcA) { + case GL_ZERO: + sA = 0.0F; + break; + case GL_ONE: + sA = 1.0F; + break; + case GL_DST_COLOR: + sA = Ad; + break; + case GL_ONE_MINUS_DST_COLOR: + sA = 1.0F - Ad; + break; + case GL_SRC_ALPHA: + sA = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sA = 1.0F - As; + break; + case GL_DST_ALPHA: + sA = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + sA = 1.0F - Ad; + break; + case GL_SRC_ALPHA_SATURATE: + sA = 1.0; + break; + case GL_CONSTANT_COLOR: + sA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + sA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_CONSTANT_ALPHA: + sA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + sA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_SRC_COLOR: /* GL_NV_blend_square */ + sA = As; + break; + case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */ + sA = 1.0F - As; + break; + default: + /* this should never happen */ + sA = 0.0F; + _mesa_problem(ctx, "Bad blend source A factor in blend_general_float"); + return; + } + + /* Dest RGB factor */ + switch (ctx->Color.BlendDstRGB) { + case GL_ZERO: + dR = dG = dB = 0.0F; + break; + case GL_ONE: + dR = dG = dB = 1.0F; + break; + case GL_SRC_COLOR: + dR = Rs; + dG = Gs; + dB = Bs; + break; + case GL_ONE_MINUS_SRC_COLOR: + dR = 1.0F - Rs; + dG = 1.0F - Gs; + dB = 1.0F - Bs; + break; + case GL_SRC_ALPHA: + dR = dG = dB = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dR = dG = dB = 1.0F - As; + break; + case GL_DST_ALPHA: + dR = dG = dB = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + dR = dG = dB = 1.0F - Ad; + break; + case GL_CONSTANT_COLOR: + dR = ctx->Color.BlendColor[0]; + dG = ctx->Color.BlendColor[1]; + dB = ctx->Color.BlendColor[2]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + dR = 1.0F - ctx->Color.BlendColor[0]; + dG = 1.0F - ctx->Color.BlendColor[1]; + dB = 1.0F - ctx->Color.BlendColor[2]; + break; + case GL_CONSTANT_ALPHA: + dR = dG = dB = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + dR = dG = dB = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_DST_COLOR: /* GL_NV_blend_square */ + dR = Rd; + dG = Gd; + dB = Bd; + break; + case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */ + dR = 1.0F - Rd; + dG = 1.0F - Gd; + dB = 1.0F - Bd; + break; + default: + /* this should never happen */ + dR = dG = dB = 0.0F; + _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float"); + return; + } + + /* Dest Alpha factor */ + switch (ctx->Color.BlendDstA) { + case GL_ZERO: + dA = 0.0F; + break; + case GL_ONE: + dA = 1.0F; + break; + case GL_SRC_COLOR: + dA = As; + break; + case GL_ONE_MINUS_SRC_COLOR: + dA = 1.0F - As; + break; + case GL_SRC_ALPHA: + dA = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dA = 1.0F - As; + break; + case GL_DST_ALPHA: + dA = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + dA = 1.0F - Ad; + break; + case GL_CONSTANT_COLOR: + dA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + dA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_CONSTANT_ALPHA: + dA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + dA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_DST_COLOR: /* GL_NV_blend_square */ + dA = Ad; + break; + case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */ + dA = 1.0F - Ad; + break; + default: + /* this should never happen */ + dA = 0.0F; + _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float"); + return; + } + + /* compute the blended RGB */ + switch (ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: + r = Rs * sR + Rd * dR; + g = Gs * sG + Gd * dG; + b = Bs * sB + Bd * dB; + a = As * sA + Ad * dA; + break; + case GL_FUNC_SUBTRACT: + r = Rs * sR - Rd * dR; + g = Gs * sG - Gd * dG; + b = Bs * sB - Bd * dB; + a = As * sA - Ad * dA; + break; + case GL_FUNC_REVERSE_SUBTRACT: + r = Rd * dR - Rs * sR; + g = Gd * dG - Gs * sG; + b = Bd * dB - Bs * sB; + a = Ad * dA - As * sA; + break; + case GL_MIN: + r = MIN2( Rd, Rs ); + g = MIN2( Gd, Gs ); + b = MIN2( Bd, Bs ); + break; + case GL_MAX: + r = MAX2( Rd, Rs ); + g = MAX2( Gd, Gs ); + b = MAX2( Bd, Bs ); + break; + default: + /* should never get here */ + r = g = b = 0.0F; /* silence uninitialized var warning */ + _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; + } + + /* compute the blended alpha */ + switch (ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: + a = As * sA + Ad * dA; + break; + case GL_FUNC_SUBTRACT: + a = As * sA - Ad * dA; + break; + case GL_FUNC_REVERSE_SUBTRACT: + a = Ad * dA - As * sA; + break; + case GL_MIN: + a = MIN2( Ad, As ); + break; + case GL_MAX: + a = MAX2( Ad, As ); + break; + default: + /* should never get here */ + a = 0.0F; /* silence uninitialized var warning */ + _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; + } + + /* final clamping */ +#if 0 + rgba[i][RCOMP] = MAX2( r, 0.0F ); + rgba[i][GCOMP] = MAX2( g, 0.0F ); + rgba[i][BCOMP] = MAX2( b, 0.0F ); + rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF ); +#else + ASSIGN_4V(rgba[i], r, g, b, a); +#endif + } + } +} +#endif + + +#if 0 /* not ready yet */ +static void +blend_general2(GLcontext *ctx, GLuint n, const GLubyte mask[], + void *src, const void *dst, GLenum chanType) +{ + GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4]; + + if (chanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + GLuint i; + /* convert ubytes to floats */ + for (i = 0; i < n; i++) { + if (mask[i]) { + rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]); + rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]); + rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]); + rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]); + destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]); + destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]); + destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]); + destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]); + } + } + /* do blend */ + blend_general_float(ctx, n, mask, rgbaF, destF, chanType); + /* convert back to ubytes */ + for (i = 0; i < n; i++) { + if (mask[i]) { + UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]); + } + } + } + else if (chanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + GLuint i; + /* convert ushorts to floats */ + for (i = 0; i < n; i++) { + if (mask[i]) { + rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]); + rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]); + rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]); + rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]); + destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]); + destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]); + destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]); + destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]); + } + } + /* do blend */ + blend_general_float(ctx, n, mask, rgbaF, destF, chanType); + /* convert back to ushorts */ + for (i = 0; i < n; i++) { + if (mask[i]) { + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]); + } + } + } + else { + blend_general_float(ctx, n, mask, (GLfloat (*)[4]) rgbaF, + (const GLfloat (*)[4]) destF, chanType); + } +} +#endif + + static void _BLENDAPI -blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan rgba[][4], CONST GLchan dest[][4] ) +blend_general(GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4], + GLenum chanType) { const GLfloat rscale = 1.0F / CHAN_MAXF; const GLfloat gscale = 1.0F / CHAN_MAXF; @@ -441,7 +862,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], break; default: /* this should never happen */ - _mesa_problem(ctx, "Bad blend source RGB factor in do_blend"); + _mesa_problem(ctx, "Bad blend source RGB factor in blend_general"); return; } @@ -466,7 +887,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], sA = 1.0F - (GLfloat) As * ascale; break; case GL_DST_ALPHA: - sA =(GLfloat) Ad * ascale; + sA = (GLfloat) Ad * ascale; break; case GL_ONE_MINUS_DST_ALPHA: sA = 1.0F - (GLfloat) Ad * ascale; @@ -495,7 +916,8 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], default: /* this should never happen */ sA = 0.0F; - _mesa_problem(ctx, "Bad blend source A factor in do_blend"); + _mesa_problem(ctx, "Bad blend source A factor in blend_general"); + return; } /* Dest RGB factor */ @@ -557,7 +979,8 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], default: /* this should never happen */ dR = dG = dB = 0.0F; - _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend"); + _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general"); + return; } /* Dest Alpha factor */ @@ -607,7 +1030,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], default: /* this should never happen */ dA = 0.0F; - _mesa_problem(ctx, "Bad blend dest A factor in do_blend"); + _mesa_problem(ctx, "Bad blend dest A factor in blend_general"); return; } @@ -633,59 +1056,63 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], /* compute blended color */ #if CHAN_TYPE == GL_FLOAT - if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) { + switch (ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: r = Rs * sR + Rd * dR; g = Gs * sG + Gd * dG; b = Bs * sB + Bd * dB; a = As * sA + Ad * dA; - } - else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) { + break; + case GL_FUNC_SUBTRACT: r = Rs * sR - Rd * dR; g = Gs * sG - Gd * dG; b = Bs * sB - Bd * dB; a = As * sA - Ad * dA; - } - else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) { + break; + case GL_FUNC_REVERSE_SUBTRACT: r = Rd * dR - Rs * sR; g = Gd * dG - Gs * sG; b = Bd * dB - Bs * sB; a = Ad * dA - As * sA; - } - else if (ctx->Color.BlendEquationRGB==GL_MIN) { + break; + case GL_MIN: r = MIN2( Rd, Rs ); g = MIN2( Gd, Gs ); b = MIN2( Bd, Bs ); - } - else if (ctx->Color.BlendEquationRGB==GL_MAX) { + break; + case GL_MAX: r = MAX2( Rd, Rs ); g = MAX2( Gd, Gs ); b = MAX2( Bd, Bs ); - } - else { + break; + default: /* should never get here */ r = g = b = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; } - if (ctx->Color.BlendEquationA==GL_FUNC_ADD) { + switch (ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: a = As * sA + Ad * dA; - } - else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) { + break; + case GL_FUNC_SUBTRACT: a = As * sA - Ad * dA; - } - else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) { + break; + case GL_FUNC_REVERSE_SUBTRACT: a = Ad * dA - As * sA; - } - else if (ctx->Color.BlendEquationA==GL_MIN) { + break; + case GL_MIN: a = MIN2( Ad, As ); - } - else if (ctx->Color.BlendEquationA==GL_MAX) { + break; + case GL_MAX: a = MAX2( Ad, As ); - } - else { + break; + default: /* should never get here */ a = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; } /* final clamping */ @@ -694,56 +1121,60 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], rgba[i][BCOMP] = MAX2( b, 0.0F ); rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF ); #else - if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) { + switch (ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: r = Rs * sR + Rd * dR + 0.5F; g = Gs * sG + Gd * dG + 0.5F; b = Bs * sB + Bd * dB + 0.5F; - } - else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) { + break; + case GL_FUNC_SUBTRACT: r = Rs * sR - Rd * dR + 0.5F; g = Gs * sG - Gd * dG + 0.5F; b = Bs * sB - Bd * dB + 0.5F; - } - else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) { + break; + case GL_FUNC_REVERSE_SUBTRACT: r = Rd * dR - Rs * sR + 0.5F; g = Gd * dG - Gs * sG + 0.5F; b = Bd * dB - Bs * sB + 0.5F; - } - else if (ctx->Color.BlendEquationRGB==GL_MIN) { + break; + case GL_MIN: r = MIN2( Rd, Rs ); g = MIN2( Gd, Gs ); b = MIN2( Bd, Bs ); - } - else if (ctx->Color.BlendEquationRGB==GL_MAX) { + break; + case GL_MAX: r = MAX2( Rd, Rs ); g = MAX2( Gd, Gs ); b = MAX2( Bd, Bs ); - } - else { + break; + default: /* should never get here */ r = g = b = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; } - if (ctx->Color.BlendEquationA==GL_FUNC_ADD) { + switch (ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: a = As * sA + Ad * dA + 0.5F; - } - else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) { + break; + case GL_FUNC_SUBTRACT: a = As * sA - Ad * dA + 0.5F; - } - else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) { + break; + case GL_FUNC_REVERSE_SUBTRACT: a = Ad * dA - As * sA + 0.5F; - } - else if (ctx->Color.BlendEquationA==GL_MIN) { + break; + case GL_MIN: a = MIN2( Ad, As ); - } - else if (ctx->Color.BlendEquationA==GL_MAX) { + break; + case GL_MAX: a = MAX2( Ad, As ); - } - else { + break; + default: /* should never get here */ a = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; } /* final clamping */ @@ -757,12 +1188,13 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], } -/* +/** * Analyze current blending parameters to pick fastest blending function. * Result: the ctx->Color.BlendFunc pointer is updated. */ void _swrast_choose_blend_func( GLcontext *ctx ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLenum eq = ctx->Color.BlendEquationRGB; const GLenum srcRGB = ctx->Color.BlendSrcRGB; const GLenum dstRGB = ctx->Color.BlendDstRGB; @@ -770,77 +1202,77 @@ void _swrast_choose_blend_func( GLcontext *ctx ) const GLenum dstA = ctx->Color.BlendDstA; if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; + swrast->BlendFunc = blend_general; } - else if (eq==GL_MIN) { + else if (eq == GL_MIN) { /* Note: GL_MIN ignores the blending weight factors */ #if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { - SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min; + swrast->BlendFunc = _mesa_mmx_blend_min; } else #endif - SWRAST_CONTEXT(ctx)->BlendFunc = blend_min; + swrast->BlendFunc = blend_min_ubyte; } - else if (eq==GL_MAX) { + else if (eq == GL_MAX) { /* Note: GL_MAX ignores the blending weight factors */ #if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { - SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max; + swrast->BlendFunc = _mesa_mmx_blend_max; } else #endif - SWRAST_CONTEXT(ctx)->BlendFunc = blend_max; + swrast->BlendFunc = blend_max_ubyte; } else if (srcRGB != srcA || dstRGB != dstA) { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; + swrast->BlendFunc = blend_general; } - else if (eq==GL_FUNC_ADD && srcRGB==GL_SRC_ALPHA - && dstRGB==GL_ONE_MINUS_SRC_ALPHA) { + else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA + && dstRGB == GL_ONE_MINUS_SRC_ALPHA) { #if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { - SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency; + swrast->BlendFunc = _mesa_mmx_blend_transparency; } else #endif - SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency; + swrast->BlendFunc = blend_transparency_ubyte; } - else if (eq==GL_FUNC_ADD && srcRGB==GL_ONE && dstRGB==GL_ONE) { + else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) { #if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { - SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add; + swrast->BlendFunc = _mesa_mmx_blend_add; } else #endif - SWRAST_CONTEXT(ctx)->BlendFunc = blend_add; + swrast->BlendFunc = blend_add_ubyte; } - else if (((eq==GL_FUNC_ADD || eq==GL_FUNC_REVERSE_SUBTRACT) - && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR)) + else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT) + && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR)) || - ((eq==GL_FUNC_ADD || eq==GL_FUNC_SUBTRACT) - && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) { + ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT) + && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) { #if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { - SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate; + swrast->BlendFunc = _mesa_mmx_blend_modulate; } else #endif - SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate; + swrast->BlendFunc = blend_modulate_ubyte; } - else if (eq==GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop; + else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { + swrast->BlendFunc = blend_noop_ubyte; } - else if (eq==GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace; + else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { + swrast->BlendFunc = blend_replace; } else { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; + swrast->BlendFunc = blend_general; } } -/* +/** * Apply the blending operator to a span of pixels. * We can handle horizontal runs of pixels (spans) or arrays of x/y * pixel coordinates. @@ -849,25 +1281,17 @@ void _swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb, struct sw_span *span) { - GLchan framebuffer[MAX_WIDTH][4]; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + void *rbPixels; ASSERT(span->end <= MAX_WIDTH); ASSERT(span->arrayMask & SPAN_RGBA); + ASSERT(rb->DataType == span->array->ChanType); ASSERT(!ctx->Color._LogicOpEnabled); - /* Read span of current frame buffer pixels */ - if (span->arrayMask & SPAN_XY) { - /* array of x/y pixel coords */ - _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, - framebuffer, 4 * sizeof(GLchan)); - } - else { - /* horizontal run of pixels */ - _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, - framebuffer); - } + rbPixels = _swrast_get_dest_rgba(ctx, rb, span); - SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask, - span->array->rgba, - (const GLchan (*)[4]) framebuffer ); + swrast->BlendFunc(ctx, span->end, span->array->mask, + span->array->rgba, (const GLchan (*)[4]) rbPixels, + span->array->ChanType); } |