From 6fd29e6c31e14e7b0f3c530798a1fc983eee17af Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 Oct 2015 09:31:41 -0600 Subject: [PATCH] mesa: optimize no-change check in _mesa_BlendFuncSeparate() Streamline the checking for no state change in _mesa_BlendFuncSeparate() (and _mesa_BlendFunc()). If _BlendFuncPerBuffer is false, we only need to check the 0th buffer state. Move argument validation after the no-op check. I'm looking at an app that issues about 1000 redundant glBlendFunc() calls per frame! Reviewed-by: Eric Anholt --- src/mesa/main/blend.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index dee5e29d5b8..98d28581d26 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -203,7 +203,7 @@ _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { GLuint buf, numBuffers; - GLboolean changed; + bool changed = false; GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) @@ -213,28 +213,41 @@ _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, _mesa_enum_to_string(sfactorA), _mesa_enum_to_string(dfactorA)); - if (!validate_blend_factors(ctx, "glBlendFuncSeparate", - sfactorRGB, dfactorRGB, - sfactorA, dfactorA)) { - return; - } - numBuffers = ctx->Extensions.ARB_draw_buffers_blend ? ctx->Const.MaxDrawBuffers : 1; - changed = GL_FALSE; - 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 = GL_TRUE; - break; + /* 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) return; + if (!validate_blend_factors(ctx, "glBlendFuncSeparate", + sfactorRGB, dfactorRGB, + sfactorA, dfactorA)) { + return; + } + FLUSH_VERTICES(ctx, _NEW_COLOR); for (buf = 0; buf < numBuffers; buf++) { -- 2.30.2