Respect xfer barriers in InstancedRendering::Op

Fixes a bug introduced when this Op stopped storing a GrPipeline.

Change-Id: I1a39814cebe18b321ea369f005bb7759f233cfe6
Reviewed-on: https://skia-review.googlesource.com/10804
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index 21b20c7..8bdf6b6 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -149,6 +149,8 @@
     fIgnoresInputColor = SkToBool(props & GrXPFactory::AnalysisProperties::kIgnoresInputColor);
     fCompatibleWithCoverageAsAlpha &=
             SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithAlphaAsCoverage);
+    fRequiresBarrierBetweenOverlappingDraws = SkToBool(
+            props & GrXPFactory::AnalysisProperties::kRequiresBarrierBetweenOverlappingDraws);
     if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
         fInitialColorProcessorsToEliminate = processors.numColorFragmentProcessors();
         // If the output of the last color stage is known then the kIgnoresInputColor optimization
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index f63369c..39ba013 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -82,6 +82,7 @@
                 , fRequiresDstTexture(false)
                 , fCanCombineOverlappedStencilAndCover(true)
                 , fIgnoresInputColor(false)
+                , fRequiresBarrierBetweenOverlappingDraws(false)
                 , fOutputCoverageType(static_cast<unsigned>(GrProcessorAnalysisCoverage::kNone))
                 , fOutputColorType(static_cast<unsigned>(ColorType::kUnknown))
                 , fInitialColorProcessorsToEliminate(0) {}
@@ -126,6 +127,9 @@
         bool canCombineOverlappedStencilAndCover() const {
             return fCanCombineOverlappedStencilAndCover;
         }
+        bool requiresBarrierBetweenOverlappingDraws() const {
+            return fRequiresBarrierBetweenOverlappingDraws;
+        }
         bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
         bool isInputColorIgnored() const { return fIgnoresInputColor; }
         GrProcessorAnalysisCoverage outputCoverage() const {
@@ -163,10 +167,11 @@
         PackedBool fCanCombineOverlappedStencilAndCover : 1;
         // These could be removed if we created the XP from the XPFactory when doing analysis.
         PackedBool fIgnoresInputColor : 1;
+        PackedBool fRequiresBarrierBetweenOverlappingDraws : 1;
         unsigned fOutputCoverageType : 2;
         unsigned fOutputColorType : 2;
 
-        unsigned fInitialColorProcessorsToEliminate : 32 - 11;
+        unsigned fInitialColorProcessorsToEliminate : 32 - 12;
 
         GrColor fInputColor;
         // This could be removed if we created the XP from the XPFactory when doing analysis.
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index 1ce258c..839fea6 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -185,6 +185,9 @@
     if ((result & AnalysisProperties::kReadsDstInShader) &&
         !caps.shaderCaps()->dstReadInShaderSupport()) {
         result |= AnalysisProperties::kRequiresDstTexture;
+        if (caps.textureBarrierSupport()) {
+            result |= AnalysisProperties::kRequiresBarrierBetweenOverlappingDraws;
+        }
     }
     return result;
 }
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index 622f760..596e849 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -272,11 +272,33 @@
 
     enum class AnalysisProperties : unsigned {
         kNone = 0x0,
+        /**
+         * The fragment shader will require the destination color.
+         */
         kReadsDstInShader = 0x1,
-        kRequiresDstTexture = 0x2,
-        kCompatibleWithAlphaAsCoverage = 0x4,
-        kIgnoresInputColor = 0x8,
-        kCanCombineOverlappedStencilAndCover = 0x10
+        /**
+         * The op may apply coverage as alpha and still blend correctly.
+         */
+        kCompatibleWithAlphaAsCoverage = 0x2,
+        /**
+         * The color input to the GrXferProcessor will be ignored.
+         */
+        kIgnoresInputColor = 0x4,
+        /**
+         * If set overlapping stencil and cover operations can be replaced by a combined stencil
+         * followed by a combined cover.
+         */
+        kCanCombineOverlappedStencilAndCover = 0x8,
+        /**
+         * The destination color will be provided to the fragment processor using a texture. This is
+         * additional information about the implementation of kReadsDstInShader.
+         */
+        kRequiresDstTexture = 0x10,
+        /**
+         * If set overlapping draws may not be combined because a barrier must be inserted between
+         * them.
+         */
+        kRequiresBarrierBetweenOverlappingDraws = 0x20,
     };
     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties);
 
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 5ac31d8..5f21c75 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -344,7 +344,12 @@
           = blend(f*Sa, Da)
     */
     if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
-        return AnalysisProperties::kCompatibleWithAlphaAsCoverage;
+        if (caps.blendEquationSupport() == GrCaps::kAdvancedCoherent_BlendEquationSupport) {
+            return AnalysisProperties::kCompatibleWithAlphaAsCoverage;
+        } else {
+            return AnalysisProperties::kCompatibleWithAlphaAsCoverage |
+                   AnalysisProperties::kRequiresBarrierBetweenOverlappingDraws;
+        }
     }
     return AnalysisProperties::kCompatibleWithAlphaAsCoverage |
            AnalysisProperties::kReadsDstInShader;
diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp
index ad61eb6..4abaef6 100644
--- a/src/gpu/instanced/InstancedRendering.cpp
+++ b/src/gpu/instanced/InstancedRendering.cpp
@@ -234,6 +234,7 @@
         , fInstancedRendering(ir)
         , fProcessors(std::move(paint))
         , fIsTracked(false)
+        , fRequiresBarrierOnOverlap(false)
         , fNumDraws(1)
         , fNumChangesInGeometry(0) {
     fHeadDraw = fTailDraw = fInstancedRendering->fDrawPool.allocate();
@@ -370,6 +371,7 @@
     fInfo.fCannotTweakAlphaForCoverage = !analysis.isCompatibleWithCoverageAsAlpha();
 
     fInfo.fUsesLocalCoords = analysis.usesLocalCoords();
+    fRequiresBarrierOnOverlap = analysis.requiresBarrierBetweenOverlappingDraws();
     return analysis.requiresDstTexture();
 }
 
@@ -390,6 +392,10 @@
         return false;
     }
 
+    SkASSERT(fRequiresBarrierOnOverlap == that->fRequiresBarrierOnOverlap);
+    if (fRequiresBarrierOnOverlap && this->bounds().intersects(that->bounds())) {
+        return false;
+    }
     OpInfo combinedInfo = fInfo | that->fInfo;
     if (!combinedInfo.isSimpleRects()) {
         // This threshold was chosen with the "shapes_mixed" bench on a MacBook with Intel graphics.
diff --git a/src/gpu/instanced/InstancedRendering.h b/src/gpu/instanced/InstancedRendering.h
index caff08f..3ec8214 100644
--- a/src/gpu/instanced/InstancedRendering.h
+++ b/src/gpu/instanced/InstancedRendering.h
@@ -153,7 +153,8 @@
         GrProcessorSet fProcessors;
         GrProcessorAnalysisColor fAnalysisColor;
         SkSTArray<5, ParamsTexel, true> fParams;
-        bool fIsTracked;
+        bool fIsTracked : 1;
+        bool fRequiresBarrierOnOverlap : 1;
         int fNumDraws;
         int fNumChangesInGeometry;
         Draw* fHeadDraw;