From de251966d26333e2107b57ad89055b179e913add Mon Sep 17 00:00:00 2001
From: Robert Bragg <robert@linux.intel.com>
Date: Fri, 12 Feb 2010 15:08:26 +0000
Subject: [PATCH] glGet: Optimize glGet calls by avoiding redundant state updates

Don't call _mesa_update_state when we know we don't depend on any
derived state. Since 2005 (474f28e57c) all the glGet calls have been
calling _mesa_update_state if they see you have changed anything that
could affect some derived state; even if that derived state has nothing
to do with the query you are making.

If you consider for example that the modelview matrix may be frequently
modified and that whenever you query some unrelated constant (e.g.
GL_MAX_TEXTURE_UNITS) then Mesa will compute a combined
modelview-projection matrix it is easy to see this is not ideal.

This tries to infer from the original 474f28e57c commit message what a
more constrained solution to the problem could be while avoiding the
need to call _mesa_update_state for the majority of queries.

Note: it still seems that calling _mesa_update_state() for
GL_{RED,GREEN,BLUE,INDEX}_BITS is a bit of a hammer solution and it
would possibly be better to only call _mesa_update_framebuffer_visual()
if necessary, but this can be further improved later.

Signed-off-by: Robert Bragg <robert@linux.intel.com>
---
 src/mesa/main/get.c      |   93 +++++++++++++++++++++++++++++++++++----------
 src/mesa/main/get_gen.py |   23 +++++++----
 2 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 22cf75f..dffbe74 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -78,9 +78,6 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    if (ctx->Driver.GetBooleanv &&
        ctx->Driver.GetBooleanv(ctx, pname, params))
       return;
@@ -108,7 +105,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaBias);
          break;
       case GL_ALPHA_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.alphaBits);
+         }
          break;
       case GL_ALPHA_SCALE:
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaScale);
@@ -168,7 +168,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueBias);
          break;
       case GL_BLUE_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.blueBits);
+         }
          break;
       case GL_BLUE_SCALE:
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueScale);
@@ -370,19 +373,28 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenBias);
          break;
       case GL_GREEN_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.greenBits);
+         }
          break;
       case GL_GREEN_SCALE:
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenScale);
          break;
       case GL_INDEX_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.indexBits);
+         }
          break;
       case GL_INDEX_CLEAR_VALUE:
          params[0] = INT_TO_BOOLEAN(ctx->Color.ClearIndex);
          break;
       case GL_INDEX_MODE:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = !ctx->DrawBuffer->Visual.rgbMode;
+         }
          break;
       case GL_INDEX_OFFSET:
          params[0] = INT_TO_BOOLEAN(ctx->Pixel.IndexOffset);
@@ -806,7 +818,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedBias);
          break;
       case GL_RED_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.redBits);
+         }
          break;
       case GL_RED_SCALE:
          params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedScale);
@@ -1922,9 +1937,6 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    if (ctx->Driver.GetFloatv &&
        ctx->Driver.GetFloatv(ctx, pname, params))
       return;
@@ -1952,7 +1964,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          params[0] = ctx->Pixel.AlphaBias;
          break;
       case GL_ALPHA_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.alphaBits);
+         }
          break;
       case GL_ALPHA_SCALE:
          params[0] = ctx->Pixel.AlphaScale;
@@ -2012,7 +2027,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          params[0] = ctx->Pixel.BlueBias;
          break;
       case GL_BLUE_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.blueBits);
+         }
          break;
       case GL_BLUE_SCALE:
          params[0] = ctx->Pixel.BlueScale;
@@ -2214,19 +2232,28 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          params[0] = ctx->Pixel.GreenBias;
          break;
       case GL_GREEN_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.greenBits);
+         }
          break;
       case GL_GREEN_SCALE:
          params[0] = ctx->Pixel.GreenScale;
          break;
       case GL_INDEX_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.indexBits);
+         }
          break;
       case GL_INDEX_CLEAR_VALUE:
          params[0] = (GLfloat)(ctx->Color.ClearIndex);
          break;
       case GL_INDEX_MODE:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = BOOLEAN_TO_FLOAT(!ctx->DrawBuffer->Visual.rgbMode);
+         }
          break;
       case GL_INDEX_OFFSET:
          params[0] = (GLfloat)(ctx->Pixel.IndexOffset);
@@ -2650,7 +2677,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          params[0] = ctx->Pixel.RedBias;
          break;
       case GL_RED_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.redBits);
+         }
          break;
       case GL_RED_SCALE:
          params[0] = ctx->Pixel.RedScale;
@@ -3766,9 +3796,6 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    if (ctx->Driver.GetIntegerv &&
        ctx->Driver.GetIntegerv(ctx, pname, params))
       return;
@@ -3796,7 +3823,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          params[0] = IROUND(ctx->Pixel.AlphaBias);
          break;
       case GL_ALPHA_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = ctx->DrawBuffer->Visual.alphaBits;
+         }
          break;
       case GL_ALPHA_SCALE:
          params[0] = IROUND(ctx->Pixel.AlphaScale);
@@ -3856,7 +3886,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          params[0] = IROUND(ctx->Pixel.BlueBias);
          break;
       case GL_BLUE_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = ctx->DrawBuffer->Visual.blueBits;
+         }
          break;
       case GL_BLUE_SCALE:
          params[0] = IROUND(ctx->Pixel.BlueScale);
@@ -4058,19 +4091,28 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          params[0] = IROUND(ctx->Pixel.GreenBias);
          break;
       case GL_GREEN_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = ctx->DrawBuffer->Visual.greenBits;
+         }
          break;
       case GL_GREEN_SCALE:
          params[0] = IROUND(ctx->Pixel.GreenScale);
          break;
       case GL_INDEX_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = ctx->DrawBuffer->Visual.indexBits;
+         }
          break;
       case GL_INDEX_CLEAR_VALUE:
          params[0] = ctx->Color.ClearIndex;
          break;
       case GL_INDEX_MODE:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = BOOLEAN_TO_INT(!ctx->DrawBuffer->Visual.rgbMode);
+         }
          break;
       case GL_INDEX_OFFSET:
          params[0] = ctx->Pixel.IndexOffset;
@@ -4494,7 +4536,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          params[0] = IROUND(ctx->Pixel.RedBias);
          break;
       case GL_RED_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = ctx->DrawBuffer->Visual.redBits;
+         }
          break;
       case GL_RED_SCALE:
          params[0] = IROUND(ctx->Pixel.RedScale);
@@ -5611,9 +5656,6 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    if (ctx->Driver.GetInteger64v &&
        ctx->Driver.GetInteger64v(ctx, pname, params))
       return;
@@ -5641,7 +5683,10 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
          params[0] = IROUND64(ctx->Pixel.AlphaBias);
          break;
       case GL_ALPHA_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.alphaBits);
+         }
          break;
       case GL_ALPHA_SCALE:
          params[0] = IROUND64(ctx->Pixel.AlphaScale);
@@ -5701,7 +5746,10 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
          params[0] = IROUND64(ctx->Pixel.BlueBias);
          break;
       case GL_BLUE_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.blueBits);
+         }
          break;
       case GL_BLUE_SCALE:
          params[0] = IROUND64(ctx->Pixel.BlueScale);
@@ -5903,19 +5951,28 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
          params[0] = IROUND64(ctx->Pixel.GreenBias);
          break;
       case GL_GREEN_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.greenBits);
+         }
          break;
       case GL_GREEN_SCALE:
          params[0] = IROUND64(ctx->Pixel.GreenScale);
          break;
       case GL_INDEX_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.indexBits);
+         }
          break;
       case GL_INDEX_CLEAR_VALUE:
          params[0] = (GLint64)(ctx->Color.ClearIndex);
          break;
       case GL_INDEX_MODE:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = BOOLEAN_TO_INT64(!ctx->DrawBuffer->Visual.rgbMode);
+         }
          break;
       case GL_INDEX_OFFSET:
          params[0] = (GLint64)(ctx->Pixel.IndexOffset);
@@ -6339,7 +6396,10 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
          params[0] = IROUND64(ctx->Pixel.RedBias);
          break;
       case GL_RED_BITS:
+         {
+         if (ctx->NewState) _mesa_update_state(ctx);
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.redBits);
+         }
          break;
       case GL_RED_SCALE:
          params[0] = IROUND64(ctx->Pixel.RedScale);
@@ -7479,9 +7539,6 @@ _mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    switch (pname) {
       case GL_BLEND:
          CHECK_EXT1(EXT_draw_buffers2, "GetBooleanIndexedv");
@@ -7514,9 +7571,6 @@ _mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    switch (pname) {
       case GL_BLEND:
          CHECK_EXT1(EXT_draw_buffers2, "GetIntegerIndexedv");
@@ -7550,9 +7604,6 @@ _mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params )
    if (!params)
       return;
 
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    switch (pname) {
       case GL_BLEND:
          CHECK_EXT1(EXT_draw_buffers2, "GetInteger64Indexedv");
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index b0beb59..a36fea1 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -73,7 +73,8 @@ StateVars = [
 	  "", None ),
 	( "GL_ALPHA_BIAS", GLfloat, ["ctx->Pixel.AlphaBias"], "", None ),
 	( "GL_ALPHA_BITS", GLint, ["ctx->DrawBuffer->Visual.alphaBits"],
-	  "", None ),
+	  "if (ctx->NewState) _mesa_update_state(ctx);",
+	  None ),
 	( "GL_ALPHA_SCALE", GLfloat, ["ctx->Pixel.AlphaScale"], "", None ),
 	( "GL_ALPHA_TEST", GLboolean, ["ctx->Color.AlphaEnabled"], "", None ),
 	( "GL_ALPHA_TEST_FUNC", GLenum, ["ctx->Color.AlphaFunc"], "", None ),
@@ -98,7 +99,9 @@ StateVars = [
 		"ctx->Color.BlendColor[2]",
 		"ctx->Color.BlendColor[3]"], "", None ),
 	( "GL_BLUE_BIAS", GLfloat, ["ctx->Pixel.BlueBias"], "", None ),
-	( "GL_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.blueBits"], "", None ),
+	( "GL_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.blueBits"],
+	  "if (ctx->NewState) _mesa_update_state(ctx);",
+	  None ),
 	( "GL_BLUE_SCALE", GLfloat, ["ctx->Pixel.BlueScale"], "", None ),
 	( "GL_CLIENT_ATTRIB_STACK_DEPTH", GLint,
 	  ["ctx->ClientAttribStackDepth"], "", None ),
@@ -213,13 +216,16 @@ StateVars = [
 	( "GL_FRONT_FACE", GLenum, ["ctx->Polygon.FrontFace"], "", None ),
 	( "GL_GREEN_BIAS", GLfloat, ["ctx->Pixel.GreenBias"], "", None ),
 	( "GL_GREEN_BITS", GLint, ["ctx->DrawBuffer->Visual.greenBits"],
-	  "", None ),
+	  "if (ctx->NewState) _mesa_update_state(ctx);",
+	  None ),
 	( "GL_GREEN_SCALE", GLfloat, ["ctx->Pixel.GreenScale"], "", None ),
 	( "GL_INDEX_BITS", GLint, ["ctx->DrawBuffer->Visual.indexBits"],
-	  "", None ),
+	  "if (ctx->NewState) _mesa_update_state(ctx);",
+	  None ),
 	( "GL_INDEX_CLEAR_VALUE", GLint, ["ctx->Color.ClearIndex"], "", None ),
 	( "GL_INDEX_MODE", GLboolean, ["!ctx->DrawBuffer->Visual.rgbMode"],
-	  "", None ),
+	  "if (ctx->NewState) _mesa_update_state(ctx);",
+	  None ),
 	( "GL_INDEX_OFFSET", GLint, ["ctx->Pixel.IndexOffset"], "", None ),
 	( "GL_INDEX_SHIFT", GLint, ["ctx->Pixel.IndexShift"], "", None ),
 	( "GL_INDEX_WRITEMASK", GLint, ["ctx->Color.IndexMask"], "", None ),
@@ -392,7 +398,9 @@ StateVars = [
 	  ["ctx->ProjectionMatrixStack.Depth + 1"], "", None ),
 	( "GL_READ_BUFFER", GLenum, ["ctx->ReadBuffer->ColorReadBuffer"], "", None ),
 	( "GL_RED_BIAS", GLfloat, ["ctx->Pixel.RedBias"], "", None ),
-	( "GL_RED_BITS", GLint, ["ctx->DrawBuffer->Visual.redBits"], "", None ),
+	( "GL_RED_BITS", GLint, ["ctx->DrawBuffer->Visual.redBits"],
+	  "if (ctx->NewState) _mesa_update_state(ctx);",
+	  None ),
 	( "GL_RED_SCALE", GLfloat, ["ctx->Pixel.RedScale"], "", None ),
 	( "GL_RENDER_MODE", GLenum, ["ctx->RenderMode"], "", None ),
 	( "GL_RESCALE_NORMAL", GLboolean,
@@ -1124,9 +1132,6 @@ def EmitGetFunction(stateVars, returnType, indexed):
 	print "   if (!params)"
 	print "      return;"
 	print ""
-	print "   if (ctx->NewState)"
-	print "      _mesa_update_state(ctx);"
-	print ""
 	if indexed == 0:
 		print "   if (ctx->Driver.%s &&" % function
 		print "       ctx->Driver.%s(ctx, pname, params))" % function
-- 
1.6.0.4

