Remove unused texture coordinate flags.

Currently we support 5 texture stages, each with 5 possible texture coordinate attributes.
However, we only ever use one explicit texture coordinate. This change removes all but one 
(now named just "aTexCoord") of the possible explicit texture coordinates.

Review URL: https://codereview.appspot.com/7308094/


git-svn-id: http://skia.googlecode.com/svn/trunk@7737 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index f2c6977..3ff8a97 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -49,100 +49,25 @@
 namespace {
 
 /**
- * This function generates some masks that we like to have known at compile
- * time. When the number of stages or tex coords is bumped or the way bits
- * are defined in GrDrawState.h changes this function should be rerun to
- * generate the new masks. (We attempted to force the compiler to generate the
- * masks using recursive templates but always wound up with static initializers
- * under gcc, even if they were just a series of immediate->memory moves.)
+ * This function generates a mask that we like to have known at compile
+ * time. When the number of stages is bumped or the way bits are defined in 
+ * GrDrawState.h changes this function should be rerun to generate the new mask. 
+ * (We attempted to force the compiler to generate the mask using recursive 
+ * templates but always wound up with static initializers under gcc, even if 
+ * they were just a series of immediate->memory moves.)
  *
  */
-void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
-                     GrVertexLayout* texCoordMasks) {
+void gen_tex_coord_mask(GrVertexLayout* texCoordMask) {
+    *texCoordMask = 0;
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        stageTexCoordMasks[s] = 0;
-        for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-            stageTexCoordMasks[s] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t);
-        }
-    }
-    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        texCoordMasks[t] = 0;
-        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-            texCoordMasks[t] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t);
-        }
+        *texCoordMask |= GrDrawState::StageTexCoordVertexLayoutBit(s);
     }
 }
 
-/**
- * Uncomment and run the gen_globals function to generate
- * the code that declares the global masks.
- *
- * #if 0'ed out to avoid unused function warning.
- */
+const GrVertexLayout kTexCoordMask = (1 << GrDrawState::kNumStages)-1;
 
-#if 0
-void gen_globals() {
-    GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
-    GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
-    gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
-
-    GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n");
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        GrPrintf("    0x%x,\n", stageTexCoordMasks[s]);
-    }
-    GrPrintf("};\n");
-    GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n");
-    GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n");
-    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        GrPrintf("    0x%x,\n", texCoordMasks[t]);
-    }
-    GrPrintf("};\n");
-    GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n");
-}
-#endif
-
-/* These values were generated by the above function */
-
-const GrVertexLayout gStageTexCoordMasks[] = {
-    0x108421,
-    0x210842,
-    0x421084,
-    0x842108,
-    0x1084210,
-};
-GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));
-
-const GrVertexLayout gTexCoordMasks[] = {
-    0x1f,
-    0x3e0,
-    0x7c00,
-    0xf8000,
-    0x1f00000,
-};
-GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));
-
-#ifdef SK_DEBUG
-bool check_layout(GrVertexLayout layout) {
-    // can only have 1 or 0 bits set for each stage.
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        int stageBits = layout & gStageTexCoordMasks[s];
-        if (stageBits && !GrIsPow2(stageBits)) {
-            return false;
-        }
-    }
-    return true;
-}
-#endif
-
-int num_tex_coords(GrVertexLayout layout) {
-    int cnt = 0;
-    // figure out how many tex coordinates are present
-    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        if (gTexCoordMasks[t] & layout) {
-            ++cnt;
-        }
-    }
-    return cnt;
+inline int num_tex_coords(GrVertexLayout layout) {
+    return (kTexCoordMask & layout) ? 1 : 0;
 }
 
 } //unnamed namespace
@@ -150,8 +75,6 @@
 static const size_t kVec2Size = sizeof(GrPoint);
 
 size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
     size_t size = kVec2Size; // position
     size += num_tex_coords(vertexLayout) * kVec2Size;
     if (vertexLayout & kColor_VertexLayoutBit) {
@@ -174,38 +97,20 @@
  *
  * Order of vertex components:
  * Position
- * Tex Coord 0
- * ...
- * Tex Coord GrDrawState::kMaxTexCoords-1
+ * Tex Coord 
  * Color
  * Coverage
  */
 
 int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
     if (!StageUsesTexCoords(vertexLayout, stageIdx)) {
         return 0;
     }
-    int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout);
-    if (tcIdx >= 0) {
 
-        int offset = kVec2Size; // position
-        // figure out how many tex coordinates are present and precede this one.
-        for (int t = 0; t < tcIdx; ++t) {
-            if (gTexCoordMasks[t] & vertexLayout) {
-                offset += kVec2Size;
-            }
-        }
-        return offset;
-    }
-
-    return -1;
+    return kVec2Size;
 }
 
 int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
     if (vertexLayout & kColor_VertexLayoutBit) {
         return kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
     }
@@ -213,8 +118,6 @@
 }
 
 int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
     if (vertexLayout & kCoverage_VertexLayoutBit) {
         int offset =  kVec2Size * (num_tex_coords(vertexLayout) + 1);
         if (vertexLayout & kColor_VertexLayoutBit) {
@@ -226,8 +129,6 @@
 }
 
 int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
     // edge pts are after the pos, tex coords, and color
     if (vertexLayout & kEdge_VertexLayoutBit) {
         int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
@@ -242,26 +143,22 @@
     return -1;
 }
 
-int GrDrawState::VertexSizeAndOffsetsByIdx(
+int GrDrawState::VertexSizeAndOffsets(
         GrVertexLayout vertexLayout,
-        int texCoordOffsetsByIdx[kMaxTexCoords],
+        int* texCoordOffset,
         int* colorOffset,
         int* coverageOffset,
         int* edgeOffset) {
-    GrAssert(check_layout(vertexLayout));
-
     int size = kVec2Size; // position
 
-    for (int t = 0; t < kMaxTexCoords; ++t) {
-        if (gTexCoordMasks[t] & vertexLayout) {
-            if (NULL != texCoordOffsetsByIdx) {
-                texCoordOffsetsByIdx[t] = size;
-            }
-            size += kVec2Size;
-        } else {
-            if (NULL != texCoordOffsetsByIdx) {
-                texCoordOffsetsByIdx[t] = -1;
-            }
+    if (kTexCoordMask & vertexLayout) {
+        if (NULL != texCoordOffset) {
+            *texCoordOffset = size;
+        }
+        size += kVec2Size;
+    } else {
+        if (NULL != texCoordOffset) {
+            *texCoordOffset = -1;
         }
     }
     if (kColor_VertexLayoutBit & vertexLayout) {
@@ -303,21 +200,17 @@
         int* colorOffset,
         int* coverageOffset,
         int* edgeOffset) {
-    GrAssert(check_layout(vertexLayout));
 
-    int texCoordOffsetsByIdx[kMaxTexCoords];
-    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
-                                         (NULL == texCoordOffsetsByStage) ?
-                                               NULL :
-                                               texCoordOffsetsByIdx,
-                                         colorOffset,
-                                         coverageOffset,
-                                         edgeOffset);
+    int texCoordOffset;
+    int size = VertexSizeAndOffsets(vertexLayout,
+                                    &texCoordOffset,
+                                    colorOffset,
+                                    coverageOffset,
+                                    edgeOffset);
     if (NULL != texCoordOffsetsByStage) {
         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-            int tcIdx = VertexTexCoordsForStage(s, vertexLayout);
-            texCoordOffsetsByStage[s] =
-                tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx];
+            texCoordOffsetsByStage[s] = StageUsesTexCoords(vertexLayout, s) ?
+                                                           texCoordOffset : 0;
         }
     }
     return size;
@@ -325,131 +218,93 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrDrawState::VertexUsesTexCoordIdx(int coordIndex,
-                                         GrVertexLayout vertexLayout) {
-    GrAssert(coordIndex < kMaxTexCoords);
-    GrAssert(check_layout(vertexLayout));
-    return !!(gTexCoordMasks[coordIndex] & vertexLayout);
-}
-
-int GrDrawState::VertexTexCoordsForStage(int stageIdx,
-                                          GrVertexLayout vertexLayout) {
-    GrAssert(stageIdx < GrDrawState::kNumStages);
-    GrAssert(check_layout(vertexLayout));
-    int bit = vertexLayout & gStageTexCoordMasks[stageIdx];
-    if (bit) {
-        // figure out which set of texture coordates is used
-        // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
-        // and start at bit 0.
-        GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
-        return (32 - SkCLZ(bit) - 1) / GrDrawState::kNumStages;
-    }
-    return -1;
+bool GrDrawState::VertexUsesTexCoords(GrVertexLayout vertexLayout) {
+    return SkToBool(kTexCoordMask & vertexLayout);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrDrawState::VertexLayoutUnitTest() {
-    // Ensure that our globals mask arrays are correct
-    GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
-    GrVertexLayout texCoordMasks[kMaxTexCoords];
-    gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]);
-    }
-    for (int t = 0; t < kMaxTexCoords; ++t) {
-        GrAssert(texCoordMasks[t] == gTexCoordMasks[t]);
-    }
+    // Ensure that our tex coord mask is correct
+    GrVertexLayout texCoordMask;
+    gen_tex_coord_mask(&texCoordMask);
+    GrAssert(texCoordMask == kTexCoordMask);
 
     // not necessarily exhaustive
     static bool run;
     if (!run) {
         run = true;
+        GrVertexLayout tcMask = 0;
+        GrAssert(!VertexUsesTexCoords(0));
         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+            tcMask |= StageTexCoordVertexLayoutBit(s);
+            GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
+            GrAssert(VertexUsesTexCoords(tcMask));
+            GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
+            GrAssert(StageUsesTexCoords(tcMask, s));
+            for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
+                GrAssert(!StageUsesTexCoords(tcMask, s2));
 
-            GrVertexLayout stageMask = 0;
-            for (int t = 0; t < kMaxTexCoords; ++t) {
-                stageMask |= StageTexCoordVertexLayoutBit(s,t);
+            #if GR_DEBUG
+                GrVertexLayout posAsTex = tcMask;
+            #endif
+                GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
+                GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
+                GrAssert(!StageUsesTexCoords(posAsTex, s2));
+                GrAssert(-1 == VertexEdgeOffset(posAsTex));
             }
-            GrAssert(1 == kMaxTexCoords ||
-                     !check_layout(stageMask));
-            GrAssert(gStageTexCoordMasks[s] == stageMask);
-            GrAssert(!check_layout(stageMask));
+            GrAssert(-1 == VertexEdgeOffset(tcMask));
+            GrAssert(-1 == VertexColorOffset(tcMask));
+            GrAssert(-1 == VertexCoverageOffset(tcMask));
+        #if GR_DEBUG
+            GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
+        #endif
+            GrAssert(-1 == VertexCoverageOffset(withColor));
+            GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
+            GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
+        #if GR_DEBUG
+            GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
+        #endif
+            GrAssert(-1 == VertexColorOffset(withEdge));
+            GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
+            GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
+        #if GR_DEBUG
+            GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
+        #endif
+            GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
+            GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
+            GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
+        #if GR_DEBUG
+            GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
+        #endif
+            GrAssert(-1 == VertexColorOffset(withCoverage));
+            GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
+            GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
+        #if GR_DEBUG
+            GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
+                                                    kColor_VertexLayoutBit;
+        #endif
+            GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
+            GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
+            GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
         }
-        for (int t = 0; t < kMaxTexCoords; ++t) {
-            GrVertexLayout tcMask = 0;
-            GrAssert(!VertexUsesTexCoordIdx(t, 0));
-            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-                tcMask |= StageTexCoordVertexLayoutBit(s,t);
-                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
-                GrAssert(VertexUsesTexCoordIdx(t, tcMask));
-                GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
-                GrAssert(t == VertexTexCoordsForStage(s, tcMask));
-                for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
-                    GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
+        GrAssert(kTexCoordMask == tcMask);
 
-                #if GR_DEBUG
-                    GrVertexLayout posAsTex = tcMask;
-                #endif
-                    GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
-                    GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
-                    GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
-                    GrAssert(-1 == VertexEdgeOffset(posAsTex));
-                }
-                GrAssert(-1 == VertexEdgeOffset(tcMask));
-                GrAssert(-1 == VertexColorOffset(tcMask));
-                GrAssert(-1 == VertexCoverageOffset(tcMask));
-            #if GR_DEBUG
-                GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
-            #endif
-                GrAssert(-1 == VertexCoverageOffset(withColor));
-                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
-                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
-            #if GR_DEBUG
-                GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
-            #endif
-                GrAssert(-1 == VertexColorOffset(withEdge));
-                GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
-                GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
-            #if GR_DEBUG
-                GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
-            #endif
-                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
-                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
-                GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
-            #if GR_DEBUG
-                GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
-            #endif
-                GrAssert(-1 == VertexColorOffset(withCoverage));
-                GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
-                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
-            #if GR_DEBUG
-                GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
-                                                      kColor_VertexLayoutBit;
-            #endif
-                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
-                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
-                GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
-            }
-            GrAssert(gTexCoordMasks[t] == tcMask);
-            GrAssert(check_layout(tcMask));
-
-            int stageOffsets[GrDrawState::kNumStages];
-            int colorOffset;
-            int edgeOffset;
-            int coverageOffset;
-            int size;
-            size = VertexSizeAndOffsetsByStage(tcMask,
-                                               stageOffsets, &colorOffset,
-                                               &coverageOffset, &edgeOffset);
-            GrAssert(2*sizeof(GrPoint) == size);
-            GrAssert(-1 == colorOffset);
-            GrAssert(-1 == coverageOffset);
-            GrAssert(-1 == edgeOffset);
-            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-                GrAssert(sizeof(GrPoint) == stageOffsets[s]);
-                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
-            }
+        int stageOffsets[GrDrawState::kNumStages];
+        int colorOffset;
+        int edgeOffset;
+        int coverageOffset;
+        int size;
+        size = VertexSizeAndOffsetsByStage(tcMask,
+                                           stageOffsets, &colorOffset,
+                                           &coverageOffset, &edgeOffset);
+        GrAssert(2*sizeof(GrPoint) == size);
+        GrAssert(-1 == colorOffset);
+        GrAssert(-1 == coverageOffset);
+        GrAssert(-1 == edgeOffset);
+        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+            GrAssert(sizeof(GrPoint) == stageOffsets[s]);
+            GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
         }
     }
 }
@@ -457,7 +312,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
-    return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
+    return SkToBool(layout & StageTexCoordVertexLayoutBit(stageIdx));
 }
 
 bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {