mesa: optimize no-change check in _mesa_BlendFuncSeparate()
authorBrian Paul <brianp@vmware.com>
Wed, 14 Oct 2015 15:31:41 +0000 (09:31 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 15 Oct 2015 13:21:07 +0000 (07:21 -0600)
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 <eric@anholt.net>
src/mesa/main/blend.c

index dee5e29d5b83e4b4bc9f074d50a495abca442be1..98d28581d26ed9925378fa046c0b6af368068986 100644 (file)
@@ -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++) {