Fix dangling pointers when Ganesh culls CCPR Ops early

BUG=chromium:775868

Change-Id: I0066e34fd8ebe4b46ad72481f5bb955dc0dd5910
Reviewed-on: https://skia-review.googlesource.com/67682
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/tests/GrCCPRTest.cpp b/tests/GrCCPRTest.cpp
index f56298b..b8e3db9 100644
--- a/tests/GrCCPRTest.cpp
+++ b/tests/GrCCPRTest.cpp
@@ -154,6 +154,28 @@
 };
 DEF_CCPR_TEST(GrCCPRTest_cleanup)
 
+class GrCCPRTest_unregisterCulledOps : public CCPRTest {
+    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
+        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+
+        // Ensure Ops get unregistered from CCPR when culled early.
+        ccpr.drawPath(fPath);
+        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
+        ccpr.clear(); // Clear should delete the CCPR Op.
+        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+        ccpr.flush(); // Should not crash (DrawPathsOp should have unregistered itself).
+
+        // Ensure Op unregisters work when we delete the context without flushing.
+        ccpr.drawPath(fPath);
+        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
+        ccpr.clear(); // Clear should delete the CCPR DrawPathsOp.
+        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+        ccpr.abandonGrContext();
+        fMockContext.reset(); // Should not crash (DrawPathsOp should have unregistered itself).
+    }
+};
+DEF_CCPR_TEST(GrCCPRTest_unregisterCulledOps)
+
 class CCPRRenderingTest {
 public:
     void run(skiatest::Reporter* reporter, GrContext* ctx) const {