diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index 3fa9678730d..b06ec334062 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -157,20 +157,6 @@ validate_blend_factors(struct gl_context *ctx, const char *func, } -/** - * Specify the blending operation. - * - * \param sfactor source factor operator. - * \param dfactor destination factor operator. - * - * \sa glBlendFunc, glBlendFuncSeparateEXT - */ -void GLAPIENTRY -_mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) -{ - _mesa_BlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); -} - static GLboolean blend_factor_is_dual_src(GLenum factor) { @@ -203,6 +189,95 @@ num_buffers(const struct gl_context *ctx) } +/* Returns true if there was no change */ +static bool +skip_blend_state_update(const struct gl_context *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + /* Check if we're really changing any state. If not, return early. */ + if (ctx->Color._BlendFuncPerBuffer) { + const unsigned numBuffers = num_buffers(ctx); + + /* Check all per-buffer states */ + for (unsigned buf = 0; buf < numBuffers; buf++) { + if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB || + ctx->Color.Blend[buf].DstRGB != dfactorRGB || + ctx->Color.Blend[buf].SrcA != sfactorA || + ctx->Color.Blend[buf].DstA != dfactorA) { + return false; + } + } + } + else { + /* only need to check 0th per-buffer state */ + if (ctx->Color.Blend[0].SrcRGB != sfactorRGB || + ctx->Color.Blend[0].DstRGB != dfactorRGB || + ctx->Color.Blend[0].SrcA != sfactorA || + ctx->Color.Blend[0].DstA != dfactorA) { + return false; + } + } + + return true; +} + + +static void +blend_func_separate(struct gl_context *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR); + ctx->NewDriverState |= ctx->DriverFlags.NewBlend; + + const unsigned numBuffers = num_buffers(ctx); + for (unsigned buf = 0; buf < numBuffers; buf++) { + ctx->Color.Blend[buf].SrcRGB = sfactorRGB; + ctx->Color.Blend[buf].DstRGB = dfactorRGB; + ctx->Color.Blend[buf].SrcA = sfactorA; + ctx->Color.Blend[buf].DstA = dfactorA; + } + + update_uses_dual_src(ctx, 0); + for (unsigned buf = 1; buf < numBuffers; buf++) { + ctx->Color.Blend[buf]._UsesDualSrc = ctx->Color.Blend[0]._UsesDualSrc; + } + + ctx->Color._BlendFuncPerBuffer = GL_FALSE; + + if (ctx->Driver.BlendFuncSeparate) { + ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB, + sfactorA, dfactorA); + } +} + + +/** + * Specify the blending operation. + * + * \param sfactor source factor operator. + * \param dfactor destination factor operator. + * + * \sa glBlendFunc, glBlendFuncSeparateEXT + */ +void GLAPIENTRY +_mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (skip_blend_state_update(ctx, sfactor, dfactor, sfactor, dfactor)) + return; + + if (!validate_blend_factors(ctx, "glBlendFunc", + sfactor, dfactor, sfactor, dfactor)) { + return; + } + + blend_func_separate(ctx, sfactor, dfactor, sfactor, dfactor); +} + + /** * Set the separate blend source/dest factors for all draw buffers. * @@ -216,9 +291,6 @@ _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { GET_CURRENT_CONTEXT(ctx); - const unsigned numBuffers = num_buffers(ctx); - unsigned buf; - bool changed = false; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n", @@ -227,30 +299,9 @@ _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, _mesa_enum_to_string(sfactorA), _mesa_enum_to_string(dfactorA)); - /* Check if we're really changing any state. If not, return early. */ - if (ctx->Color._BlendFuncPerBuffer) { - /* Check all per-buffer states */ - for (buf = 0; buf < numBuffers; buf++) { - if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB || - ctx->Color.Blend[buf].DstRGB != dfactorRGB || - ctx->Color.Blend[buf].SrcA != sfactorA || - ctx->Color.Blend[buf].DstA != dfactorA) { - changed = true; - break; - } - } - } - else { - /* only need to check 0th per-buffer state */ - if (ctx->Color.Blend[0].SrcRGB != sfactorRGB || - ctx->Color.Blend[0].DstRGB != dfactorRGB || - ctx->Color.Blend[0].SrcA != sfactorA || - ctx->Color.Blend[0].DstA != dfactorA) { - changed = true; - } - } - if (!changed) + + if (skip_blend_state_update(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA)) return; if (!validate_blend_factors(ctx, "glBlendFuncSeparate", @@ -259,27 +310,7 @@ _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, return; } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; - - for (buf = 0; buf < numBuffers; buf++) { - ctx->Color.Blend[buf].SrcRGB = sfactorRGB; - ctx->Color.Blend[buf].DstRGB = dfactorRGB; - ctx->Color.Blend[buf].SrcA = sfactorA; - ctx->Color.Blend[buf].DstA = dfactorA; - } - - update_uses_dual_src(ctx, 0); - for (buf = 1; buf < numBuffers; buf++) { - ctx->Color.Blend[buf]._UsesDualSrc = ctx->Color.Blend[0]._UsesDualSrc; - } - - ctx->Color._BlendFuncPerBuffer = GL_FALSE; - - if (ctx->Driver.BlendFuncSeparate) { - ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB, - sfactorA, dfactorA); - } + blend_func_separate(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA); }