mesa/dlist: fixes and improvements for material caching
authorKeith Whitwell <keithw@vmware.com>
Tue, 30 Jun 2009 17:40:20 +0000 (18:40 +0100)
committerKeith Whitwell <keithw@vmware.com>
Tue, 30 Jun 2009 17:40:20 +0000 (18:40 +0100)
Only short-circuit material call if *all* statechanges from this call
are cached.  Some material calls (eg with FRONT_AND_BACK) change more
than one piece of state -- need to check all of them before returning.

Also, Material calls are legal inside begin/end pairs, so don't need
to be as careful about begin/end state as with regular statechanges
(like ShadeModel) when caching.  Take advantage of this and do better
caching.

src/mesa/main/dlist.c

index 2af0dd3c59721383ba5a35c208d36a92a1e1ae6a..c5a1c1f38fcf9805486da64f3f87e7c90dda4cdb 100644 (file)
@@ -5225,20 +5225,28 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
 
    bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
 
-   /* Try to eliminate redundant statechanges
+   /* Try to eliminate redundant statechanges.  Because it is legal to
+    * call glMaterial even inside begin/end calls, don't need to worry
+    * about ctx->Driver.CurrentSavePrimitive here.
     */
    for (i = 0; i < MAT_ATTRIB_MAX; i++) {
       if (bitmask & (1 << i)) {
-         if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END && 
-             ctx->ListState.ActiveMaterialSize[i] == args &&
-             compare4fv(ctx->ListState.CurrentMaterial[i], param, args))
-            return;
-             
-         ctx->ListState.ActiveMaterialSize[i] = args;
-         COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
+         if (ctx->ListState.ActiveMaterialSize[i] == args &&
+             compare4fv(ctx->ListState.CurrentMaterial[i], param, args)) {
+            bitmask &= ~(1 << i);
+         }
+         else {
+            ctx->ListState.ActiveMaterialSize[i] = args;
+            COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
+         }
       }
    }
 
+   /* If this call has effect, return early:
+    */
+   if (bitmask == 0)
+      return;
+
    SAVE_FLUSH_VERTICES(ctx);
 
    n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6);