Add method to iterate over a GrOp's GrSurfaceProxies

The extra generality of having a std::function is for MDB reordering. In the current MDB reordering world there is one pass through the surfaceProxies at creation time and a second pass after flush to create the usage intervals.

Change-Id: I3f548417eddc1dad7503d919241301e404255ffe
Reviewed-on: https://skia-review.googlesource.com/46200
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 956093d..7528df3 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -33,6 +33,10 @@
         return analysis.requiresDstTexture() ? RequiresDstTexture::kYes : RequiresDstTexture::kNo;
     }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fProcessorSet.visitProxies(func);
+    }
+
 protected:
     BezierTestOp(sk_sp<GrGeometryProcessor> gp, const SkRect& rect, GrColor color, int32_t classID)
             : INHERITED(classID)
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index dcde104..ab9a4d0 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -42,12 +42,16 @@
 public:
     DEFINE_OP_CLASS_ID
 
-    const char* name() const override { return "PolyBoundsOp"; }
-
     static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkRect& rect) {
         return std::unique_ptr<GrDrawOp>(new PolyBoundsOp(std::move(paint), rect));
     }
 
+    const char* name() const override { return "PolyBoundsOp"; }
+
+    void visitProxies(VisitProxyFunc func) const override {
+        fProcessors.visitProxies(func);
+    }
+
     FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
 
     RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
diff --git a/src/gpu/GrAppliedClip.h b/src/gpu/GrAppliedClip.h
index bcf6eb9..e942baa 100644
--- a/src/gpu/GrAppliedClip.h
+++ b/src/gpu/GrAppliedClip.h
@@ -82,6 +82,12 @@
     }
     bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
 
+    void visitProxies(std::function<void(GrSurfaceProxy*)> func) const {
+        if (fClipCoverageFP) {
+            fClipCoverageFP->visitProxies(func);
+        }
+    }
+
 private:
     GrScissorState             fScissorState;
     GrWindowRectsState         fWindowRectsState;
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 8bf30d5..44a69f6 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -241,6 +241,13 @@
                                          &GrResourceIOProcessor::numTextureSamplers,
                                          &GrResourceIOProcessor::textureSampler>;
 
+    void visitProxies(std::function<void(GrSurfaceProxy*)> func) {
+        GrFragmentProcessor::TextureAccessIter iter(this);
+        while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
+            func(sampler->proxy());
+        }
+    }
+
 protected:
     enum OptimizationFlags : uint32_t {
         kNone_OptimizationFlags,
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 023c4df..67269eb 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -36,9 +36,6 @@
     int numCoverageFragmentProcessors() const {
         return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
     }
-    int numFragmentProcessors() const {
-        return fFragmentProcessors.count() - fFragmentProcessorOffset;
-    }
 
     const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
         SkASSERT(idx < fColorFragmentProcessorCnt);
@@ -155,9 +152,26 @@
 
     SkString dumpProcessors() const;
 
+    void visitProxies(std::function<void(GrSurfaceProxy*)> func) const {
+        for (int i = 0; i < this->numFragmentProcessors(); ++i) {
+            GrFragmentProcessor::TextureAccessIter iter(this->fragmentProcessor(i));
+            while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
+                func(sampler->proxy());
+            }
+        }
+    }
+
 private:
     GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
 
+    int numFragmentProcessors() const {
+        return fFragmentProcessors.count() - fFragmentProcessorOffset;
+    }
+
+    const GrFragmentProcessor* fragmentProcessor(int idx) const {
+        return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
+    }
+
     // This absurdly large limit allows Analysis and this to pack fields together.
     static constexpr int kMaxColorProcessors = UINT8_MAX;
 
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index ef4bdac..d80f667 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -68,12 +68,28 @@
     bool onExecute(GrOpFlushState* flushState) override;
 
     uint32_t addOp(std::unique_ptr<GrOp> op, const GrCaps& caps) {
+        auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) {
+            this->addDependency(p, caps);
+        };
+
+        op->visitProxies(addDependency);
+
         this->recordOp(std::move(op), caps, nullptr, nullptr);
+
         return this->uniqueID();
     }
+
     uint32_t addOp(std::unique_ptr<GrOp> op, const GrCaps& caps,
                    GrAppliedClip&& clip, const DstProxy& dstProxy) {
+        auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) {
+            this->addDependency(p, caps);
+        };
+
+        op->visitProxies(addDependency);
+        clip.visitProxies(addDependency);
+
         this->recordOp(std::move(op), caps, clip.doesClip() ? &clip : nullptr, &dstProxy);
+
         return this->uniqueID();
     }
 
diff --git a/src/gpu/instanced/InstancedOp.h b/src/gpu/instanced/InstancedOp.h
index 204a944..ae70e54 100644
--- a/src/gpu/instanced/InstancedOp.h
+++ b/src/gpu/instanced/InstancedOp.h
@@ -28,6 +28,10 @@
     ~InstancedOp() override;
     const char* name() const override { return "InstancedOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fProcessors.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.printf(
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 0fe7443..95b3907 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -733,6 +733,7 @@
 
 public:
     DEFINE_OP_CLASS_ID
+
     static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
                                           const SkPath& path,
                                           const GrUserStencilSettings* stencilSettings) {
@@ -750,6 +751,10 @@
 
     const char* name() const override { return "AAConvexPathOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Count: %d\n", fPaths.count());
diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp
index d0976a0..f371844 100644
--- a/src/gpu/ops/GrAAFillRectOp.cpp
+++ b/src/gpu/ops/GrAAFillRectOp.cpp
@@ -201,6 +201,10 @@
 
     const char* name() const override { return "AAFillRectOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString str;
         str.append(INHERITED::dumpInfo());
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index ba72eac..d5dfa2d 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -785,6 +785,10 @@
 
     const char* name() const override { return "AAHairlineOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Color: 0x%08x Coverage: 0x%02x, Count: %d\n", fColor, fCoverage,
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index d206951..5733cf2 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -177,6 +177,10 @@
 
     const char* name() const override { return "AAFlatteningConvexPathOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (const auto& path : fPaths) {
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index 07d8f30..a6a1f48 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -171,6 +171,10 @@
 
     const char* name() const override { return "AAStrokeRect"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (const auto& info : fRects) {
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index 58e0515..051c541 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -97,6 +97,17 @@
 
     const char* name() const override { return "AtlasTextOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fProcessors.visitProxies(func);
+
+        const sk_sp<GrTextureProxy>* proxies = fFontCache->getProxies(this->maskFormat());
+        for (int i = 0; i < kMaxTextures; ++i) {
+            if (proxies[i]) {
+                func(proxies[i].get());
+            }
+        }
+    }
+
     SkString dumpInfo() const override;
 
     FixedFunctionFlags fixedFunctionFlags() const override;
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index 14c15cb..8e2394b 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -243,6 +243,7 @@
 class DashOp final : public GrMeshDrawOp {
 public:
     DEFINE_OP_CLASS_ID
+
     struct LineData {
         SkMatrix fViewMatrix;
         SkMatrix fSrcRotInv;
@@ -263,6 +264,10 @@
 
     const char* name() const override { return "DashOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fProcessorSet.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (const auto& geo : fLines) {
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index 9741781..7c31f1e 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -343,6 +343,10 @@
 
     const char* name() const override { return "DefaultPathOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Color: 0x%08x Count: %d\n", fColor, fPaths.count());
diff --git a/src/gpu/ops/GrDrawAtlasOp.h b/src/gpu/ops/GrDrawAtlasOp.h
index 7c3bceb..1dc2386 100644
--- a/src/gpu/ops/GrDrawAtlasOp.h
+++ b/src/gpu/ops/GrDrawAtlasOp.h
@@ -33,6 +33,10 @@
 
     const char* name() const override { return "DrawAtlasOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override;
 
     FixedFunctionFlags fixedFunctionFlags() const override;
diff --git a/src/gpu/ops/GrDrawPathOp.h b/src/gpu/ops/GrDrawPathOp.h
index 2df5f34..98c3807 100644
--- a/src/gpu/ops/GrDrawPathOp.h
+++ b/src/gpu/ops/GrDrawPathOp.h
@@ -24,6 +24,7 @@
 protected:
     GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&&,
                      GrPathRendering::FillType, GrAAType);
+
     FixedFunctionFlags fixedFunctionFlags() const override {
         if (GrAATypeIsHW(fAAType)) {
             return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
@@ -35,6 +36,10 @@
                                                                           : RequiresDstTexture::kNo;
     }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fProcessorSet.visitProxies(func);
+    }
+
 protected:
     const SkMatrix& viewMatrix() const { return fViewMatrix; }
     GrColor color() const { return fInputColor; }
diff --git a/src/gpu/ops/GrDrawVerticesOp.h b/src/gpu/ops/GrDrawVerticesOp.h
index 4e12d2d..c2a5b45 100644
--- a/src/gpu/ops/GrDrawVerticesOp.h
+++ b/src/gpu/ops/GrDrawVerticesOp.h
@@ -46,6 +46,10 @@
 
     const char* name() const override { return "DrawVerticesOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override;
 
     FixedFunctionFlags fixedFunctionFlags() const override;
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index ba4733d..64983f4 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -60,6 +60,10 @@
 
     const char* name() const override { return "NonAALatticeOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString str;
 
diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp
index b80a811..bd9f14c 100644
--- a/src/gpu/ops/GrMSAAPathRenderer.cpp
+++ b/src/gpu/ops/GrMSAAPathRenderer.cpp
@@ -222,6 +222,7 @@
 
 public:
     DEFINE_OP_CLASS_ID
+
     static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkPath& path, GrAAType aaType,
                                           const SkMatrix& viewMatrix, const SkRect& devBounds,
                                           const GrUserStencilSettings* stencilSettings) {
@@ -243,6 +244,10 @@
 
     const char* name() const override { return "MSAAPathOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Indexed: %d\n", fIsIndexed);
diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp
index 07994aa..8b58fe5 100644
--- a/src/gpu/ops/GrNonAAFillRectOp.cpp
+++ b/src/gpu/ops/GrNonAAFillRectOp.cpp
@@ -139,6 +139,10 @@
 
     const char* name() const override { return "NonAAFillRectOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString str;
         str.append(GrMeshDrawOp::dumpInfo());
@@ -258,6 +262,10 @@
 
     const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString str;
         str.appendf("# combined: %d\n", fRects.count());
diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
index badcf07..de2f46e 100644
--- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
@@ -63,6 +63,10 @@
 
     const char* name() const override { return "NonAAStrokeRectOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf(
diff --git a/src/gpu/ops/GrOp.h b/src/gpu/ops/GrOp.h
index a87f8b6..70928b4 100644
--- a/src/gpu/ops/GrOp.h
+++ b/src/gpu/ops/GrOp.h
@@ -65,6 +65,12 @@
 
     virtual const char* name() const = 0;
 
+    typedef std::function<void(GrSurfaceProxy*)> VisitProxyFunc;
+
+    virtual void visitProxies(VisitProxyFunc) const {
+        // This default implementation assumes the op has no proxies
+    }
+
     bool combineIfPossible(GrOp* that, const GrCaps& caps) {
         if (this->classID() != that->classID()) {
             return false;
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index 5677bce..755acce 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -785,6 +785,10 @@
 
     const char* name() const override { return "CircleOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (int i = 0; i < fCircles.count(); ++i) {
@@ -1160,6 +1164,7 @@
 
 public:
     DEFINE_OP_CLASS_ID
+
     static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
                                           const SkRect& ellipse, const SkStrokeRec& stroke) {
         DeviceSpaceParams params;
@@ -1247,6 +1252,10 @@
 
     const char* name() const override { return "EllipseOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Stroked: %d\n", fStroked);
@@ -1473,6 +1482,10 @@
 
     const char* name() const override { return "DIEllipseOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (const auto& geo : fEllipses) {
@@ -1787,6 +1800,10 @@
 
     const char* name() const override { return "CircularRRectOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (int i = 0; i < fRRects.count(); ++i) {
@@ -2140,6 +2157,10 @@
 
     const char* name() const override { return "EllipticalRRectOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Stroked: %d\n", fStroked);
diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp
index f9cc61f..054bb81 100644
--- a/src/gpu/ops/GrRegionOp.cpp
+++ b/src/gpu/ops/GrRegionOp.cpp
@@ -79,6 +79,10 @@
 
     const char* name() const override { return "GrRegionOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString str;
         str.appendf("# combined: %d\n", fRegions.count());
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
index 9630f10..cf8763f 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
@@ -97,6 +97,12 @@
         friend class GrSimpleMeshDrawOpHelper;
     };
 
+    void visitProxies(std::function<void(GrSurfaceProxy*)> func) const {
+        if (fProcessors) {
+            fProcessors->visitProxies(func);
+        }
+    }
+
     SkString dumpInfo() const;
 
 protected:
@@ -127,6 +133,7 @@
 public:
     using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
     using Flags = GrSimpleMeshDrawOpHelper::Flags;
+    using GrSimpleMeshDrawOpHelper::visitProxies;
 
     // using declarations can't be templated, so this is a pass through function instead.
     template <typename Op, typename... OpArgs>
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 1c3cbe9..8be6922 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -192,6 +192,17 @@
 
     const char* name() const override { return "SmallPathOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+
+        const sk_sp<GrTextureProxy>* proxies = fAtlas->getProxies();
+        for (int i = 0; i < GrDrawOpAtlas::kMaxPages; ++i) {
+            if (proxies[i].get()) {
+                func(proxies[i].get());
+            }
+        }
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         for (const auto& geo : fShapes) {
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index c56a9eb..9acaffa 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -177,6 +177,10 @@
 
     const char* name() const override { return "TessellatingPathOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     SkString dumpInfo() const override {
         SkString string;
         string.appendf("Color 0x%08x, aa: %d\n", fColor, fAntiAlias);
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 0415d9d..92278d1 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -245,6 +245,13 @@
 
     const char* name() const override { return "TextureOp"; }
 
+    void visitProxies(VisitProxyFunc func) const override {
+        auto proxies = this->proxies();
+        for (int i = 0; i < fProxyCnt; ++i) {
+            func(proxies[i]);
+        }
+    }
+
     SkString dumpInfo() const override {
         SkString str;
         str.appendf("AllowSRGBInputs: %d\n", fAllowSRGBInputs);
@@ -482,6 +489,7 @@
             for (int i = 0; i < that->fProxyCnt; ++i) {
                 if (map[i] < 0) {
                     thatProxies[i]->addPendingRead();
+
                     thisProxies[-map[i]] = thatProxies[i];
                     thisFilters[-map[i]] = thatFilters[i];
                     map[i] = -map[i];
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index b26dd68..a8fdc7c 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -29,7 +29,6 @@
 
 public:
     DEFINE_OP_CLASS_ID
-    const char* name() const override { return "NonAARectOp"; }
 
     // This creates an instance of a simple non-AA solid color rect-drawing Op
     static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkRect& r) {
@@ -57,6 +56,12 @@
         this->setBounds(r, HasAABloat::kYes, IsZeroArea::kYes);
     }
 
+    const char* name() const override { return "NonAARectOp"; }
+
+    void visitProxies(VisitProxyFunc func) const override {
+        fHelper.visitProxies(func);
+    }
+
     FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
 
     RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip*) override {