Move vertex layout definitions from GrDrawTarget to GrDrawState.

This is the first step in revising vertex layouts so that the currently
installed GrEffects determine the current vertex layout.

https://codereview.appspot.com/7235051/


git-svn-id: http://skia.googlecode.com/svn/trunk@7423 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 4efc43a..930d8a2 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -454,7 +454,7 @@
     const SkMatrix* vm = &adcd.getOriginalMatrix();
 
     GrVertexLayout layout = 0;
-    layout |= GrDrawTarget::kEdge_VertexLayoutBit;
+    layout |= GrDrawState::kEdge_VertexLayoutBit;
 
     // We use the fact that SkPath::transform path does subdivision based on
     // perspective. Otherwise, we apply the view matrix when copying to the
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index df7aca8..c229f66 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -502,7 +502,7 @@
     target->getClip()->getConservativeBounds(drawState.getRenderTarget(),
                                              &devClipBounds);
 
-    GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
+    GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit;
     SkMatrix viewM = drawState.getViewMatrix();
 
     PREALLOC_PTARRAY(128) lines;
@@ -514,7 +514,7 @@
     *lineCnt = lines.count() / 2;
     int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
 
-    GrAssert(sizeof(Vertex) == GrDrawTarget::VertexSize(layout));
+    GrAssert(sizeof(Vertex) == GrDrawState::VertexSize(layout));
 
     if (!arg->set(target, layout, vertCnt, 0)) {
         return false;
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index b9d17f8..b23ed9a 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -16,9 +16,9 @@
 static GrVertexLayout aa_rect_layout(bool useCoverage) {
     GrVertexLayout layout = 0;
     if (useCoverage) {
-        layout |= GrDrawTarget::kCoverage_VertexLayoutBit;
+        layout |= GrDrawState::kCoverage_VertexLayoutBit;
     } else {
-        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+        layout |= GrDrawState::kColor_VertexLayoutBit;
     }
     return layout;
 }
@@ -127,7 +127,7 @@
                                   bool useVertexCoverage) {
     GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
 
-    size_t vsize = GrDrawTarget::VertexSize(layout);
+    size_t vsize = GrDrawState::VertexSize(layout);
 
     GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0);
     if (!geo.succeeded()) {
@@ -196,7 +196,7 @@
         return;
     }
     GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
-    size_t vsize = GrDrawTarget::VertexSize(layout);
+    size_t vsize = GrDrawState::VertexSize(layout);
 
     GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0);
     if (!geo.succeeded()) {
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index 66b74e4..831c430 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -382,7 +382,7 @@
     GrAssert(NULL != buffer);
     GrAssert(NULL != startVertex);
 
-    size_t vSize = GrDrawTarget::VertexSize(layout);
+    size_t vSize = GrDrawState::VertexSize(layout);
     size_t offset = 0; // assign to suppress warning
     const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
     void* ptr = INHERITED::makeSpace(vSize * vertexCount,
@@ -405,7 +405,7 @@
     if (NULL != space) {
         memcpy(space,
                vertices,
-               GrDrawTarget::VertexSize(layout) * vertexCount);
+               GrDrawState::VertexSize(layout) * vertexCount);
         return true;
     } else {
         return false;
@@ -414,11 +414,11 @@
 
 int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
     return INHERITED::preallocatedBufferSize() /
-            GrDrawTarget::VertexSize(layout);
+            GrDrawState::VertexSize(layout);
 }
 
 int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
-    return currentBufferItems(GrDrawTarget::VertexSize(layout));
+    return currentBufferItems(GrDrawState::VertexSize(layout));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index fdeb15c..41029f4 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -309,7 +309,7 @@
         GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
         drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params);
 
-        static const GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+        static const GrVertexLayout layout = GrDrawState::StageTexCoordVertexLayoutBit(0,0);
         GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
 
         if (arg.succeeded()) {
@@ -875,12 +875,12 @@
 
     GrVertexLayout layout = 0;
     if (NULL != texCoords) {
-        layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
+        layout |= GrDrawState::StageTexCoordVertexLayoutBit(0, 0);
     }
     if (NULL != colors) {
-        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+        layout |= GrDrawState::kColor_VertexLayoutBit;
     }
-    int vertexSize = GrDrawTarget::VertexSize(layout);
+    int vertexSize = GrDrawState::VertexSize(layout);
 
     if (sizeof(GrPoint) != vertexSize) {
         if (!geo.set(target, layout, vertexCount, 0)) {
@@ -889,7 +889,7 @@
         }
         int texOffsets[GrDrawState::kMaxTexCoords];
         int colorOffset;
-        GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+        GrDrawState::VertexSizeAndOffsetsByIdx(layout,
                                                 texOffsets,
                                                 &colorOffset,
                                                 NULL,
@@ -1005,7 +1005,7 @@
         return;
     }
 
-    GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
+    GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit;
     GrAssert(sizeof(CircleVertex) == GrDrawTarget::VertexSize(layout));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, layout, 4, 0);
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 2d5c7aa..6079272 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -7,6 +7,7 @@
 
 #include "GrDrawState.h"
 
+#include "GrGpuVertex.h"
 #include "GrPaint.h"
 
 void GrDrawState::setFromPaint(const GrPaint& paint) {
@@ -47,6 +48,490 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+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.)
+ *
+ */
+void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
+                     GrVertexLayout* texCoordMasks) {
+    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);
+        }
+    }
+}
+
+/**
+ * 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.
+ */
+
+#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;
+}
+
+} //unnamed namespace
+
+size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+
+    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                        sizeof(GrGpuTextVertex) :
+                        sizeof(GrPoint);
+
+    size_t size = vecSize; // position
+    size += num_tex_coords(vertexLayout) * vecSize;
+    if (vertexLayout & kColor_VertexLayoutBit) {
+        size += sizeof(GrColor);
+    }
+    if (vertexLayout & kCoverage_VertexLayoutBit) {
+        size += sizeof(GrColor);
+    }
+    if (vertexLayout & kEdge_VertexLayoutBit) {
+        size += 4 * sizeof(SkScalar);
+    }
+    return size;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Functions for computing offsets of various components from the layout
+ * bitfield.
+ *
+ * Order of vertex components:
+ * Position
+ * Tex Coord 0
+ * ...
+ * Tex Coord GrDrawState::kMaxTexCoords-1
+ * 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 vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        int offset = vecSize; // 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 += vecSize;
+            }
+        }
+        return offset;
+    }
+
+    return -1;
+}
+
+int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+
+    if (vertexLayout & kColor_VertexLayoutBit) {
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
+    }
+    return -1;
+}
+
+int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+
+    if (vertexLayout & kCoverage_VertexLayoutBit) {
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+
+        int offset = vecSize * (num_tex_coords(vertexLayout) + 1);
+        if (vertexLayout & kColor_VertexLayoutBit) {
+            offset += sizeof(GrColor);
+        }
+        return offset;
+    }
+    return -1;
+}
+
+int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+
+    // edge pts are after the pos, tex coords, and color
+    if (vertexLayout & kEdge_VertexLayoutBit) {
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
+        if (vertexLayout & kColor_VertexLayoutBit) {
+            offset += sizeof(GrColor);
+        }
+        if (vertexLayout & kCoverage_VertexLayoutBit) {
+            offset += sizeof(GrColor);
+        }
+        return offset;
+    }
+    return -1;
+}
+
+int GrDrawState::VertexSizeAndOffsetsByIdx(
+        GrVertexLayout vertexLayout,
+        int texCoordOffsetsByIdx[kMaxTexCoords],
+        int* colorOffset,
+        int* coverageOffset,
+        int* edgeOffset) {
+    GrAssert(check_layout(vertexLayout));
+
+    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                                    sizeof(GrGpuTextVertex) :
+                                                    sizeof(GrPoint);
+    int size = vecSize; // position
+
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (gTexCoordMasks[t] & vertexLayout) {
+            if (NULL != texCoordOffsetsByIdx) {
+                texCoordOffsetsByIdx[t] = size;
+            }
+            size += vecSize;
+        } else {
+            if (NULL != texCoordOffsetsByIdx) {
+                texCoordOffsetsByIdx[t] = -1;
+            }
+        }
+    }
+    if (kColor_VertexLayoutBit & vertexLayout) {
+        if (NULL != colorOffset) {
+            *colorOffset = size;
+        }
+        size += sizeof(GrColor);
+    } else {
+        if (NULL != colorOffset) {
+            *colorOffset = -1;
+        }
+    }
+    if (kCoverage_VertexLayoutBit & vertexLayout) {
+        if (NULL != coverageOffset) {
+            *coverageOffset = size;
+        }
+        size += sizeof(GrColor);
+    } else {
+        if (NULL != coverageOffset) {
+            *coverageOffset = -1;
+        }
+    }
+    if (kEdge_VertexLayoutBit & vertexLayout) {
+        if (NULL != edgeOffset) {
+            *edgeOffset = size;
+        }
+        size += 4 * sizeof(SkScalar);
+    } else {
+        if (NULL != edgeOffset) {
+            *edgeOffset = -1;
+        }
+    }
+    return size;
+}
+
+int GrDrawState::VertexSizeAndOffsetsByStage(
+        GrVertexLayout vertexLayout,
+        int texCoordOffsetsByStage[GrDrawState::kNumStages],
+        int* colorOffset,
+        int* coverageOffset,
+        int* edgeOffset) {
+    GrAssert(check_layout(vertexLayout));
+
+    int texCoordOffsetsByIdx[kMaxTexCoords];
+    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
+                                         (NULL == texCoordOffsetsByStage) ?
+                                               NULL :
+                                               texCoordOffsetsByIdx,
+                                         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];
+        }
+    }
+    return size;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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]);
+    }
+
+    // not necessarily exhaustive
+    static bool run;
+    if (!run) {
+        run = true;
+        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+
+            GrVertexLayout stageMask = 0;
+            for (int t = 0; t < kMaxTexCoords; ++t) {
+                stageMask |= StageTexCoordVertexLayoutBit(s,t);
+            }
+            GrAssert(1 == kMaxTexCoords ||
+                     !check_layout(stageMask));
+            GrAssert(gStageTexCoordMasks[s] == stageMask);
+            GrAssert(!check_layout(stageMask));
+        }
+        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));
+
+                #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));
+            }
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
+    return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
+}
+
+bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {
+
+    uint32_t validComponentFlags;
+    GrColor  color;
+    // Check if per-vertex or constant color may have partial alpha
+    if (layout & kColor_VertexLayoutBit) {
+        validComponentFlags = 0;
+    } else {
+        validComponentFlags = GrEffect::kAll_ValidComponentFlags;
+        color = this->getColor();
+    }
+
+    // Run through the color stages
+    int stageCnt = getFirstCoverageStage();
+    for (int s = 0; s < stageCnt; ++s) {
+        const GrEffectRef* effect = this->getStage(s).getEffect();
+        if (NULL != effect) {
+            (*effect)->getConstantColorComponents(&color, &validComponentFlags);
+        }
+    }
+
+    // Check if the color filter could introduce an alpha.
+    // We could skip the above work when this is true, but it is rare and the right fix is to make
+    // the color filter a GrEffect and implement getConstantColorComponents() for it.
+    if (SkXfermode::kDst_Mode != this->getColorFilterMode()) {
+        validComponentFlags = 0;
+    }
+
+    // Check whether coverage is treated as color. If so we run through the coverage computation.
+    if (this->isCoverageDrawing()) {
+        GrColor coverageColor = this->getCoverage();
+        GrColor oldColor = color;
+        color = 0;
+        for (int c = 0; c < 4; ++c) {
+            if (validComponentFlags & (1 << c)) {
+                U8CPU a = (oldColor >> (c * 8)) & 0xff;
+                U8CPU b = (coverageColor >> (c * 8)) & 0xff;
+                color |= (SkMulDiv255Round(a, b) << (c * 8));
+            }
+        }
+        for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
+            const GrEffectRef* effect = this->getStage(s).getEffect();
+            if (NULL != effect) {
+                (*effect)->getConstantColorComponents(&color, &validComponentFlags);
+            }
+        }
+    }
+    return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 void GrDrawState::AutoViewMatrixRestore::restore() {
     if (NULL != fDrawState) {
         fDrawState->setViewMatrix(fViewMatrix);
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index e70c38f..dc3fdfe 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -10,14 +10,15 @@
 
 #include "GrBackendEffectFactory.h"
 #include "GrColor.h"
-#include "SkMatrix.h"
-#include "GrRefCnt.h"
 #include "GrEffectStage.h"
-#include "GrStencil.h"
-#include "GrTexture.h"
+#include "GrRefCnt.h"
 #include "GrRenderTarget.h"
+#include "GrStencil.h"
+#include "GrTemplates.h"
+#include "GrTexture.h"
 #include "effects/GrSimpleTextureEffect.h"
 
+#include "SkMatrix.h"
 #include "SkXfermode.h"
 
 class GrPaint;
@@ -103,6 +104,269 @@
     void setFromPaint(const GrPaint& paint);
 
     ///////////////////////////////////////////////////////////////////////////
+    /// @name Vertex Format
+    ////
+
+    /**
+     * The format of vertices is represented as a bitfield of flags.
+     * Flags that indicate the layout of vertex data. Vertices always contain
+     * positions and may also contain up to GrDrawState::kMaxTexCoords sets
+     * of 2D texture coordinates, per-vertex colors, and per-vertex coverage.
+     * Each stage can
+     * use any of the texture coordinates as its input texture coordinates or it
+     * may use the positions as texture coordinates.
+     *
+     * If no texture coordinates are specified for a stage then the stage is
+     * disabled.
+     *
+     * Only one type of texture coord can be specified per stage. For
+     * example StageTexCoordVertexLayoutBit(0, 2) and
+     * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
+     *
+     * The order in memory is always (position, texture coord 0, ..., color,
+     * coverage) with any unused fields omitted. Note that this means that if
+     * only texture coordinates 1 is referenced then there is no texture
+     * coordinates 0 and the order would be (position, texture coordinate 1
+     * [, color][, coverage]).
+     */
+
+    /**
+     * Generates a bit indicating that a texture stage uses texture coordinates
+     *
+     * @param stageIdx    the stage that will use texture coordinates.
+     * @param texCoordIdx the index of the texture coordinates to use
+     *
+     * @return the bit to add to a GrVertexLayout bitfield.
+     */
+    static int StageTexCoordVertexLayoutBit(int stageIdx, int texCoordIdx) {
+        GrAssert(stageIdx < kNumStages);
+        GrAssert(texCoordIdx < kMaxTexCoords);
+        return 1 << (stageIdx + (texCoordIdx * kNumStages));
+    }
+
+    static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
+    
+private:
+    // non-stage bits start at this index.
+    static const int STAGE_BIT_CNT = kNumStages * kMaxTexCoords;
+public:
+
+    /**
+     * Additional Bits that can be specified in GrVertexLayout.
+     */
+    enum VertexLayoutBits {
+        /* vertices have colors (GrColor) */
+        kColor_VertexLayoutBit              = 1 << (STAGE_BIT_CNT + 0),
+        /* vertices have coverage (GrColor)
+         */
+        kCoverage_VertexLayoutBit           = 1 << (STAGE_BIT_CNT + 1),
+        /* Use text vertices. (Pos and tex coords may be a different type for
+         * text [GrGpuTextVertex vs GrPoint].)
+         */
+        kTextFormat_VertexLayoutBit         = 1 << (STAGE_BIT_CNT + 2),
+
+        /* Each vertex specificies an edge. Distance to the edge is used to
+         * compute a coverage. See GrDrawState::setVertexEdgeType().
+         */
+        kEdge_VertexLayoutBit               = 1 << (STAGE_BIT_CNT + 3),
+        // for below assert
+        kDummyVertexLayoutBit,
+        kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
+    };
+    // make sure we haven't exceeded the number of bits in GrVertexLayout.
+    GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Helpers for picking apart vertex layouts
+
+    /**
+     * Helper function to compute the size of a vertex from a vertex layout
+     * @return size of a single vertex.
+     */
+    static size_t VertexSize(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function for determining the index of texture coordinates that
+     * is input for a texture stage. Note that a stage may instead use positions
+     * as texture coordinates, in which case the result of the function is
+     * indistinguishable from the case when the stage is disabled.
+     *
+     * @param stageIdx      the stage to query
+     * @param vertexLayout  layout to query
+     *
+     * @return the texture coordinate index or -1 if the stage doesn't use
+     *         separate (non-position) texture coordinates.
+     */
+    static int VertexTexCoordsForStage(int stageIdx, GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of texture coordinates in a vertex
+     * @return offset of texture coordinates in vertex layout or -1 if the
+     *         layout has no texture coordinates. Will be 0 if positions are
+     *         used as texture coordinates for the stage.
+     */
+    static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of the color in a vertex
+     * @return offset of color in vertex layout or -1 if the
+     *         layout has no color.
+     */
+    static int VertexColorOffset(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of the coverage in a vertex
+     * @return offset of coverage in vertex layout or -1 if the
+     *         layout has no coverage.
+     */
+    static int VertexCoverageOffset(GrVertexLayout vertexLayout);
+
+     /**
+      * Helper function to compute the offset of the edge pts in a vertex
+      * @return offset of edge in vertex layout or -1 if the
+      *         layout has no edge.
+      */
+     static int VertexEdgeOffset(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to determine if vertex layout contains explicit texture
+     * coordinates of some index.
+     *
+     * @param coordIndex    the tex coord index to query
+     * @param vertexLayout  layout to query
+     *
+     * @return true if vertex specifies texture coordinates for the index,
+     *              false otherwise.
+     */
+    static bool VertexUsesTexCoordIdx(int coordIndex,
+                                      GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the size of each vertex and the offsets of
+     * texture coordinates and color. Determines tex coord offsets by tex coord
+     * index rather than by stage. (Each stage can be mapped to any t.c. index
+     * by StageTexCoordVertexLayoutBit.)
+     *
+     * @param vertexLayout          the layout to query
+     * @param texCoordOffsetsByIdx  after return it is the offset of each
+     *                              tex coord index in the vertex or -1 if
+     *                              index isn't used. (optional)
+     * @param colorOffset           after return it is the offset of the
+     *                              color field in each vertex, or -1 if
+     *                              there aren't per-vertex colors. (optional)
+     * @param coverageOffset        after return it is the offset of the
+     *                              coverage field in each vertex, or -1 if
+     *                              there aren't per-vertex coeverages.
+     *                              (optional)
+     * @param edgeOffset            after return it is the offset of the
+     *                              edge eq field in each vertex, or -1 if
+     *                              there aren't per-vertex edge equations.
+     *                              (optional)
+     * @return size of a single vertex
+     */
+    static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
+                   int texCoordOffsetsByIdx[kMaxTexCoords],
+                   int *colorOffset,
+                   int *coverageOffset,
+                   int* edgeOffset);
+
+    /**
+     * Helper function to compute the size of each vertex and the offsets of
+     * texture coordinates and color. Determines tex coord offsets by stage
+     * rather than by index. (Each stage can be mapped to any t.c. index
+     * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
+     * tex coords then that stage's offset will be 0 (positions are always at 0).
+     *
+     * @param vertexLayout              the layout to query
+     * @param texCoordOffsetsByStage    after return it is the offset of each
+     *                                  tex coord index in the vertex or -1 if
+     *                                  index isn't used. (optional)
+     * @param colorOffset               after return it is the offset of the
+     *                                  color field in each vertex, or -1 if
+     *                                  there aren't per-vertex colors.
+     *                                  (optional)
+     * @param coverageOffset            after return it is the offset of the
+     *                                  coverage field in each vertex, or -1 if
+     *                                  there aren't per-vertex coeverages.
+     *                                  (optional)
+     * @param edgeOffset                after return it is the offset of the
+     *                                  edge eq field in each vertex, or -1 if
+     *                                  there aren't per-vertex edge equations.
+     *                                  (optional)
+     * @return size of a single vertex
+     */
+    static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
+                   int texCoordOffsetsByStage[kNumStages],
+                   int* colorOffset,
+                   int* coverageOffset,
+                   int* edgeOffset);
+
+    // determine if src alpha is guaranteed to be one for all src pixels
+    bool srcAlphaWillBeOne(GrVertexLayout vertexLayout) const;
+
+    /**
+     * Accessing positions, texture coords, or colors, of a vertex within an
+     * array is a hassle involving casts and simple math. These helpers exist
+     * to keep GrDrawTarget clients' code a bit nicer looking.
+     */
+
+    /**
+     * Gets a pointer to a GrPoint of a vertex's position or texture
+     * coordinate.
+     * @param vertices      the vetex array
+     * @param vertexIndex   the index of the vertex in the array
+     * @param vertexSize    the size of each vertex in the array
+     * @param offset        the offset in bytes of the vertex component.
+     *                      Defaults to zero (corresponding to vertex position)
+     * @return pointer to the vertex component as a GrPoint
+     */
+    static GrPoint* GetVertexPoint(void* vertices,
+                                   int vertexIndex,
+                                   int vertexSize,
+                                   int offset = 0) {
+        intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<GrPoint*>(start + offset +
+                                 vertexIndex * vertexSize);
+    }
+    static const GrPoint* GetVertexPoint(const void* vertices,
+                                         int vertexIndex,
+                                         int vertexSize,
+                                         int offset = 0) {
+        intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<const GrPoint*>(start + offset +
+                                       vertexIndex * vertexSize);
+    }
+
+    /**
+     * Gets a pointer to a GrColor inside a vertex within a vertex array.
+     * @param vertices      the vetex array
+     * @param vertexIndex   the index of the vertex in the array
+     * @param vertexSize    the size of each vertex in the array
+     * @param offset        the offset in bytes of the vertex color
+     * @return pointer to the vertex component as a GrColor
+     */
+    static GrColor* GetVertexColor(void* vertices,
+                                   int vertexIndex,
+                                   int vertexSize,
+                                   int offset) {
+        intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<GrColor*>(start + offset +
+                                 vertexIndex * vertexSize);
+    }
+    static const GrColor* GetVertexColor(const void* vertices,
+                                         int vertexIndex,
+                                         int vertexSize,
+                                         int offset) {
+        const intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<const GrColor*>(start + offset +
+                                       vertexIndex * vertexSize);
+    }
+
+    static void VertexLayoutUnitTest();
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
     /// @name Color
     ////
 
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index b0bac8a..ff8b9da 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -9,7 +9,6 @@
 
 
 #include "GrDrawTarget.h"
-#include "GrGpuVertex.h"
 #include "GrRenderTarget.h"
 #include "GrTexture.h"
 #include "GrVertexBuffer.h"
@@ -18,432 +17,6 @@
 
 SK_DEFINE_INST_COUNT(GrDrawTarget)
 
-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 GrDrawTarget.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.)
- *
- */
-void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
-                     GrVertexLayout* texCoordMasks) {
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        stageTexCoordMasks[s] = 0;
-        for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-            stageTexCoordMasks[s] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t);
-        }
-    }
-    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        texCoordMasks[t] = 0;
-        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-            texCoordMasks[t] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t);
-        }
-    }
-}
-
-/**
- * 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.
- */
-
-#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;
-}
-
-} //unnamed namespace
-
-size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
-    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
-                        sizeof(GrGpuTextVertex) :
-                        sizeof(GrPoint);
-
-    size_t size = vecSize; // position
-    size += num_tex_coords(vertexLayout) * vecSize;
-    if (vertexLayout & kColor_VertexLayoutBit) {
-        size += sizeof(GrColor);
-    }
-    if (vertexLayout & kCoverage_VertexLayoutBit) {
-        size += sizeof(GrColor);
-    }
-    if (vertexLayout & kEdge_VertexLayoutBit) {
-        size += 4 * sizeof(SkScalar);
-    }
-    return size;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Functions for computing offsets of various components from the layout
- * bitfield.
- *
- * Order of vertex components:
- * Position
- * Tex Coord 0
- * ...
- * Tex Coord GrDrawState::kMaxTexCoords-1
- * Color
- * Coverage
- */
-
-int GrDrawTarget::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
-    if (!StageUsesTexCoords(vertexLayout, stageIdx)) {
-        return 0;
-    }
-    int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout);
-    if (tcIdx >= 0) {
-
-        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
-                                    sizeof(GrGpuTextVertex) :
-                                    sizeof(GrPoint);
-        int offset = vecSize; // 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 += vecSize;
-            }
-        }
-        return offset;
-    }
-
-    return -1;
-}
-
-int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
-    if (vertexLayout & kColor_VertexLayoutBit) {
-        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
-                                    sizeof(GrGpuTextVertex) :
-                                    sizeof(GrPoint);
-        return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
-    }
-    return -1;
-}
-
-int GrDrawTarget::VertexCoverageOffset(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
-    if (vertexLayout & kCoverage_VertexLayoutBit) {
-        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
-                                    sizeof(GrGpuTextVertex) :
-                                    sizeof(GrPoint);
-
-        int offset = vecSize * (num_tex_coords(vertexLayout) + 1);
-        if (vertexLayout & kColor_VertexLayoutBit) {
-            offset += sizeof(GrColor);
-        }
-        return offset;
-    }
-    return -1;
-}
-
-int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) {
-    GrAssert(check_layout(vertexLayout));
-
-    // edge pts are after the pos, tex coords, and color
-    if (vertexLayout & kEdge_VertexLayoutBit) {
-        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
-                                    sizeof(GrGpuTextVertex) :
-                                    sizeof(GrPoint);
-        int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
-        if (vertexLayout & kColor_VertexLayoutBit) {
-            offset += sizeof(GrColor);
-        }
-        if (vertexLayout & kCoverage_VertexLayoutBit) {
-            offset += sizeof(GrColor);
-        }
-        return offset;
-    }
-    return -1;
-}
-
-int GrDrawTarget::VertexSizeAndOffsetsByIdx(
-        GrVertexLayout vertexLayout,
-        int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords],
-        int* colorOffset,
-        int* coverageOffset,
-        int* edgeOffset) {
-    GrAssert(check_layout(vertexLayout));
-
-    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
-                                                    sizeof(GrGpuTextVertex) :
-                                                    sizeof(GrPoint);
-    int size = vecSize; // position
-
-    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        if (gTexCoordMasks[t] & vertexLayout) {
-            if (NULL != texCoordOffsetsByIdx) {
-                texCoordOffsetsByIdx[t] = size;
-            }
-            size += vecSize;
-        } else {
-            if (NULL != texCoordOffsetsByIdx) {
-                texCoordOffsetsByIdx[t] = -1;
-            }
-        }
-    }
-    if (kColor_VertexLayoutBit & vertexLayout) {
-        if (NULL != colorOffset) {
-            *colorOffset = size;
-        }
-        size += sizeof(GrColor);
-    } else {
-        if (NULL != colorOffset) {
-            *colorOffset = -1;
-        }
-    }
-    if (kCoverage_VertexLayoutBit & vertexLayout) {
-        if (NULL != coverageOffset) {
-            *coverageOffset = size;
-        }
-        size += sizeof(GrColor);
-    } else {
-        if (NULL != coverageOffset) {
-            *coverageOffset = -1;
-        }
-    }
-    if (kEdge_VertexLayoutBit & vertexLayout) {
-        if (NULL != edgeOffset) {
-            *edgeOffset = size;
-        }
-        size += 4 * sizeof(SkScalar);
-    } else {
-        if (NULL != edgeOffset) {
-            *edgeOffset = -1;
-        }
-    }
-    return size;
-}
-
-int GrDrawTarget::VertexSizeAndOffsetsByStage(
-        GrVertexLayout vertexLayout,
-        int texCoordOffsetsByStage[GrDrawState::kNumStages],
-        int* colorOffset,
-        int* coverageOffset,
-        int* edgeOffset) {
-    GrAssert(check_layout(vertexLayout));
-
-    int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords];
-    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
-                                         (NULL == texCoordOffsetsByStage) ?
-                                               NULL :
-                                               texCoordOffsetsByIdx,
-                                         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];
-        }
-    }
-    return size;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
-                                         GrVertexLayout vertexLayout) {
-    GrAssert(coordIndex < GrDrawState::kMaxTexCoords);
-    GrAssert(check_layout(vertexLayout));
-    return !!(gTexCoordMasks[coordIndex] & vertexLayout);
-}
-
-int GrDrawTarget::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;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrDrawTarget::VertexLayoutUnitTest() {
-    // Ensure that our globals mask arrays are correct
-    GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
-    GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
-    gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]);
-    }
-    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        GrAssert(texCoordMasks[t] == gTexCoordMasks[t]);
-    }
-
-    // not necessarily exhaustive
-    static bool run;
-    if (!run) {
-        run = true;
-        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-
-            GrVertexLayout stageMask = 0;
-            for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-                stageMask |= StageTexCoordVertexLayoutBit(s,t);
-            }
-            GrAssert(1 == GrDrawState::kMaxTexCoords ||
-                     !check_layout(stageMask));
-            GrAssert(gStageTexCoordMasks[s] == stageMask);
-            GrAssert(!check_layout(stageMask));
-        }
-        for (int t = 0; t < GrDrawState::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));
-
-                #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));
-            }
-        }
-    }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 
 #define DEBUG_INVAL_BUFFER 0xdeadcafe
@@ -551,10 +124,6 @@
 
 }
 
-bool GrDrawTarget::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
-    return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
-}
-
 bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
                                               int vertexCount,
                                               int indexCount,
@@ -824,57 +393,6 @@
            this->getDrawState().isCoverageDrawing();
 }
 
-bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const {
-    const GrDrawState& drawState = this->getDrawState();
-
-    uint32_t validComponentFlags;
-    GrColor  color;
-    // Check if per-vertex or constant color may have partial alpha
-    if (layout & kColor_VertexLayoutBit) {
-        validComponentFlags = 0;
-    } else {
-        validComponentFlags = GrEffect::kAll_ValidComponentFlags;
-        color = drawState.getColor();
-    }
-
-    // Run through the color stages
-    int stageCnt = drawState.getFirstCoverageStage();
-    for (int s = 0; s < stageCnt; ++s) {
-        const GrEffectRef* effect = drawState.getStage(s).getEffect();
-        if (NULL != effect) {
-            (*effect)->getConstantColorComponents(&color, &validComponentFlags);
-        }
-    }
-
-    // Check if the color filter could introduce an alpha.
-    // We could skip the above work when this is true, but it is rare and the right fix is to make
-    // the color filter a GrEffect and implement getConstantColorComponents() for it.
-    if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) {
-        validComponentFlags = 0;
-    }
-
-    // Check whether coverage is treated as color. If so we run through the coverage computation.
-    if (drawState.isCoverageDrawing()) {
-        GrColor coverageColor = drawState.getCoverage();
-        GrColor oldColor = color;
-        color = 0;
-        for (int c = 0; c < 4; ++c) {
-            if (validComponentFlags & (1 << c)) {
-                U8CPU a = (oldColor >> (c * 8)) & 0xff;
-                U8CPU b = (coverageColor >> (c * 8)) & 0xff;
-                color |= (SkMulDiv255Round(a, b) << (c * 8));
-            }
-        }
-        for (int s = drawState.getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
-            const GrEffectRef* effect = drawState.getStage(s).getEffect();
-            if (NULL != effect) {
-                (*effect)->getConstantColorComponents(&color, &validComponentFlags);
-            }
-        }
-    }
-    return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
-}
-
 namespace {
 GrVertexLayout default_blend_opts_vertex_layout() {
     GrVertexLayout layout = 0;
@@ -912,14 +430,14 @@
         *dstCoeff = kOne_GrBlendCoeff;
     }
 
-    bool srcAIsOne = this->srcAlphaWillBeOne(layout);
+    bool srcAIsOne = drawState.srcAlphaWillBeOne(layout);
     bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
                          (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
     bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
                          (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
 
     bool covIsZero = !drawState.isCoverageDrawing() &&
-                     !(layout & kCoverage_VertexLayoutBit) &&
+                     !(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
                      0 == drawState.getCoverage();
     // When coeffs are (0,1) there is no reason to draw at all, unless
     // stenciling is enabled. Having color writes disabled is effectively
@@ -937,8 +455,8 @@
     // edge aa or coverage stage
     bool hasCoverage = forceCoverage ||
                        0xffffffff != drawState.getCoverage() ||
-                       (layout & kCoverage_VertexLayoutBit) ||
-                       (layout & kEdge_VertexLayoutBit);
+                       (layout & GrDrawState::kCoverage_VertexLayoutBit) ||
+                       (layout & GrDrawState::kEdge_VertexLayoutBit);
     for (int s = drawState.getFirstCoverageStage();
          !hasCoverage && s < GrDrawState::kNumStages;
          ++s) {
@@ -1076,7 +594,7 @@
     for (int i = 0; i < GrDrawState::kNumStages; ++i) {
         int numTC = 0;
         if (NULL != srcRects[i]) {
-            layout |= StageTexCoordVertexLayoutBit(i, numTC);
+            layout |= GrDrawState::StageTexCoordVertexLayoutBit(i, numTC);
             ++numTC;
         }
     }
@@ -1111,8 +629,8 @@
 #endif
 
     int stageOffsets[GrDrawState::kNumStages], colorOffset;
-    int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets,
-                                            &colorOffset, NULL, NULL);
+    int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets,
+                                                         &colorOffset, NULL, NULL);
 
     GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
                                             rect.fRight, rect.fBottom,
@@ -1134,7 +652,7 @@
         }
     }
 
-    if (layout & kColor_VertexLayoutBit) {
+    if (colorOffset >= 0) {
 
         GrColor* vertCol = GrTCast<GrColor*>(GrTCast<intptr_t>(vertices) + colorOffset);
 
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 544cfc3..74d820b 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -16,7 +16,6 @@
 #include "GrIndexBuffer.h"
 #include "SkMatrix.h"
 #include "GrRefCnt.h"
-#include "GrTemplates.h"
 
 #include "SkClipStack.h"
 #include "SkPath.h"
@@ -170,76 +169,6 @@
     bool willUseHWAALines() const;
 
     /**
-     * The format of vertices is represented as a bitfield of flags.
-     * Flags that indicate the layout of vertex data. Vertices always contain
-     * positions and may also contain up to GrDrawState::kMaxTexCoords sets
-     * of 2D texture coordinates, per-vertex colors, and per-vertex coverage.
-     * Each stage can
-     * use any of the texture coordinates as its input texture coordinates or it
-     * may use the positions as texture coordinates.
-     *
-     * If no texture coordinates are specified for a stage then the stage is
-     * disabled.
-     *
-     * Only one type of texture coord can be specified per stage. For
-     * example StageTexCoordVertexLayoutBit(0, 2) and
-     * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
-     *
-     * The order in memory is always (position, texture coord 0, ..., color,
-     * coverage) with any unused fields omitted. Note that this means that if
-     * only texture coordinates 1 is referenced then there is no texture
-     * coordinates 0 and the order would be (position, texture coordinate 1
-     * [, color][, coverage]).
-     */
-
-    /**
-     * Generates a bit indicating that a texture stage uses texture coordinates
-     *
-     * @param stageIdx    the stage that will use texture coordinates.
-     * @param texCoordIdx the index of the texture coordinates to use
-     *
-     * @return the bit to add to a GrVertexLayout bitfield.
-     */
-    static int StageTexCoordVertexLayoutBit(int stageIdx, int texCoordIdx) {
-        GrAssert(stageIdx < GrDrawState::kNumStages);
-        GrAssert(texCoordIdx < GrDrawState::kMaxTexCoords);
-        return 1 << (stageIdx + (texCoordIdx * GrDrawState::kNumStages));
-    }
-
-    static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
-
-private:
-    // non-stage bits start at this index.
-    static const int STAGE_BIT_CNT = GrDrawState::kNumStages *
-                                     GrDrawState::kMaxTexCoords;
-public:
-
-    /**
-     * Additional Bits that can be specified in GrVertexLayout.
-     */
-    enum VertexLayoutBits {
-        /* vertices have colors (GrColor) */
-        kColor_VertexLayoutBit              = 1 << (STAGE_BIT_CNT + 0),
-        /* vertices have coverage (GrColor)
-         */
-        kCoverage_VertexLayoutBit           = 1 << (STAGE_BIT_CNT + 1),
-        /* Use text vertices. (Pos and tex coords may be a different type for
-         * text [GrGpuTextVertex vs GrPoint].)
-         */
-        kTextFormat_VertexLayoutBit         = 1 << (STAGE_BIT_CNT + 2),
-
-        /* Each vertex specificies an edge. Distance to the edge is used to
-         * compute a coverage. See GrDrawState::setVertexEdgeType().
-         */
-        kEdge_VertexLayoutBit               = 1 << (STAGE_BIT_CNT + 3),
-        // for below assert
-        kDummyVertexLayoutBit,
-        kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
-    };
-    // make sure we haven't exceeded the number of bits in GrVertexLayout.
-    GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
-
-    /**
      * There are three types of "sources" of geometry (vertices and indices) for
      * draw calls made on the target. When performing an indexed draw, the
      * indices and vertices can use different source types. Once a source is
@@ -671,191 +600,6 @@
         GrDrawTarget* fTarget;
     };
 
-    ////////////////////////////////////////////////////////////////////////////
-    // Helpers for picking apart vertex layouts
-
-    /**
-     * Helper function to compute the size of a vertex from a vertex layout
-     * @return size of a single vertex.
-     */
-    static size_t VertexSize(GrVertexLayout vertexLayout);
-
-    /**
-     * Helper function for determining the index of texture coordinates that
-     * is input for a texture stage. Note that a stage may instead use positions
-     * as texture coordinates, in which case the result of the function is
-     * indistinguishable from the case when the stage is disabled.
-     *
-     * @param stageIdx      the stage to query
-     * @param vertexLayout  layout to query
-     *
-     * @return the texture coordinate index or -1 if the stage doesn't use
-     *         separate (non-position) texture coordinates.
-     */
-    static int VertexTexCoordsForStage(int stageIdx, GrVertexLayout vertexLayout);
-
-    /**
-     * Helper function to compute the offset of texture coordinates in a vertex
-     * @return offset of texture coordinates in vertex layout or -1 if the
-     *         layout has no texture coordinates. Will be 0 if positions are
-     *         used as texture coordinates for the stage.
-     */
-    static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
-
-    /**
-     * Helper function to compute the offset of the color in a vertex
-     * @return offset of color in vertex layout or -1 if the
-     *         layout has no color.
-     */
-    static int VertexColorOffset(GrVertexLayout vertexLayout);
-
-    /**
-     * Helper function to compute the offset of the coverage in a vertex
-     * @return offset of coverage in vertex layout or -1 if the
-     *         layout has no coverage.
-     */
-    static int VertexCoverageOffset(GrVertexLayout vertexLayout);
-
-     /**
-      * Helper function to compute the offset of the edge pts in a vertex
-      * @return offset of edge in vertex layout or -1 if the
-      *         layout has no edge.
-      */
-     static int VertexEdgeOffset(GrVertexLayout vertexLayout);
-
-    /**
-     * Helper function to determine if vertex layout contains explicit texture
-     * coordinates of some index.
-     *
-     * @param coordIndex    the tex coord index to query
-     * @param vertexLayout  layout to query
-     *
-     * @return true if vertex specifies texture coordinates for the index,
-     *              false otherwise.
-     */
-    static bool VertexUsesTexCoordIdx(int coordIndex,
-                                      GrVertexLayout vertexLayout);
-
-    /**
-     * Helper function to compute the size of each vertex and the offsets of
-     * texture coordinates and color. Determines tex coord offsets by tex coord
-     * index rather than by stage. (Each stage can be mapped to any t.c. index
-     * by StageTexCoordVertexLayoutBit.)
-     *
-     * @param vertexLayout          the layout to query
-     * @param texCoordOffsetsByIdx  after return it is the offset of each
-     *                              tex coord index in the vertex or -1 if
-     *                              index isn't used. (optional)
-     * @param colorOffset           after return it is the offset of the
-     *                              color field in each vertex, or -1 if
-     *                              there aren't per-vertex colors. (optional)
-     * @param coverageOffset        after return it is the offset of the
-     *                              coverage field in each vertex, or -1 if
-     *                              there aren't per-vertex coeverages.
-     *                              (optional)
-     * @param edgeOffset            after return it is the offset of the
-     *                              edge eq field in each vertex, or -1 if
-     *                              there aren't per-vertex edge equations.
-     *                              (optional)
-     * @return size of a single vertex
-     */
-    static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
-                   int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords],
-                   int *colorOffset,
-                   int *coverageOffset,
-                   int* edgeOffset);
-
-    /**
-     * Helper function to compute the size of each vertex and the offsets of
-     * texture coordinates and color. Determines tex coord offsets by stage
-     * rather than by index. (Each stage can be mapped to any t.c. index
-     * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
-     * tex coords then that stage's offset will be 0 (positions are always at 0).
-     *
-     * @param vertexLayout              the layout to query
-     * @param texCoordOffsetsByStage    after return it is the offset of each
-     *                                  tex coord index in the vertex or -1 if
-     *                                  index isn't used. (optional)
-     * @param colorOffset               after return it is the offset of the
-     *                                  color field in each vertex, or -1 if
-     *                                  there aren't per-vertex colors.
-     *                                  (optional)
-     * @param coverageOffset            after return it is the offset of the
-     *                                  coverage field in each vertex, or -1 if
-     *                                  there aren't per-vertex coeverages.
-     *                                  (optional)
-     * @param edgeOffset                after return it is the offset of the
-     *                                  edge eq field in each vertex, or -1 if
-     *                                  there aren't per-vertex edge equations.
-     *                                  (optional)
-     * @return size of a single vertex
-     */
-    static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
-                   int texCoordOffsetsByStage[GrDrawState::kNumStages],
-                   int* colorOffset,
-                   int* coverageOffset,
-                   int* edgeOffset);
-
-    /**
-     * Accessing positions, texture coords, or colors, of a vertex within an
-     * array is a hassle involving casts and simple math. These helpers exist
-     * to keep GrDrawTarget clients' code a bit nicer looking.
-     */
-
-    /**
-     * Gets a pointer to a GrPoint of a vertex's position or texture
-     * coordinate.
-     * @param vertices      the vetex array
-     * @param vertexIndex   the index of the vertex in the array
-     * @param vertexSize    the size of each vertex in the array
-     * @param offset        the offset in bytes of the vertex component.
-     *                      Defaults to zero (corresponding to vertex position)
-     * @return pointer to the vertex component as a GrPoint
-     */
-    static GrPoint* GetVertexPoint(void* vertices,
-                                   int vertexIndex,
-                                   int vertexSize,
-                                   int offset = 0) {
-        intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<GrPoint*>(start + offset +
-                                 vertexIndex * vertexSize);
-    }
-    static const GrPoint* GetVertexPoint(const void* vertices,
-                                         int vertexIndex,
-                                         int vertexSize,
-                                         int offset = 0) {
-        intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<const GrPoint*>(start + offset +
-                                       vertexIndex * vertexSize);
-    }
-
-    /**
-     * Gets a pointer to a GrColor inside a vertex within a vertex array.
-     * @param vertices      the vetex array
-     * @param vertexIndex   the index of the vertex in the array
-     * @param vertexSize    the size of each vertex in the array
-     * @param offset        the offset in bytes of the vertex color
-     * @return pointer to the vertex component as a GrColor
-     */
-    static GrColor* GetVertexColor(void* vertices,
-                                   int vertexIndex,
-                                   int vertexSize,
-                                   int offset) {
-        intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<GrColor*>(start + offset +
-                                 vertexIndex * vertexSize);
-    }
-    static const GrColor* GetVertexColor(const void* vertices,
-                                         int vertexIndex,
-                                         int vertexSize,
-                                         int offset) {
-        const intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<const GrColor*>(start + offset +
-                                       vertexIndex * vertexSize);
-    }
-
-    static void VertexLayoutUnitTest();
-
 protected:
 
     /**
@@ -906,9 +650,6 @@
                                GrBlendCoeff* srcCoeff = NULL,
                                GrBlendCoeff* dstCoeff = NULL) const;
 
-    // determine if src alpha is guaranteed to be one for all src pixels
-    bool srcAlphaWillBeOne(GrVertexLayout vertexLayout) const;
-
     enum GeometrySrcType {
         kNone_GeometrySrcType,     //<! src has not been specified
         kReserved_GeometrySrcType, //<! src was set using reserve*Space
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index d2a8852..b32c56a 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -498,7 +498,7 @@
 void GrGpu::releaseReservedVertexSpace() {
     const GeometrySrcState& geoSrc = this->getGeomSrc();
     GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
-    size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+    size_t bytes = geoSrc.fVertexCount * GrDrawState::VertexSize(geoSrc.fVertexLayout);
     fVertexPool->putBack(bytes);
     --fVertexPoolUseCnt;
 }
@@ -544,7 +544,7 @@
     // if vertex source was array, we stowed data in the pool
     const GeometrySrcState& geoSrc = this->getGeomSrc();
     GrAssert(kArray_GeometrySrcType == geoSrc.fVertexSrc);
-    size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+    size_t bytes = geoSrc.fVertexCount * GrDrawState::VertexSize(geoSrc.fVertexLayout);
     fVertexPool->putBack(bytes);
     --fVertexPoolUseCnt;
 }
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index aceff2e..7e83589 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -118,7 +118,7 @@
         }
 
         if (batchAcrossColors) {
-            layout |= kColor_VertexLayoutBit;
+            layout |= GrDrawState::kColor_VertexLayoutBit;
         }
 
         AutoReleaseGeometry geo(this, layout, 4, 0);
@@ -193,10 +193,10 @@
                 if (target->height() <= devClipRect.fBottom) {
                     devClipRect.fBottom = SK_ScalarMax;
                 }
-                int stride = VertexSize(layout);
+                int stride = GrDrawState::VertexSize(layout);
                 bool insideClip = true;
                 for (int v = 0; v < 4; ++v) {
-                    const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
+                    const GrPoint& p = *GrDrawState::GetVertexPoint(geo.vertices(), v, stride);
                     if (!devClipRect.contains(p)) {
                         insideClip = false;
                         break;
@@ -215,7 +215,7 @@
             fCurrQuad < fMaxQuads &&
             layout == fLastRectVertexLayout) {
 
-            int vsize = VertexSize(layout);
+            int vsize = GrDrawState::VertexSize(layout);
 
             Draw& lastDraw = fDraws.back();
 
@@ -335,7 +335,7 @@
 
         // update the amount of reserved data actually referenced in draws
         size_t vertexBytes = instanceCount * verticesPerInstance *
-                             VertexSize(draw->fVertexLayout);
+                             GrDrawState::VertexSize(draw->fVertexLayout);
         poolState.fUsedPoolVertexBytes =
                             GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
 
@@ -411,7 +411,7 @@
     case kReserved_GeometrySrcType: // fallthrough
     case kArray_GeometrySrcType: {
         size_t vertexBytes = (vertexCount + startVertex) *
-                             VertexSize(draw->fVertexLayout);
+                             GrDrawState::VertexSize(draw->fVertexLayout);
         poolState.fUsedPoolVertexBytes =
                             GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
         draw->fVertexBuffer = poolState.fPoolVertexBuffer;
@@ -474,7 +474,7 @@
     case kReserved_GeometrySrcType: // fallthrough
     case kArray_GeometrySrcType: {
         size_t vertexBytes = (vertexCount + startVertex) *
-                             VertexSize(draw->fVertexLayout);
+                             GrDrawState::VertexSize(draw->fVertexLayout);
         poolState.fUsedPoolVertexBytes =
                             GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
         draw->fVertexBuffer = poolState.fPoolVertexBuffer;
@@ -759,7 +759,7 @@
     // provided by the vertex buffer pool. At each draw we tracked the largest
     // offset into the pool's pointer that was referenced. Now we return to the
     // pool any portion at the tail of the allocation that no draw referenced.
-    size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
+    size_t reservedVertexBytes = GrDrawState::VertexSize(geoSrc.fVertexLayout) *
                                  geoSrc.fVertexCount;
     fVertexPool.putBack(reservedVertexBytes -
                         poolState.fUsedPoolVertexBytes);
@@ -852,7 +852,7 @@
     if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
         kArray_GeometrySrcType == restoredState.fVertexSrc) {
         poolState.fUsedPoolVertexBytes =
-            VertexSize(restoredState.fVertexLayout) *
+            GrDrawState::VertexSize(restoredState.fVertexLayout) *
             restoredState.fVertexCount;
     }
     if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index beb3f91..206f4ca 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -95,8 +95,8 @@
     fMaxVertices = 0;
 
     fVertexLayout =
-        GrDrawTarget::kTextFormat_VertexLayoutBit |
-        GrDrawTarget::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);
+        GrDrawState::kTextFormat_VertexLayoutBit |
+        GrDrawState::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);
 }
 
 GrTextContext::~GrTextContext() {
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index e6daa9c..2aa7236 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -225,7 +225,7 @@
 
 bool GrGLProgram::genEdgeCoverage(SkString* coverageVar,
                                   GrGLShaderBuilder* builder) const {
-    if (fDesc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit) {
+    if (fDesc.fVertexLayout & GrDrawState::kEdge_VertexLayoutBit) {
         const char *vsName, *fsName;
         builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName);
         builder->fVSAttrs.push_back().set(kVec4f_GrSLType,
@@ -587,7 +587,7 @@
     // add texture coordinates that are used to the list of vertex attr decls
     SkString texCoordAttrs[GrDrawState::kMaxTexCoords];
     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
-        if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
+        if (GrDrawState::VertexUsesTexCoordIdx(t, layout)) {
             tex_attr_name(t, texCoordAttrs + t);
             builder.fVSAttrs.push_back().set(kVec2f_GrSLType,
                 GrGLShaderVar::kAttribute_TypeModifier,
@@ -611,7 +611,7 @@
 
                 const char* inCoords;
                 // figure out what our input coords are
-                int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout);
+                int tcIdx = GrDrawState::VertexTexCoordsForStage(s, layout);
                 if (tcIdx < 0) {
                     inCoords = builder.positionAttribute().c_str();
                 } else {
@@ -708,7 +708,7 @@
                     const char* inCoords;
                     // figure out what our input coords are
                     int tcIdx =
-                        GrDrawTarget::VertexTexCoordsForStage(s, layout);
+                        GrDrawState::VertexTexCoordsForStage(s, layout);
                     if (tcIdx < 0) {
                         inCoords = builder.positionAttribute().c_str();
                     } else {
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index b8d5f08..d1a60fa 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -165,7 +165,7 @@
     const ProgramDesc& desc = fCurrentProgram->getDesc();
     const GrDrawState& drawState = this->getDrawState();
 
-    if (this->getVertexLayout() & kColor_VertexLayoutBit) {
+    if (this->getVertexLayout() & GrDrawState::kColor_VertexLayoutBit) {
         // color will be specified per-vertex as an attribute
         // invalidate the const vertex attrib color
         fHWConstAttribColor = GrColor_ILLEGAL;
@@ -214,7 +214,7 @@
     // const GrDrawState& drawState = this->getDrawState();
 
 
-    if (this->getVertexLayout() & kCoverage_VertexLayoutBit) {
+    if (this->getVertexLayout() & GrDrawState::kCoverage_VertexLayoutBit) {
         // coverage will be specified per-vertex as an attribute
         // invalidate the const vertex attrib coverage
         fHWConstAttribCoverage = GrColor_ILLEGAL;
@@ -352,7 +352,7 @@
 
     GrVertexLayout currLayout = this->getVertexLayout();
 
-    GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
+    GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(
                                             currLayout,
                                             newTexCoordOffsets,
                                             &newColorOffset,
@@ -363,7 +363,7 @@
     int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
     int oldEdgeOffset;
 
-    GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
+    GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(
                                             fHWGeometryState.fVertexLayout,
                                             oldTexCoordOffsets,
                                             &oldColorOffset,
@@ -377,7 +377,7 @@
 
     GrGLenum scalarType;
     bool texCoordNorm;
-    if (currLayout & kTextFormat_VertexLayoutBit) {
+    if (currLayout & GrDrawState::kTextFormat_VertexLayoutBit) {
         scalarType = TEXT_COORDS_GL_TYPE;
         texCoordNorm = SkToBool(TEXT_COORDS_ARE_NORMALIZED);
     } else {
@@ -401,7 +401,7 @@
     // or the type/normalization changed based on text vs nontext type coords.
     bool posAndTexChange = allOffsetsChange ||
                            (((TEXT_COORDS_GL_TYPE != GR_GL_FLOAT) || TEXT_COORDS_ARE_NORMALIZED) &&
-                                (kTextFormat_VertexLayoutBit &
+                                (GrDrawState::kTextFormat_VertexLayoutBit &
                                   (fHWGeometryState.fVertexLayout ^ currLayout)));
 
     if (posAndTexChange) {
@@ -503,14 +503,14 @@
     desc->fEmitsPointSize = isPoints;
 
     bool requiresAttributeColors = !skipColor &&
-                                   SkToBool(desc->fVertexLayout & kColor_VertexLayoutBit);
+                                   SkToBool(desc->fVertexLayout & GrDrawState::kColor_VertexLayoutBit);
     bool requiresAttributeCoverage = !skipCoverage &&
-                                     SkToBool(desc->fVertexLayout & kCoverage_VertexLayoutBit);
+                                     SkToBool(desc->fVertexLayout & GrDrawState::kCoverage_VertexLayoutBit);
 
     // fColorInput/fCoverageInput records how colors are specified for the.
     // program. So we strip the bits from the layout to avoid false negatives
     // when searching for an existing program in the cache.
-    desc->fVertexLayout &= ~(kColor_VertexLayoutBit | kCoverage_VertexLayoutBit);
+    desc->fVertexLayout &= ~(GrDrawState::kColor_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit);
 
     desc->fColorFilterXfermode = skipColor ?
                                 SkXfermode::kDst_Mode :
@@ -519,7 +519,7 @@
     // no reason to do edge aa or look at per-vertex coverage if coverage is
     // ignored
     if (skipCoverage) {
-        desc->fVertexLayout &= ~(kEdge_VertexLayoutBit | kCoverage_VertexLayoutBit);
+        desc->fVertexLayout &= ~(GrDrawState::kEdge_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit);
     }
 
     bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
@@ -549,7 +549,7 @@
 
     int lastEnabledStage = -1;
 
-    if (!skipCoverage && (desc->fVertexLayout &GrDrawTarget::kEdge_VertexLayoutBit)) {
+    if (!skipCoverage && (desc->fVertexLayout &GrDrawState::kEdge_VertexLayoutBit)) {
         desc->fVertexEdgeType = drawState.getVertexEdgeType();
         desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite();
     } else {
@@ -592,7 +592,7 @@
     // other coverage inputs
     if (!hasCoverage) {
         hasCoverage = requiresAttributeCoverage ||
-                      (desc->fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit);
+                      (desc->fVertexLayout & GrDrawState::kEdge_VertexLayoutBit);
     }
 
     if (hasCoverage) {
diff --git a/src/gpu/gr_unittests.cpp b/src/gpu/gr_unittests.cpp
index 7a3a251..7f5c7e9 100644
--- a/src/gpu/gr_unittests.cpp
+++ b/src/gpu/gr_unittests.cpp
@@ -75,5 +75,5 @@
     test_bsearch();
     test_binHashKey();
     GrRedBlackTree<int>::UnitTest();
-    GrDrawTarget::VertexLayoutUnitTest();
+    GrDrawState::VertexLayoutUnitTest();
 }