New API for computing optimization invariants.

Review URL: https://codereview.chromium.org/1467553002
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index aee18b7..79296e3 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -752,29 +752,30 @@
 
     const char* name() const override { return "AAConvexBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
-    }
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = false;
     }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fGeoData[0].fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
+        fBatch.fColorIgnored = !overrides.readsColor();
         fBatch.fColor = fGeoData[0].fColor;
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
         fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSegmentMasks();
-        fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
+        fBatch.fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
     }
 
     void prepareLinesOnlyDraws(Target* target) {
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index bb388d7..80fd542 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -154,26 +154,26 @@
 
     const char* name() const override { return "AADistanceFieldPathBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
-        out->setKnownFourComponents(fBatch.fColor);
-    }
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
+        color->setKnownFourComponents(fBatch.fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = false;
     }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fBatch.fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fBatch.fColor);
+        overrides.getOverrideColorIfSet(&fBatch.fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fColorIgnored = !overrides.readsColor();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
     }
 
     struct FlushInfo {
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp
index e2b088c..9ec8ffd 100644
--- a/src/gpu/batches/GrAAFillRectBatch.cpp
+++ b/src/gpu/batches/GrAAFillRectBatch.cpp
@@ -46,7 +46,7 @@
 
 static const GrGeometryProcessor* create_fill_rect_gp(
                                        const SkMatrix& viewMatrix,
-                                       const GrPipelineOptimizations& opts,
+                                       const GrXPOverridesForBatch& overrides,
                                        GrDefaultGeoProcFactory::LocalCoords::Type localCoordsType) {
     using namespace GrDefaultGeoProcFactory;
 
@@ -55,7 +55,7 @@
     // TODO remove coverage if coverage is ignored
     /*if (coverageIgnored) {
         coverageType = Coverage::kNone_Type;
-    } else*/ if (opts.canTweakAlphaForCoverage()) {
+    } else*/ if (overrides.canTweakAlphaForCoverage()) {
         coverageType = Coverage::kSolid_Type;
     } else {
         coverageType = Coverage::kAttribute_Type;
@@ -67,8 +67,8 @@
         LocalCoords localCoords(localCoordsType);
         return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
     } else {
-        LocalCoords localCoords(opts.readsLocalCoords() ? localCoordsType :
-                                                          LocalCoords::kUnused_Type);
+        LocalCoords localCoords(overrides.readsLocalCoords() ? localCoordsType :
+                                                               LocalCoords::kUnused_Type);
         return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
     }
 }
@@ -79,7 +79,7 @@
                                            const SkMatrix& viewMatrix,
                                            const SkRect& rect,
                                            const SkRect& devRect,
-                                           const GrPipelineOptimizations& opts,
+                                           const GrXPOverridesForBatch& overrides,
                                            const SkMatrix* localMatrix) {
     SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
     SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
@@ -140,7 +140,7 @@
         localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
     }
 
-    bool tweakAlphaForCoverage = opts.canTweakAlphaForCoverage();
+    bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
 
     // Make verts point to vertex color and then set all the color and coverage vertex attrs
     // values.
@@ -227,20 +227,20 @@
     }
 
     static bool CanCombine(const Geometry& mine, const Geometry& theirs,
-                           const GrPipelineOptimizations& opts) {
+                           const GrXPOverridesForBatch& overrides) {
         // We apply the viewmatrix to the rect points on the cpu.  However, if the pipeline uses
         // local coords then we won't be able to batch.  We could actually upload the viewmatrix
         // using vertex attributes in these cases, but haven't investigated that
-        return !opts.readsLocalCoords() || mine.fViewMatrix.cheapEqualTo(theirs.fViewMatrix);
+        return !overrides.readsLocalCoords() || mine.fViewMatrix.cheapEqualTo(theirs.fViewMatrix);
     }
 
     static const GrGeometryProcessor* CreateGP(const Geometry& geo,
-                                               const GrPipelineOptimizations& opts) {
+                                               const GrXPOverridesForBatch& overrides) {
         const GrGeometryProcessor* gp =
-                create_fill_rect_gp(geo.fViewMatrix, opts,
+                create_fill_rect_gp(geo.fViewMatrix, overrides,
                                     GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type);
 
-        SkASSERT(opts.canTweakAlphaForCoverage() ?
+        SkASSERT(overrides.canTweakAlphaForCoverage() ?
                  gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
                  gp->getVertexStride() ==
                          sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
@@ -248,10 +248,10 @@
     }
 
     static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
-                          const GrPipelineOptimizations& opts) {
+                          const GrXPOverridesForBatch& overrides) {
         generate_aa_fill_rect_geometry(vertices, vertexStride,
-                                       geo.fColor, geo.fViewMatrix, geo.fRect, geo.fDevRect, opts,
-                                       nullptr);
+                                       geo.fColor, geo.fViewMatrix, geo.fRect, geo.fDevRect, 
+                                       overrides, nullptr);
     }
 };
 
@@ -277,17 +277,17 @@
     }
 
     static bool CanCombine(const Geometry& mine, const Geometry& theirs,
-                           const GrPipelineOptimizations&) {
+                           const GrXPOverridesForBatch& overrides) {
         return true;
     }
 
     static const GrGeometryProcessor* CreateGP(const Geometry& geo,
-                                               const GrPipelineOptimizations& opts) {
+                                               const GrXPOverridesForBatch& overrides) {
         const GrGeometryProcessor* gp =
-                create_fill_rect_gp(geo.fViewMatrix, opts,
+                create_fill_rect_gp(geo.fViewMatrix, overrides,
                                     GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type);
 
-        SkASSERT(opts.canTweakAlphaForCoverage() ?
+        SkASSERT(overrides.canTweakAlphaForCoverage() ?
                  gp->getVertexStride() ==
                          sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
                  gp->getVertexStride() ==
@@ -296,10 +296,10 @@
     }
 
     static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
-                          const GrPipelineOptimizations& opts) {
+                          const GrXPOverridesForBatch& overrides) {
         generate_aa_fill_rect_geometry(vertices, vertexStride,
-                                       geo.fColor, geo.fViewMatrix, geo.fRect, geo.fDevRect, opts,
-                                       &geo.fLocalMatrix);
+                                       geo.fColor, geo.fViewMatrix, geo.fRect, geo.fDevRect, 
+                                       overrides, &geo.fLocalMatrix);
     }
 };
 
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index d17ed09..fd579f2 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -686,27 +686,28 @@
 
     const char* name() const override { return "AAHairlineBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
-    }
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = true;
     }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fGeoData[0].fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
+        fBatch.fColorIgnored = !overrides.readsColor();
         fBatch.fColor = fGeoData[0].fColor;
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
         fBatch.fCoverage = fGeoData[0].fCoverage;
     }
 
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index 659f9d4..295bcb1 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -135,29 +135,30 @@
 
     const char* name() const override { return "AAConvexBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
-    }
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = false;
     }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fGeoData[0].fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
+        fBatch.fColorIgnored = !overrides.readsColor();
         fBatch.fColor = fGeoData[0].fColor;
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
         fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSegmentMasks();
-        fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
+        fBatch.fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
     }
 
     void draw(GrVertexBatch::Target* target, const GrPipeline* pipeline, int vertexCount,
diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp
index 9addc2f..419964f 100644
--- a/src/gpu/batches/GrAAStrokeRectBatch.cpp
+++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp
@@ -62,13 +62,13 @@
 
     const char* name() const override { return "AAStrokeRect"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
-    }
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = false;
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -108,7 +108,7 @@
     }
 
     void onPrepareDraws(Target*) override;
-    void initBatchTracker(const GrPipelineOptimizations&) override;
+    void initBatchTracker(const GrXPOverridesForBatch&) override;
 
     AAStrokeRectBatch(const SkMatrix& viewMatrix,bool miterStroke)
         : INHERITED(ClassID()) {
@@ -167,19 +167,19 @@
     typedef GrVertexBatch INHERITED;
 };
 
-void AAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
+void AAStrokeRectBatch::initBatchTracker(const GrXPOverridesForBatch& overrides) {
     // Handle any color overrides
-    if (!opt.readsColor()) {
+    if (!overrides.readsColor()) {
         fGeoData[0].fColor = GrColor_ILLEGAL;
     }
-    opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+    overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
     // setup batch properties
-    fBatch.fColorIgnored = !opt.readsColor();
+    fBatch.fColorIgnored = !overrides.readsColor();
     fBatch.fColor = fGeoData[0].fColor;
-    fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-    fBatch.fCoverageIgnored = !opt.readsCoverage();
-    fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
+    fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+    fBatch.fCoverageIgnored = !overrides.readsCoverage();
+    fBatch.fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
 }
 
 void AAStrokeRectBatch::onPrepareDraws(Target* target) {
diff --git a/src/gpu/batches/GrAtlasTextBatch.cpp b/src/gpu/batches/GrAtlasTextBatch.cpp
index 710b155..ac5ec11 100644
--- a/src/gpu/batches/GrAtlasTextBatch.cpp
+++ b/src/gpu/batches/GrAtlasTextBatch.cpp
@@ -240,42 +240,41 @@
     return str;
 }
 
-void GrAtlasTextBatch::getInvariantOutputColor(GrInitInvariantOutput* out) const {
+void GrAtlasTextBatch::computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                                    GrInitInvariantOutput* coverage,
+                                                    GrBatchToXPOverrides* overrides) const {
     if (kColorBitmapMask_MaskType == fMaskType) {
-        out->setUnknownFourComponents();
+        color->setUnknownFourComponents();
     } else {
-        out->setKnownFourComponents(fBatch.fColor);
+        color->setKnownFourComponents(fBatch.fColor);
     }
-}
-
-void GrAtlasTextBatch::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
     switch (fMaskType) {
         case kGrayscaleDistanceField_MaskType:
         case kGrayscaleCoverageMask_MaskType:
-            out->setUnknownSingleComponent();
+            coverage->setUnknownSingleComponent();
             break;
         case kLCDCoverageMask_MaskType:
         case kLCDDistanceField_MaskType:
-            out->setUnknownOpaqueFourComponents();
-            out->setUsingLCDCoverage();
+            coverage->setUnknownOpaqueFourComponents();
+            coverage->setUsingLCDCoverage();
             break;
         case kColorBitmapMask_MaskType:
-            out->setKnownSingleComponent(0xff);
+            coverage->setKnownSingleComponent(0xff);
     }
 }
 
-void GrAtlasTextBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
+void GrAtlasTextBatch::initBatchTracker(const GrXPOverridesForBatch& overrides) {
     // Handle any color overrides
-    if (!opt.readsColor()) {
+    if (!overrides.readsColor()) {
         fGeoData[0].fColor = GrColor_ILLEGAL;
     }
-    opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+    overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
     // setup batch properties
-    fBatch.fColorIgnored = !opt.readsColor();
+    fBatch.fColorIgnored = !overrides.readsColor();
     fBatch.fColor = fGeoData[0].fColor;
-    fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-    fBatch.fCoverageIgnored = !opt.readsCoverage();
+    fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+    fBatch.fCoverageIgnored = !overrides.readsCoverage();
 }
 
 enum RegenMask {
diff --git a/src/gpu/batches/GrAtlasTextBatch.h b/src/gpu/batches/GrAtlasTextBatch.h
index 5997d49..1e6d953 100644
--- a/src/gpu/batches/GrAtlasTextBatch.h
+++ b/src/gpu/batches/GrAtlasTextBatch.h
@@ -102,10 +102,6 @@
 
     SkString dumpInfo() const override;
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override;
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override;
-
     static size_t GetVertexStride(GrMaskFormat maskFormat) {
         switch (maskFormat) {
             case kA8_GrMaskFormat:
@@ -126,8 +122,14 @@
         }
     }
 
+protected:
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override;
+
+
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override;
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override;
 
     struct FlushInfo {
         SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index fa2ffe0..23f9fc8 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -227,27 +227,28 @@
 
     const char* name() const override { return "DefaultPathBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
-    }
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setKnownSingleComponent(this->coverage());
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        coverage->setKnownSingleComponent(this->coverage());
+        overrides->fUsePLSDstRead = false;
     }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fGeoData[0].fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
+        fBatch.fColorIgnored = !overrides.readsColor();
         fBatch.fColor = fGeoData[0].fColor;
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
     }
 
     void onPrepareDraws(Target* target) override {
diff --git a/src/gpu/batches/GrDrawAtlasBatch.cpp b/src/gpu/batches/GrDrawAtlasBatch.cpp
index 5ecdc1f..3ee8f88 100644
--- a/src/gpu/batches/GrDrawAtlasBatch.cpp
+++ b/src/gpu/batches/GrDrawAtlasBatch.cpp
@@ -12,13 +12,13 @@
 #include "SkRandom.h"
 #include "SkRSXform.h"
 
-void GrDrawAtlasBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
+void GrDrawAtlasBatch::initBatchTracker(const GrXPOverridesForBatch& overrides) {
     SkASSERT(fGeoData.count() == 1);
     // Handle any color overrides
-    if (!opt.readsColor()) {
+    if (!overrides.readsColor()) {
         fGeoData[0].fColor = GrColor_ILLEGAL;
     }
-    if (opt.getOverrideColorIfSet(&fGeoData[0].fColor) && fHasColors) {
+    if (overrides.getOverrideColorIfSet(&fGeoData[0].fColor) && fHasColors) {
         size_t vertexStride = sizeof(SkPoint) + sizeof(SkPoint) +
                              (this->hasColors() ? sizeof(GrColor) : 0);
         uint8_t* currVertex = fGeoData[0].fVerts.begin();
@@ -29,11 +29,11 @@
     }
 
     // setup batch properties
-    fColorIgnored = !opt.readsColor();
+    fColorIgnored = !overrides.readsColor();
     fColor = fGeoData[0].fColor;
     // We'd like to assert this, but we can't because of GLPrograms test
     //SkASSERT(init.readsLocalCoords());
-    fCoverageIgnored = !opt.readsCoverage();
+    fCoverageIgnored = !overrides.readsCoverage();
 }
 
 static const GrGeometryProcessor* set_vertex_attributes(bool hasColors,
diff --git a/src/gpu/batches/GrDrawAtlasBatch.h b/src/gpu/batches/GrDrawAtlasBatch.h
index de128f2..3c0c348 100644
--- a/src/gpu/batches/GrDrawAtlasBatch.h
+++ b/src/gpu/batches/GrDrawAtlasBatch.h
@@ -29,17 +29,17 @@
     
     const char* name() const override { return "DrawAtlasBatch"; }
     
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
         if (this->hasColors()) {
-            out->setUnknownFourComponents();
+            color->setUnknownFourComponents();
         } else {
-            out->setKnownFourComponents(fGeoData[0].fColor);
+            color->setKnownFourComponents(fGeoData[0].fColor);
         }
-    }
-    
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setKnownSingleComponent(0xff);
+        coverage->setKnownSingleComponent(0xff);
+        overrides->fUsePLSDstRead = false;
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -47,7 +47,7 @@
 private:
     void onPrepareDraws(Target*) override;
 
-    void initBatchTracker(const GrPipelineOptimizations&) override;
+    void initBatchTracker(const GrXPOverridesForBatch&) override;
 
     GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, int spriteCount,
                      const SkRSXform* xforms, const SkRect* rects, const SkColor* colors);
diff --git a/src/gpu/batches/GrDrawBatch.cpp b/src/gpu/batches/GrDrawBatch.cpp
index 43ef2ec..4253923 100644
--- a/src/gpu/batches/GrDrawBatch.cpp
+++ b/src/gpu/batches/GrDrawBatch.cpp
@@ -15,13 +15,21 @@
     }
 }
 
+void GrDrawBatch::getPipelineOptimizations(GrPipelineOptimizations* opt) const {
+    GrInitInvariantOutput color;
+    GrInitInvariantOutput coverage;
+    this->computePipelineOptimizations(&color, &coverage, &opt->fOverrides);
+    opt->fColorPOI.initUsingInvariantOutput(color);
+    opt->fCoveragePOI.initUsingInvariantOutput(coverage);
+}
+
 bool GrDrawBatch::installPipeline(const GrPipeline::CreateArgs& args) {
-    GrPipelineOptimizations opts;
+    GrXPOverridesForBatch overrides;
     void* location = fPipelineStorage.get();
-    if (!GrPipeline::CreateAt(location, args, &opts)) {
+    if (!GrPipeline::CreateAt(location, args, &overrides)) {
         return false;
     }
-    this->initBatchTracker(opts);
+    this->initBatchTracker(overrides);
     fPipelineInstalled = true;
     return true;
 }
diff --git a/src/gpu/batches/GrDrawBatch.h b/src/gpu/batches/GrDrawBatch.h
index b5def69..8e73878 100644
--- a/src/gpu/batches/GrDrawBatch.h
+++ b/src/gpu/batches/GrDrawBatch.h
@@ -43,8 +43,10 @@
     GrDrawBatch(uint32_t classID);
     ~GrDrawBatch() override;
 
-    virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
-    virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
+    /**
+     * Fills in a structure informing the XP of overrides to its normal behavior.
+     */
+    void getPipelineOptimizations(GrPipelineOptimizations* override) const;
 
     const GrPipeline* pipeline() const {
         SkASSERT(fPipelineInstalled);
@@ -80,12 +82,17 @@
         return string;
     }
 
+protected:
+    virtual void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                              GrInitInvariantOutput* coverage,
+                                              GrBatchToXPOverrides* overrides) const = 0;
+
 private:
     /**
      * initBatchTracker is a hook for the some additional overrides / optimization possibilities
      * from the GrXferProcessor.
      */
-    virtual void initBatchTracker(const GrPipelineOptimizations&) = 0;
+    virtual void initBatchTracker(const GrXPOverridesForBatch&) = 0;
 
 protected:
     SkTArray<SkAutoTUnref<GrBatchUploader>, true>   fInlineUploads;
diff --git a/src/gpu/batches/GrDrawPathBatch.cpp b/src/gpu/batches/GrDrawPathBatch.cpp
index a829378..5209f90 100644
--- a/src/gpu/batches/GrDrawPathBatch.cpp
+++ b/src/gpu/batches/GrDrawPathBatch.cpp
@@ -17,7 +17,7 @@
     GrProgramDesc  desc;
 
     SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
-                                                                   this->opts(),
+                                                                   this->overrides(),
                                                                    this->viewMatrix()));
     state->gpu()->buildProgramDesc(&desc, *pathProc, *this->pipeline());
     GrPathRendering::DrawPathArgs args(pathProc, this->pipeline(),
@@ -92,10 +92,10 @@
     // combined. (Glyphs in the same font tend to wind the same direction so it works out OK.)
     if (!this->isWinding() ||
         this->stencilSettings() != that->stencilSettings() ||
-        this->opts().willColorBlendWithDst()) {
+        this->overrides().willColorBlendWithDst()) {
         return false;
     }
-    SkASSERT(!that->opts().willColorBlendWithDst());
+    SkASSERT(!that->overrides().willColorBlendWithDst());
     fTotalPathCount += that->fTotalPathCount;
     while (GrPathRangeDraw** head = that->fDraws.head()) {
         fDraws.addToTail(*head);
@@ -108,7 +108,7 @@
 void GrDrawPathRangeBatch::onDraw(GrBatchFlushState* state) {
     GrProgramDesc  desc;
     SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
-                                                                   this->opts(),
+                                                                   this->overrides(),
                                                                    this->viewMatrix(),
                                                                    fLocalMatrix));
     state->gpu()->buildProgramDesc(&desc, *pathProc, *this->pipeline());
diff --git a/src/gpu/batches/GrDrawPathBatch.h b/src/gpu/batches/GrDrawPathBatch.h
index 2c166c1..4067c80 100644
--- a/src/gpu/batches/GrDrawPathBatch.h
+++ b/src/gpu/batches/GrDrawPathBatch.h
@@ -19,12 +19,12 @@
 
 class GrDrawPathBatchBase : public GrDrawBatch {
 public:
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
-        out->setKnownFourComponents(fColor);
-    }
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setKnownSingleComponent(0xff);
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
+        color->setKnownFourComponents(fColor);
+        coverage->setKnownSingleComponent(0xff);
+        overrides->fUsePLSDstRead = false;
     }
 
     void setStencilSettings(const GrStencilSettings& stencil) { fStencilSettings = stencil; }
@@ -36,20 +36,20 @@
         , fColor(initialColor) {}
 
     const GrStencilSettings& stencilSettings() const { return fStencilSettings; }
-    const GrPipelineOptimizations& opts() const { return fOpts; }
+    const GrXPOverridesForBatch& overrides() const { return fOverrides; }
     const SkMatrix& viewMatrix() const { return fViewMatrix; }
     GrColor color() const { return fColor; }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opts) override {
-        opts.getOverrideColorIfSet(&fColor);
-        fOpts = opts;
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
+        overrides.getOverrideColorIfSet(&fColor);
+        fOverrides = overrides;
     }
 
     SkMatrix                                                fViewMatrix;
     GrColor                                                 fColor;
     GrStencilSettings                                       fStencilSettings;
-    GrPipelineOptimizations                                 fOpts;
+    GrXPOverridesForBatch                                   fOverrides;
 
     typedef GrDrawBatch INHERITED;
 };
diff --git a/src/gpu/batches/GrDrawVerticesBatch.cpp b/src/gpu/batches/GrDrawVerticesBatch.cpp
index 16c70e8..cc5ccbd 100644
--- a/src/gpu/batches/GrDrawVerticesBatch.cpp
+++ b/src/gpu/batches/GrDrawVerticesBatch.cpp
@@ -65,29 +65,29 @@
     this->setBounds(bounds);
 }
 
-void GrDrawVerticesBatch::getInvariantOutputColor(GrInitInvariantOutput* out) const {
+void GrDrawVerticesBatch::computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                                       GrInitInvariantOutput* coverage,
+                                                       GrBatchToXPOverrides* overrides) const {
     // When this is called on a batch, there is only one geometry bundle
     if (fVariableColor) {
-        out->setUnknownFourComponents();
+        color->setUnknownFourComponents();
     } else {
-        out->setKnownFourComponents(fGeoData[0].fColor);
+        color->setKnownFourComponents(fGeoData[0].fColor);
     }
+    coverage->setKnownSingleComponent(0xff);
+    overrides->fUsePLSDstRead = false;
 }
 
-void GrDrawVerticesBatch::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
-    out->setKnownSingleComponent(0xff);
-}
-
-void GrDrawVerticesBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
+void GrDrawVerticesBatch::initBatchTracker(const GrXPOverridesForBatch& overrides) {
     SkASSERT(fGeoData.count() == 1);
     GrColor overrideColor;
-    if (opt.getOverrideColorIfSet(&overrideColor)) {
+    if (overrides.getOverrideColorIfSet(&overrideColor)) {
         fGeoData[0].fColor = overrideColor;
         fGeoData[0].fColors.reset();
         fVariableColor = false;
     }
-    fCoverageIgnored = !opt.readsCoverage();
-    if (!opt.readsLocalCoords()) {
+    fCoverageIgnored = !overrides.readsCoverage();
+    if (!overrides.readsLocalCoords()) {
         fGeoData[0].fLocalCoords.reset();
     }
 }
diff --git a/src/gpu/batches/GrDrawVerticesBatch.h b/src/gpu/batches/GrDrawVerticesBatch.h
index 8503b01..33647df 100644
--- a/src/gpu/batches/GrDrawVerticesBatch.h
+++ b/src/gpu/batches/GrDrawVerticesBatch.h
@@ -42,15 +42,15 @@
 
     const char* name() const override { return "DrawVerticesBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override;
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override;
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override;
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
 
 private:
     void onPrepareDraws(Target*) override;
-    void initBatchTracker(const GrPipelineOptimizations&) override;
+    void initBatchTracker(const GrXPOverridesForBatch&) override;
 
     GrDrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType,
                         const SkMatrix& viewMatrix,
diff --git a/src/gpu/batches/GrNinePatch.cpp b/src/gpu/batches/GrNinePatch.cpp
index 999e1fd..b438919 100644
--- a/src/gpu/batches/GrNinePatch.cpp
+++ b/src/gpu/batches/GrNinePatch.cpp
@@ -74,19 +74,19 @@
         return str;
     }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
-        out->setUnknownFourComponents();
-    }
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setKnownSingleComponent(0xff);
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
+        color->setUnknownFourComponents();
+        coverage->setKnownSingleComponent(0xff);
+        overrides->fUsePLSDstRead = false;
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
 
 private:
     void onPrepareDraws(Target* target) override {
-        SkAutoTUnref<const GrGeometryProcessor> gp(create_gp(fOpts.readsCoverage()));
+        SkAutoTUnref<const GrGeometryProcessor> gp(create_gp(fOverrides.readsCoverage()));
         if (!gp) {
             SkDebugf("Couldn't create GrGeometryProcessor\n");
             return;
@@ -142,9 +142,9 @@
         helper.recordDraw(target);
     }
 
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
-        fOpts = opt;
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
+        fOverrides = overrides;
     }
 
     bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
@@ -159,8 +159,8 @@
 
         // In the event of two batches, one who can tweak, one who cannot, we just fall back to
         // not tweaking
-        if (fOpts.canTweakAlphaForCoverage() && !that->fOpts.canTweakAlphaForCoverage()) {
-            fOpts = that->fOpts;
+        if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) {
+            fOverrides = that->fOverrides;
         }
 
         fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
@@ -168,7 +168,7 @@
         return true;
     }
 
-    GrPipelineOptimizations fOpts;
+    GrXPOverridesForBatch fOverrides;
     int fImageWidth;
     int fImageHeight;
     SkSTArray<1, Geometry, true> fGeoData;
diff --git a/src/gpu/batches/GrNonAAFillRectBatch.cpp b/src/gpu/batches/GrNonAAFillRectBatch.cpp
index 5f37741..0964344 100644
--- a/src/gpu/batches/GrNonAAFillRectBatch.cpp
+++ b/src/gpu/batches/GrNonAAFillRectBatch.cpp
@@ -134,13 +134,13 @@
     }
 
     static bool CanCombine(const Geometry& mine, const Geometry& theirs,
-                           const GrPipelineOptimizations& opts) {
+                           const GrXPOverridesForBatch& overrides) {
         return true;
     }
 
     static const GrGeometryProcessor* CreateGP(const Geometry& geo,
-                                               const GrPipelineOptimizations& opts) {
-        const GrGeometryProcessor* gp = create_gp(geo.fViewMatrix, opts.readsCoverage(), true,
+                                               const GrXPOverridesForBatch& overrides) {
+        const GrGeometryProcessor* gp = create_gp(geo.fViewMatrix, overrides.readsCoverage(), true,
                                                   nullptr);
 
         SkASSERT(gp->getVertexStride() ==
@@ -149,7 +149,7 @@
     }
 
     static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
-                          const GrPipelineOptimizations& opts) {
+                          const GrXPOverridesForBatch& overrides) {
         tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, &geo.fLocalQuad);
     }
 };
@@ -179,7 +179,7 @@
     }
 
     static bool CanCombine(const Geometry& mine, const Geometry& theirs,
-                           const GrPipelineOptimizations& opts) {
+                           const GrXPOverridesForBatch& overrides) {
         // We could batch across perspective vm changes if we really wanted to
         return mine.fViewMatrix.cheapEqualTo(theirs.fViewMatrix) &&
                mine.fHasLocalRect == theirs.fHasLocalRect &&
@@ -187,8 +187,8 @@
     }
 
     static const GrGeometryProcessor* CreateGP(const Geometry& geo,
-                                               const GrPipelineOptimizations& opts) {
-        const GrGeometryProcessor* gp = create_gp(geo.fViewMatrix, opts.readsCoverage(),
+                                               const GrXPOverridesForBatch& overrides) {
+        const GrGeometryProcessor* gp = create_gp(geo.fViewMatrix, overrides.readsCoverage(),
                                                   geo.fHasLocalRect,
                                                   geo.fHasLocalMatrix ? &geo.fLocalMatrix :
                                                                         nullptr);
@@ -200,7 +200,7 @@
     }
 
     static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
-                          const GrPipelineOptimizations& opts) {
+                          const GrXPOverridesForBatch& overrides) {
         if (geo.fHasLocalRect) {
             GrQuad quad(geo.fLocalRect);
             tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, &quad);
diff --git a/src/gpu/batches/GrNonAAStrokeRectBatch.cpp b/src/gpu/batches/GrNonAAStrokeRectBatch.cpp
index a5de607..2f80884 100644
--- a/src/gpu/batches/GrNonAAStrokeRectBatch.cpp
+++ b/src/gpu/batches/GrNonAAStrokeRectBatch.cpp
@@ -54,13 +54,13 @@
 
     const char* name() const override { return "GrStrokeRectBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
-    }
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setKnownSingleComponent(0xff);
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        coverage->setKnownSingleComponent(0xff);
+        overrides->fUsePLSDstRead = false;
     }
 
     void append(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
@@ -162,18 +162,18 @@
         target->draw(vertices);
     }
 
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fGeoData[0].fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
+        fBatch.fColorIgnored = !overrides.readsColor();
         fBatch.fColor = fGeoData[0].fColor;
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
     }
 
     NonAAStrokeRectBatch() : INHERITED(ClassID()) {}
diff --git a/src/gpu/batches/GrTInstanceBatch.h b/src/gpu/batches/GrTInstanceBatch.h
index 5dc5988..d2d4d6c 100644
--- a/src/gpu/batches/GrTInstanceBatch.h
+++ b/src/gpu/batches/GrTInstanceBatch.h
@@ -29,15 +29,15 @@
  *     void UpdateBoundsAfterAppend(const Geometry& lastGeometry, SkRect* currentBounds)
  *
  *     bool CanCombine(const Geometry& mine, const Geometry& theirs,
- *                     const GrPipelineOptimizations&)
+ *                     const GrXPOverridesForBatch&)
  *
  *     const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry,
- *                                         const GrPipelineOptimizations& opts)
+ *                                         const GrXPOverridesForBatch& overrides)
  *
  *     const GrIndexBuffer* GetIndexBuffer(GrResourceProvider*)
  *
  *     Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
- *               const GrPipelineOptimizations& opts)
+ *               const GrXPOverridesForBatch& overrides)
  */
 template <typename Impl>
 class GrTInstanceBatch : public GrVertexBatch {
@@ -59,18 +59,18 @@
         return str;
     }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(fGeoData[0].fColor);
+        color->setKnownFourComponents(fGeoData[0].fColor);
+        Impl::InitInvariantOutputCoverage(coverage);
+        overrides->fUsePLSDstRead = false;
     }
 
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        Impl::InitInvariantOutputCoverage(out);
-    }
-
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
-        opt.getOverrideColorIfSet(&fGeoData[0].fColor);
-        fOpts = opt;
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
+        overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
+        fOverrides = overrides;
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -90,7 +90,8 @@
     GrTInstanceBatch() : INHERITED(ClassID()) {}
 
     void onPrepareDraws(Target* target) override {
-        SkAutoTUnref<const GrGeometryProcessor> gp(Impl::CreateGP(this->seedGeometry(), fOpts));
+        SkAutoTUnref<const GrGeometryProcessor> gp(Impl::CreateGP(this->seedGeometry(), 
+                                                                  fOverrides));
         if (!gp) {
             SkDebugf("Couldn't create GrGeometryProcessor\n");
             return;
@@ -115,7 +116,7 @@
         for (int i = 0; i < instanceCount; i++) {
             intptr_t verts = reinterpret_cast<intptr_t>(vertices) +
                              i * Impl::kVertsPerInstance * vertexStride;
-            Impl::Tesselate(verts, vertexStride, fGeoData[i], fOpts);
+            Impl::Tesselate(verts, vertexStride, fGeoData[i], fOverrides);
         }
         helper.recordDraw(target);
     }
@@ -129,14 +130,14 @@
             return false;
         }
 
-        if (!Impl::CanCombine(this->seedGeometry(), that->seedGeometry(), fOpts)) {
+        if (!Impl::CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides)) {
             return false;
         }
 
         // In the event of two batches, one who can tweak, one who cannot, we just fall back to
         // not tweaking
-        if (fOpts.canTweakAlphaForCoverage() && !that->fOpts.canTweakAlphaForCoverage()) {
-            fOpts = that->fOpts;
+        if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) {
+            fOverrides = that->fOverrides;
         }
 
         fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
@@ -144,7 +145,7 @@
         return true;
     }
 
-    GrPipelineOptimizations fOpts;
+    GrXPOverridesForBatch fOverrides;
     SkSTArray<1, Geometry, true> fGeoData;
 
     typedef GrVertexBatch INHERITED;
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index a3a8883..8cd411a 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -1397,22 +1397,22 @@
 
     const char* name() const override { return "TessellatingPathBatch"; }
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
-        out->setKnownFourComponents(fColor);
-    }
-
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
+        color->setKnownFourComponents(fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = false;
     }
 
 private:
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&fColor);
-        fPipelineInfo = opt;
+        overrides.getOverrideColorIfSet(&fColor);
+        fPipelineInfo = overrides;
     }
 
     int tessellate(GrUniqueKey* key,
@@ -1621,7 +1621,7 @@
     GrStrokeInfo            fStroke;
     SkMatrix                fViewMatrix;
     SkRect                  fClipBounds; // in source space
-    GrPipelineOptimizations fPipelineInfo;
+    GrXPOverridesForBatch   fPipelineInfo;
 
     typedef GrVertexBatch INHERITED;
 };
diff --git a/src/gpu/batches/GrTestBatch.h b/src/gpu/batches/GrTestBatch.h
index 02881c9..b070bba 100644
--- a/src/gpu/batches/GrTestBatch.h
+++ b/src/gpu/batches/GrTestBatch.h
@@ -26,27 +26,27 @@
 
     virtual const char* name() const override = 0;
 
-    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+    void computePipelineOptimizations(GrInitInvariantOutput* color, 
+                                      GrInitInvariantOutput* coverage,
+                                      GrBatchToXPOverrides* overrides) const override {
         // When this is called on a batch, there is only one geometry bundle
-        out->setKnownFourComponents(this->geoData(0)->fColor);
+        color->setKnownFourComponents(this->geoData(0)->fColor);
+        coverage->setUnknownSingleComponent();
+        overrides->fUsePLSDstRead = false;
     }
 
-    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
-        out->setUnknownSingleComponent();
-    }
-
-    void initBatchTracker(const GrPipelineOptimizations& opt) override {
+    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
         // Handle any color overrides
-        if (!opt.readsColor()) {
+        if (!overrides.readsColor()) {
             this->geoData(0)->fColor = GrColor_ILLEGAL;
         }
-        opt.getOverrideColorIfSet(&this->geoData(0)->fColor);
+        overrides.getOverrideColorIfSet(&this->geoData(0)->fColor);
 
         // setup batch properties
-        fBatch.fColorIgnored = !opt.readsColor();
+        fBatch.fColorIgnored = !overrides.readsColor();
         fBatch.fColor = this->geoData(0)->fColor;
-        fBatch.fUsesLocalCoords = opt.readsLocalCoords();
-        fBatch.fCoverageIgnored = !opt.readsCoverage();
+        fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
+        fBatch.fCoverageIgnored = !overrides.readsCoverage();
     }
 
 protected: