Initial change to create GeometryProcessor

BUG=skia:
R=bsalomon@google.com, robertphillips@google.com, egdaniel@google.com, jvanverth@google.com

Author: joshualitt@chromium.org

Review URL: https://codereview.chromium.org/509153002
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 545ed21..8d0ea3d 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -53,6 +53,7 @@
                             GrBlendCoeff dstCoeff,
                             const GrGpuGL* gpu,
                             const GrDeviceCoordTexture* dstCopy,
+                            const GrEffectStage** geometryProcessor,
                             SkTArray<const GrEffectStage*, true>* colorStages,
                             SkTArray<const GrEffectStage*, true>* coverageStages,
                             GrGLProgramDesc* desc) {
@@ -69,6 +70,7 @@
 
     int firstEffectiveColorStage = 0;
     bool inputColorIsUsed = true;
+
     if (!skipColor) {
         firstEffectiveColorStage = drawState.numColorStages();
         while (firstEffectiveColorStage > 0 && inputColorIsUsed) {
@@ -107,6 +109,9 @@
     bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType);
 
     int numStages = 0;
+    if (drawState.hasGeometryProcessor()) {
+        numStages++;
+    }
     if (!skipColor) {
         numStages += drawState.numColorStages() - firstEffectiveColorStage;
     }
@@ -120,9 +125,14 @@
 
     int offsetAndSizeIndex = 0;
     bool effectKeySuccess = true;
-    if (!skipColor) {
-        for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
-            uint16_t* offsetAndSize =
+
+    KeyHeader* header = desc->header();
+    // make sure any padding in the header is zeroed.
+    memset(desc->header(), 0, kHeaderSize);
+
+    // We can only have one effect which touches the vertex shader
+    if (drawState.hasGeometryProcessor()) {
+        uint16_t* offsetAndSize =
                 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
                                             offsetAndSizeIndex * 2 * sizeof(uint16_t));
 
@@ -130,7 +140,7 @@
             uint16_t effectKeySize;
             uint32_t effectOffset = desc->fKey.count();
             effectKeySuccess |= GetEffectKeyAndUpdateStats(
-                                    drawState.getColorStage(s), gpu->glCaps(),
+                                    *drawState.getGeometryProcessor(), gpu->glCaps(),
                                     requiresLocalCoordAttrib, &b,
                                     &effectKeySize, &readsDst,
                                     &readFragPosition, &requiresVertexShader);
@@ -139,6 +149,32 @@
             offsetAndSize[0] = SkToU16(effectOffset);
             offsetAndSize[1] = effectKeySize;
             ++offsetAndSizeIndex;
+            *geometryProcessor = drawState.getGeometryProcessor();
+            SkASSERT(requiresVertexShader);
+            header->fHasGeometryProcessor = true;
+    }
+
+    if (!skipColor) {
+        for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
+            uint16_t* offsetAndSize =
+                reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
+                                            offsetAndSizeIndex * 2 * sizeof(uint16_t));
+
+            bool effectRequiresVertexShader = false;
+            GrEffectKeyBuilder b(&desc->fKey);
+            uint16_t effectKeySize;
+            uint32_t effectOffset = desc->fKey.count();
+            effectKeySuccess |= GetEffectKeyAndUpdateStats(
+                                    drawState.getColorStage(s), gpu->glCaps(),
+                                    requiresLocalCoordAttrib, &b,
+                                    &effectKeySize, &readsDst,
+                                    &readFragPosition, &effectRequiresVertexShader);
+            effectKeySuccess |= (effectOffset <= SK_MaxU16);
+
+            offsetAndSize[0] = SkToU16(effectOffset);
+            offsetAndSize[1] = effectKeySize;
+            ++offsetAndSizeIndex;
+            SkASSERT(!effectRequiresVertexShader);
         }
     }
     if (!skipCoverage) {
@@ -147,6 +183,7 @@
                 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
                                             offsetAndSizeIndex * 2 * sizeof(uint16_t));
 
+            bool effectRequiresVertexShader = false;
             GrEffectKeyBuilder b(&desc->fKey);
             uint16_t effectKeySize;
             uint32_t effectOffset = desc->fKey.count();
@@ -154,12 +191,13 @@
                                     drawState.getCoverageStage(s), gpu->glCaps(),
                                     requiresLocalCoordAttrib, &b,
                                     &effectKeySize, &readsDst,
-                                    &readFragPosition, &requiresVertexShader);
+                                    &readFragPosition, &effectRequiresVertexShader);
             effectKeySuccess |= (effectOffset <= SK_MaxU16);
 
             offsetAndSize[0] = SkToU16(effectOffset);
             offsetAndSize[1] = effectKeySize;
             ++offsetAndSizeIndex;
+            SkASSERT(!effectRequiresVertexShader);
         }
     }
     if (!effectKeySuccess) {
@@ -167,10 +205,6 @@
         return false;
     }
 
-    KeyHeader* header = desc->header();
-    // make sure any padding in the header is zeroed.
-    memset(desc->header(), 0, kHeaderSize);
-
     // Because header is a pointer into the dynamic array, we can't push any new data into the key
     // below here.
 
@@ -259,9 +293,11 @@
     header->fCoverageOutput = kModulate_CoverageOutput;
 
     // If we do have coverage determine whether it matters.
-    bool separateCoverageFromColor = false;
+    bool separateCoverageFromColor = drawState.hasGeometryProcessor();
     if (!drawState.isCoverageDrawing() && !skipCoverage &&
-        (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) {
+        (drawState.numCoverageStages() > 0 ||
+         drawState.hasGeometryProcessor() ||
+         requiresCoverageAttrib)) {
 
         if (gpu->caps()->dualSourceBlendingSupport() &&
             !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag |
@@ -286,6 +322,7 @@
             separateCoverageFromColor = true;
         }
     }
+
     if (!skipColor) {
         for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
             colorStages->push_back(&drawState.getColorStage(s));