Push creation of default GP to the caller

TBR=
BUG=skia:

Review URL: https://codereview.chromium.org/715903002
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 2e9c82c..74d19bd 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -8,12 +8,13 @@
 #include "GrAAHairLinePathRenderer.h"
 
 #include "GrContext.h"
+#include "GrDefaultGeoProcFactory.h"
 #include "GrDrawState.h"
 #include "GrDrawTargetCaps.h"
-#include "GrProcessor.h"
 #include "GrGpu.h"
 #include "GrIndexBuffer.h"
 #include "GrPathUtils.h"
+#include "GrProcessor.h"
 #include "GrTBackendProcessorFactory.h"
 #include "SkGeometry.h"
 #include "SkStroke.h"
@@ -642,19 +643,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 namespace {
-
 // position + edge
 extern const GrVertexAttrib gHairlineBezierAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,                  kPosition_GrVertexAttribBinding},
     {kVec4f_GrVertexAttribType, sizeof(SkPoint),    kGeometryProcessor_GrVertexAttribBinding}
 };
-
-// position + coverage
-extern const GrVertexAttrib gHairlineLineAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
-    {kFloat_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding},
-};
-
 };
 
 bool GrAAHairLinePathRenderer::createLineGeom(const SkPath& path,
@@ -669,8 +662,8 @@
 
     int vertCnt = kLineSegNumVertices * lineCnt;
 
-    drawState->setVertexAttribs<gHairlineLineAttribs>(SK_ARRAY_COUNT(gHairlineLineAttribs),
-                                                      sizeof(LineVertex));
+    GrDefaultGeoProcFactory::SetAttribs(drawState, GrDefaultGeoProcFactory::kPosition_GPType |
+                                                   GrDefaultGeoProcFactory::kCoverage_GPType);
 
     if (!arg->set(target, vertCnt, 0)) {
         return false;
@@ -884,6 +877,7 @@
 
         {
             GrDrawState::AutoRestoreEffects are(drawState);
+            drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
             target->setIndexSourceToBuffer(fLinesIndexBuffer);
             int lines = 0;
             while (lines < lineCnt) {
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index e743ae9..f748895 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -6,24 +6,19 @@
  */
 
 #include "GrAARectRenderer.h"
+#include "GrDefaultGeoProcFactory.h"
+#include "GrGeometryProcessor.h"
 #include "GrGpu.h"
 #include "GrInvariantOutput.h"
-#include "gl/builders/GrGLProgramBuilder.h"
-#include "gl/GrGLProcessor.h"
-#include "gl/GrGLGeometryProcessor.h"
 #include "GrTBackendProcessorFactory.h"
 #include "SkColorPriv.h"
-#include "GrGeometryProcessor.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
 namespace {
-extern const GrVertexAttrib gAARectAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,                                 kPosition_GrVertexAttribBinding},
-    {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding},
-    {kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor),  kCoverage_GrVertexAttribBinding},
-};
-
 // Should the coverage be multiplied into the color attrib or use a separate attrib.
 enum CoverageAttribType {
     kUseColor_CoverageAttribType,
@@ -33,11 +28,17 @@
 
 static CoverageAttribType set_rect_attribs(GrDrawState* drawState) {
     if (drawState->canTweakAlphaForCoverage()) {
-        drawState->setVertexAttribs<gAARectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
+        drawState->setGeometryProcessor(
+                GrDefaultGeoProcFactory::CreateAndSetAttribs(
+                        drawState,
+                        GrDefaultGeoProcFactory::kColor_GPType))->unref();
         return kUseColor_CoverageAttribType;
     } else {
-        drawState->setVertexAttribs<gAARectAttribs>(3, sizeof(SkPoint) + sizeof(SkColor) +
-                                                       sizeof(float));
+        drawState->setGeometryProcessor(
+                GrDefaultGeoProcFactory::CreateAndSetAttribs(
+                        drawState,
+                        GrDefaultGeoProcFactory::kColor_GPType |
+                        GrDefaultGeoProcFactory::kCoverage_GPType))->unref();
         return kUseCoverage_CoverageAttribType;
     }
 }
@@ -180,6 +181,7 @@
                                           const SkMatrix& combinedMatrix,
                                           const SkRect& devRect) {
     GrDrawState* drawState = target->drawState();
+    GrDrawState::AutoRestoreEffects are(drawState);
 
     GrColor color = drawState->getColor();
 
@@ -377,6 +379,7 @@
                                             const SkRect& devInside,
                                             bool miterStroke) {
     GrDrawState* drawState = target->drawState();
+    GrDrawState::AutoRestoreEffects are(drawState);
 
     CoverageAttribType covAttribType = set_rect_attribs(drawState);
 
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 41dc784..50fe9ca 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -7,6 +7,7 @@
 
 #include "GrBitmapTextContext.h"
 #include "GrAtlas.h"
+#include "GrDefaultGeoProcFactory.h"
 #include "GrDrawTarget.h"
 #include "GrFontScaler.h"
 #include "GrIndexBuffer.h"
@@ -14,8 +15,6 @@
 #include "GrTexturePriv.h"
 #include "GrTextStrike.h"
 #include "GrTextStrike_impl.h"
-#include "effects/GrCustomCoordsTextureEffect.h"
-#include "effects/GrSimpleTextureEffect.h"
 
 #include "SkAutoKern.h"
 #include "SkColorPriv.h"
@@ -29,6 +28,9 @@
 #include "SkStrokeRec.h"
 #include "SkTextMapStateProc.h"
 
+#include "effects/GrCustomCoordsTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
+
 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
                 "Dump the contents of the font cache before every purge.");
 
@@ -42,11 +44,6 @@
 static const size_t kLCDTextVASize = 2 * sizeof(SkPoint);
 
 // position + local coord
-extern const GrVertexAttrib gColorVertexAttribs[] = {
-    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding}
-};
-
 static const size_t kColorTextVASize = 2 * sizeof(SkPoint);
 
 // position + color + texture coord
@@ -360,8 +357,8 @@
         drawTarget->drawState()->setVertexAttribs<gGrayVertexAttribs>(
                                     SK_ARRAY_COUNT(gGrayVertexAttribs), kGrayTextVASize);
     } else if (kARGB_GrMaskFormat == maskFormat) {
-        drawTarget->drawState()->setVertexAttribs<gColorVertexAttribs>(
-                                    SK_ARRAY_COUNT(gColorVertexAttribs), kColorTextVASize);
+        GrDefaultGeoProcFactory::SetAttribs(drawTarget->drawState(),
+                                            GrDefaultGeoProcFactory::kLocalCoord_GPType);
     } else {
         drawTarget->drawState()->setVertexAttribs<gLCDVertexAttribs>(
                                     SK_ARRAY_COUNT(gLCDVertexAttribs), kLCDTextVASize);
@@ -564,6 +561,7 @@
 
         // This effect could be stored with one of the cache objects (atlas?)
         if (kARGB_GrMaskFormat == fCurrMaskFormat) {
+            drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(true))->unref();
             GrFragmentProcessor* fragProcessor = GrSimpleTextureEffect::Create(fCurrTexture,
                                                                                SkMatrix::I(),
                                                                                params);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 0a742ed..5e0755b 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -8,17 +8,14 @@
 
 #include "GrContext.h"
 
-#include "effects/GrConfigConversionEffect.h"
-#include "effects/GrDashingEffect.h"
-#include "effects/GrSingleTextureEffect.h"
-
 #include "GrAARectRenderer.h"
 #include "GrBufferAllocPool.h"
-#include "GrGpu.h"
+#include "GrDefaultGeoProcFactory.h"
 #include "GrGpuResource.h"
 #include "GrGpuResourceCacheAccess.h"
 #include "GrDistanceFieldTextContext.h"
 #include "GrDrawTargetCaps.h"
+#include "GrGpu.h"
 #include "GrIndexBuffer.h"
 #include "GrInOrderDrawBuffer.h"
 #include "GrLayerCache.h"
@@ -44,6 +41,10 @@
 #include "SkTLS.h"
 #include "SkTraceEvent.h"
 
+#include "effects/GrConfigConversionEffect.h"
+#include "effects/GrDashingEffect.h"
+#include "effects/GrSingleTextureEffect.h"
+
 #ifdef SK_DEBUG
     // change this to a 1 to see notifications when partial coverage fails
     #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0
@@ -299,16 +300,6 @@
     }
 }
 
-namespace {
-
-// position + local coordinate
-extern const GrVertexAttrib gVertexAttribs[] = {
-    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding}
-};
-
-};
-
 // The desired texture is NPOT and tiled but that isn't supported by
 // the current hardware. Resize the texture to be a POT
 GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
@@ -347,8 +338,11 @@
                                         GrTextureParams::kNone_FilterMode);
         drawState->addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
 
-        drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs),
-                                                    2 * sizeof(SkPoint));
+        drawState->setGeometryProcessor(
+                GrDefaultGeoProcFactory::CreateAndSetAttribs(
+                        drawState,
+                        GrDefaultGeoProcFactory::kPosition_GPType |
+                        GrDefaultGeoProcFactory::kLocalCoord_GPType))->unref();
 
         GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, 0);
 
@@ -772,6 +766,7 @@
 
         static const int worstCaseVertCount = 10;
         target->drawState()->setDefaultVertexAttribs();
+        target->drawState()->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
         GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0);
 
         if (!geo.succeeded()) {
@@ -821,25 +816,6 @@
     target->drawRect(dstRect, &localRect, localMatrix);
 }
 
-namespace {
-
-extern const GrVertexAttrib gPosUVColorAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding },
-    {kVec2f_GrVertexAttribType,  sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding },
-    {kVec4ub_GrVertexAttribType, 2*sizeof(SkPoint), kColor_GrVertexAttribBinding}
-};
-
-static const size_t kPosUVAttribsSize = 2 * sizeof(SkPoint);
-static const size_t kPosUVColorAttribsSize = 2 * sizeof(SkPoint) + sizeof(GrColor);
-
-extern const GrVertexAttrib gPosColorAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding},
-    {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
-};
-
-static const size_t kPosAttribsSize = sizeof(SkPoint);
-static const size_t kPosColorAttribsSize = sizeof(SkPoint) + sizeof(GrColor);
-
 static void set_vertex_attributes(GrDrawState* drawState,
                                   const SkPoint* texCoords,
                                   const GrColor* colors,
@@ -848,23 +824,23 @@
     *texOffset = -1;
     *colorOffset = -1;
 
+    uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
     if (texCoords && colors) {
-        *texOffset = sizeof(SkPoint);
-        *colorOffset = 2*sizeof(SkPoint);
-        drawState->setVertexAttribs<gPosUVColorAttribs>(3, kPosUVColorAttribsSize);
+        *colorOffset = sizeof(SkPoint);
+        *texOffset = sizeof(SkPoint) + sizeof(GrColor);
+        flags |= GrDefaultGeoProcFactory::kColor_GPType |
+                 GrDefaultGeoProcFactory::kLocalCoord_GPType;
     } else if (texCoords) {
         *texOffset = sizeof(SkPoint);
-        drawState->setVertexAttribs<gPosUVColorAttribs>(2, kPosUVAttribsSize);
+        flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
     } else if (colors) {
         *colorOffset = sizeof(SkPoint);
-        drawState->setVertexAttribs<gPosColorAttribs>(2, kPosColorAttribsSize);
-    } else {
-        drawState->setVertexAttribs<gPosColorAttribs>(1, kPosAttribsSize);
+        flags |= GrDefaultGeoProcFactory::kColor_GPType;
     }
+    drawState->setGeometryProcessor(GrDefaultGeoProcFactory::CreateAndSetAttribs(drawState,
+                                                                                 flags))->unref();
 }
 
-};
-
 void GrContext::drawVertices(const GrPaint& paint,
                              GrPrimitiveType primitiveType,
                              int vertexCount,
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 1258d59..332e733 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -20,8 +20,8 @@
  */
 class DefaultGeoProc : public GrGeometryProcessor {
 public:
-    static GrGeometryProcessor* Create() {
-        GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, ());
+    static GrGeometryProcessor* Create(bool hasCoverage) {
+        GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, (hasCoverage));
         return SkRef(gDefaultGeoProc);
     }
 
@@ -57,18 +57,24 @@
     };
 
 private:
-    DefaultGeoProc() {}
+    DefaultGeoProc(bool hasCoverageAttribute) : fHasCoverageAttribute(hasCoverageAttribute) {}
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
         return true;
     }
 
     virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+        if (fHasCoverageAttribute) {
+            inout->mulByUnknownAlpha();
+        } else {
+            inout->mulByKnownAlpha(255);
+        }
     }
 
     GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
+    bool fHasCoverageAttribute;
+
     typedef GrFragmentProcessor INHERITED;
 };
 
@@ -78,33 +84,33 @@
                                                 GrContext*,
                                                 const GrDrawTargetCaps& caps,
                                                 GrTexture*[]) {
-    return DefaultGeoProc::Create();
+    return DefaultGeoProc::Create(random->nextBool());
 }
 
 // We use these arrays to customize our default GP.  We only need 4 because we omit coverage if
 // coverage is not requested in the flags to the create function.
 GrVertexAttrib kDefaultPositionGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                kPosition_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding },
+    { kFloat_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
 };
 
 GrVertexAttrib kDefaultPosColorGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                                  kPosition_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 0,                                 kPosition_GrVertexAttribBinding },
+    { kVec4ub_GrVertexAttribType, sizeof(SkPoint),                  kColor_GrVertexAttribBinding },
+    { kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
 };
 
-GrVertexAttrib kDefaultPosUVGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                    kPosition_GrVertexAttribBinding },
-    { kVec2f_GrVertexAttribType, sizeof(SkPoint),      kLocalCoord_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
+GrVertexAttrib kDefaultPosLocalCoordGeoProc[] = {
+    { kVec2f_GrVertexAttribType, 0,                   kPosition_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, sizeof(SkPoint),     kLocalCoord_GrVertexAttribBinding },
+    { kFloat_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
 };
 
-GrVertexAttrib kDefaultPosColUVGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                                      kPosition_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint),                       kColor_GrVertexAttribBinding },
-    { kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor),      kLocalCoord_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
+GrVertexAttrib kDefaultPosColLocalCoordGeoProc[] = {
+    { kVec2f_GrVertexAttribType, 0,                                     kPosition_GrVertexAttribBinding },
+    { kVec4ub_GrVertexAttribType, sizeof(SkPoint),                      kColor_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor),     kLocalCoord_GrVertexAttribBinding },
+    { kFloat_GrVertexAttribType, 2 * sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
 };
 
 static size_t get_size(GrDefaultGeoProcFactory::GPType flag) {
@@ -116,15 +122,14 @@
         case GrDefaultGeoProcFactory::kLocalCoord_GPType:
             return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
         case GrDefaultGeoProcFactory::kCoverage_GPType:
-            return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType);
+            return GrVertexAttribTypeSize(kFloat_GrVertexAttribType);
         default:
             SkFAIL("Should never get here");
             return 0;
     }
 }
 
-const GrGeometryProcessor*
-GrDefaultGeoProcFactory::CreateAndSetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
+void GrDefaultGeoProcFactory::SetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
     SkASSERT(ds);
     // always atleast position in the GP
     size_t size = get_size(kPosition_GPType);
@@ -143,9 +148,9 @@
             if (hasCoverage) {
                 size += get_size(kCoverage_GPType);
                 count++;
-                ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size);
+                ds->setVertexAttribs<kDefaultPosColLocalCoordGeoProc>(count, size);
             } else {
-                ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size);
+                ds->setVertexAttribs<kDefaultPosColLocalCoordGeoProc>(count, size);
 
             }
         } else {
@@ -163,9 +168,9 @@
         if (hasCoverage) {
             size += get_size(kCoverage_GPType);
             count++;
-            ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
+            ds->setVertexAttribs<kDefaultPosLocalCoordGeoProc>(count, size);
         } else {
-            ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
+            ds->setVertexAttribs<kDefaultPosLocalCoordGeoProc>(count, size);
         }
     } else if (hasCoverage) {
         size += get_size(kCoverage_GPType);
@@ -175,9 +180,16 @@
         // Just position
         ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
     }
-    return DefaultGeoProc::Create();
 }
 
-const GrGeometryProcessor* GrDefaultGeoProcFactory::Create() {
-    return DefaultGeoProc::Create();
+const GrGeometryProcessor*
+GrDefaultGeoProcFactory::CreateAndSetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
+    SetAttribs(ds, gpTypeFlags);
+
+    bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPType);
+    return DefaultGeoProc::Create(hasCoverage);
+}
+
+const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(bool hasAttributeCoverage) {
+    return DefaultGeoProc::Create(hasAttributeCoverage);
 }
diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h
index 26ce662..99d85b6 100644
--- a/src/gpu/GrDefaultGeoProcFactory.h
+++ b/src/gpu/GrDefaultGeoProcFactory.h
@@ -75,9 +75,16 @@
         kLastGPType = kCoverage_GPType
     };
 
-    // YOU MUST UNREF
-    static const GrGeometryProcessor* CreateAndSetAttribs(GrDrawState*, uint32_t GPTypeFlags);
-    static const GrGeometryProcessor* Create();
+    /*
+     * The following functions are used to create default GPs.  If you just need to create
+     * attributes seperately from creating the default GP, use the SetAttribs function followed
+     * by the Create function.  Otherwise use CreateAndSetAttribs to do both at once.
+     *
+     * You must unref the return from Create.
+     */
+    static void SetAttribs(GrDrawState*, uint32_t GPTypeFlags = 0);
+    static const GrGeometryProcessor* CreateAndSetAttribs(GrDrawState*, uint32_t GPTypeFlags = 0);
+    static const GrGeometryProcessor* Create(bool hasAttributeCoverage);
 };
 
 #endif
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 43a545c..e4ac225 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -8,6 +8,7 @@
 #include "GrDefaultPathRenderer.h"
 
 #include "GrContext.h"
+#include "GrDefaultGeoProcFactory.h"
 #include "GrDrawState.h"
 #include "GrPathUtils.h"
 #include "SkString.h"
@@ -496,6 +497,8 @@
             if (passCount > 1) {
                 drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
             }
+            GrDrawState::AutoRestoreEffects are(drawState);
+            drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
             if (indexCnt) {
                 target->drawIndexed(primType, 0, 0,
                                     vertexCnt, indexCnt, &devBounds);
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 82f1e60..3d858c3 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -126,7 +126,6 @@
 }
 
 void GrDrawTarget::setClip(const GrClipData* clip) {
-    clipWillBeSet(clip);
     fClip = clip;
 }
 
@@ -758,59 +757,6 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-namespace {
-
-// position + (optional) texture coord
-extern const GrVertexAttrib gBWRectPosUVAttribs[] = {
-    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding}
-};
-
-void set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
-    if (hasUVs) {
-        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2, 2 * sizeof(SkPoint));
-    } else {
-        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1, sizeof(SkPoint));
-    }
-}
-
-};
-
-void GrDrawTarget::onDrawRect(const SkRect& rect,
-                              const SkRect* localRect,
-                              const SkMatrix* localMatrix) {
-
-    set_vertex_attributes(this->drawState(), SkToBool(localRect));
-
-    AutoReleaseGeometry geo(this, 4, 0);
-    if (!geo.succeeded()) {
-        SkDebugf("Failed to get space for vertices!\n");
-        return;
-    }
-
-    size_t vstride = this->drawState()->getVertexStride();
-    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
-    if (localRect) {
-        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
-                                            sizeof(SkPoint));
-        coords->setRectFan(localRect->fLeft, localRect->fTop,
-                           localRect->fRight, localRect->fBottom,
-                           vstride);
-        if (localMatrix) {
-            localMatrix->mapPointsWithStride(coords, vstride, 4);
-        }
-    }
-    SkRect bounds;
-    this->getDrawState().getViewMatrix().mapRect(&bounds, rect);
-
-    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, &bounds);
-}
-
-void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 GrDrawTarget::AutoStateRestore::AutoStateRestore() {
     fDrawTarget = NULL;
 }
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 41f9b36..75a2f25 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -808,10 +808,6 @@
     GrContext* getContext() { return fContext; }
     const GrContext* getContext() const { return fContext; }
 
-    // A subclass may override this function if it wishes to be notified when the clip is changed.
-    // The override should call INHERITED::clipWillBeSet().
-    virtual void clipWillBeSet(const GrClipData* clipData);
-
     // subclasses must call this in their destructors to ensure all vertex
     // and index sources have been released (including those held by
     // pushGeometrySource())
@@ -855,15 +851,10 @@
     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
     // subclass called to perform drawing
     virtual void onDraw(const DrawInfo&, const GrClipMaskManager::ScissorState&) = 0;
-    // Implementation of drawRect. The geometry src and vertex attribs will already
-    // be saved before this is called and restored afterwards. A subclass may override
-    // this to perform more optimal rect rendering. Its draws should be funneled through
-    // one of the public GrDrawTarget draw methods (e.g. drawNonIndexed,
-    // drawIndexedInstances, ...). The base class draws a two triangle fan using
-    // drawNonIndexed from reserved vertex space.
+    // TODO copy in order drawbuffer onDrawRect to here
     virtual void onDrawRect(const SkRect& rect,
                             const SkRect* localRect,
-                            const SkMatrix* localMatrix);
+                            const SkMatrix* localMatrix) = 0;
 
     virtual void onStencilPath(const GrPath*,
                                const GrClipMaskManager::ScissorState&,
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 38994f1..c180cc6 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -8,6 +8,7 @@
 #include "GrInOrderDrawBuffer.h"
 
 #include "GrBufferAllocPool.h"
+#include "GrDefaultGeoProcFactory.h"
 #include "GrDrawTargetCaps.h"
 #include "GrGpu.h"
 #include "GrOptDrawState.h"
@@ -74,16 +75,6 @@
 }
 }
 
-
-namespace {
-
-extern const GrVertexAttrib kRectAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,                               kPosition_GrVertexAttribBinding},
-    {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                 kColor_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType,  sizeof(SkPoint)+sizeof(GrColor), kLocalCoord_GrVertexAttribBinding},
-};
-}
-
 /** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
     have explicit local coords and sometimes not. We *could* always provide explicit local coords
     and just duplicate the positions when the caller hasn't provided a local coord rect, but we
@@ -95,11 +86,11 @@
     The vertex attrib order is always pos, color, [local coords].
  */
 static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) {
-    if (hasLocalCoords) {
-        drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeof(SkColor));
-    } else {
-        drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
-    }
+    uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
+                     GrDefaultGeoProcFactory::kColor_GPType;
+    flags |= hasLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
+    drawState->setGeometryProcessor(GrDefaultGeoProcFactory::CreateAndSetAttribs(drawState,
+                                                                                 flags))->unref();
     if (0xFF == GrColorUnpackA(color)) {
         drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
     }
@@ -146,6 +137,7 @@
                                      const SkRect* localRect,
                                      const SkMatrix* localMatrix) {
     GrDrawState* drawState = this->drawState();
+    GrDrawState::AutoRestoreEffects are(drawState);
 
     GrColor color = drawState->getColor();
 
@@ -272,7 +264,6 @@
 
 void GrInOrderDrawBuffer::onDraw(const DrawInfo& info,
                                  const GrClipMaskManager::ScissorState& scissorState) {
-
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     const GrDrawState& drawState = this->getDrawState();
 
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index 0f2fcf0..24ba3a1 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -60,12 +60,11 @@
     this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &descInfo);
 
     // Copy GeometryProcesssor from DS or ODS
+    SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) ||
+             GrGpu::kStencilPath_DrawType ||
+             drawState.hasGeometryProcessor());
     if (drawState.hasGeometryProcessor()) {
         fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
-    } else if (!GrGpu::IsPathRenderingDrawType(drawType)) {
-        // Install default GP, this will be ignored if we are rendering with fragment shader only
-        // TODO(joshualitt) rendering code should do this
-        fGeometryProcessor.reset(GrDefaultGeoProcFactory::Create());
     } else {
         fGeometryProcessor.reset(NULL);
     }
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index bee7b87..af96ef6 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -10,20 +10,20 @@
 #include "../GrAARectRenderer.h"
 
 #include "GrGeometryProcessor.h"
-#include "gl/builders/GrGLProgramBuilder.h"
-#include "gl/GrGLProcessor.h"
-#include "gl/GrGLGeometryProcessor.h"
-#include "gl/GrGLSL.h"
 #include "GrContext.h"
 #include "GrCoordTransform.h"
+#include "GrDefaultGeoProcFactory.h"
 #include "GrDrawTarget.h"
 #include "GrDrawTargetCaps.h"
 #include "GrInvariantOutput.h"
 #include "GrProcessor.h"
-#include "GrGpu.h"
 #include "GrStrokeInfo.h"
 #include "GrTBackendProcessorFactory.h"
 #include "SkGr.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLSL.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -70,10 +70,6 @@
     SkPoint fDashPos;
 };
 
-extern const GrVertexAttrib gDashLineNoAAVertexAttribs[] = {
-    { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding }
-};
-
 extern const GrVertexAttrib gDashLineVertexAttribs[] = {
     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
     { kVec2f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
@@ -150,7 +146,6 @@
 
 static void setup_dashed_rect(const SkRect& rect, DashLineVertex* verts, int idx, const SkMatrix& matrix,
                        SkScalar offset, SkScalar bloat, SkScalar len, SkScalar stroke) {
-
         SkScalar startDashX = offset - bloat;
         SkScalar endDashX = offset + len + bloat;
         SkScalar startDashY = -stroke - bloat;
@@ -159,15 +154,21 @@
         verts[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY);
         verts[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY);
         verts[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY);
-
         verts[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop);
         verts[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom);
         verts[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom);
         verts[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop);
-
         matrix.mapPointsWithStride(&verts[idx].fPos, sizeof(DashLineVertex), 4);
 }
 
+static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& matrix,
+                                  SkPoint* verts) {
+    verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop);
+    verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom);
+    verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom);
+    verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop);
+    matrix.mapPoints(&verts[idx], 4);
+}
 
 bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint,
                                    const GrStrokeInfo& strokeInfo, GrGpu* gpu,
@@ -340,7 +341,8 @@
         }
         devIntervals[0] = lineLength;
     }
-    if (devIntervals[1] > 0.f || useAA) {
+    bool fullDash = devIntervals[1] > 0.f || useAA;
+    if (fullDash) {
         SkPathEffect::DashInfo devInfo;
         devInfo.fPhase = devPhase;
         devInfo.fCount = 2;
@@ -358,8 +360,10 @@
                                                             sizeof(DashLineVertex));
     } else {
         // Set up the vertex data for the line and start/end dashes
-        drawState->setVertexAttribs<gDashLineNoAAVertexAttribs>(
-                SK_ARRAY_COUNT(gDashLineNoAAVertexAttribs), sizeof(DashLineVertex));
+        drawState->setGeometryProcessor(
+                GrDefaultGeoProcFactory::CreateAndSetAttribs(
+                        drawState,
+                        GrDefaultGeoProcFactory::kPosition_GPType))->unref();
     }
 
     int totalRectCnt = 0;
@@ -374,8 +378,6 @@
         return false;
     }
 
-    DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
-
     int curVIdx = 0;
 
     if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) {
@@ -395,24 +397,44 @@
         SkRect bounds;
         bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY);
         bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke);
-        setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat,
-                          lineLength, halfDevStroke);
+        if (fullDash) {
+            DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
+            setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat,
+                                      lineLength, halfDevStroke);
+        } else {
+            SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
+            setup_dashed_rect_pos(bounds, curVIdx, combinedMatrix, verts);
+        }
         curVIdx += 4;
     }
 
     if (hasStartRect) {
         SkASSERT(useAA);  // so that we know bloatX and bloatY have been set
         startRect.outset(bloatX, bloatY);
-        setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
-                          devIntervals[0], halfDevStroke);
+        if (fullDash) {
+            DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
+            setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
+                              devIntervals[0], halfDevStroke);
+        } else {
+            SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
+            setup_dashed_rect_pos(startRect, curVIdx, combinedMatrix, verts);
+        }
+
         curVIdx += 4;
     }
 
     if (hasEndRect) {
         SkASSERT(useAA);  // so that we know bloatX and bloatY have been set
         endRect.outset(bloatX, bloatY);
-        setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
-                          devIntervals[0], halfDevStroke);
+        if (fullDash) {
+            DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());
+            setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
+                              devIntervals[0], halfDevStroke);
+        } else {
+            SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
+            setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts);
+        }
+
     }
 
     target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());