SkSurface copy-on-write can yield stale GPU render targets.

Prepare_rt_for_external_access() grabs the render target and then fires
access notifications.

But the notification handlers may trigger copy-on-write, causing the
returned render target to be stale (pointing at the detached snapshot).

We should grab the render target after firing notifications.

R=reed@google.com,bsalomon@google.com

Review URL: https://codereview.chromium.org/1276713002
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 192abd7..157ccf6 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -622,6 +622,19 @@
     }
 }
 
+static void test_backend_cow(skiatest::Reporter* reporter, SkSurface* surface,
+                             SkSurface::BackendHandleAccess mode,
+                             GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
+    GrBackendObject obj1 = func(surface, mode);
+    SkAutoTUnref<SkImage> snap1(surface->newImageSnapshot());
+
+    GrBackendObject obj2 = func(surface, mode);
+    SkAutoTUnref<SkImage> snap2(surface->newImageSnapshot());
+
+    // If the access mode triggers CoW, then the backend objects should reflect it.
+    REPORTER_ASSERT(reporter, (obj1 == obj2) == (snap1 == snap2));
+}
+
 static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType,
                                    GrContext* context) {
     // Verify that the right canvas commands trigger a copy on write
@@ -700,6 +713,28 @@
         testPaint))
     EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, NULL, \
         testPaint))
+
+    const SkSurface::BackendHandleAccess accessModes[] = {
+        SkSurface::kFlushRead_BackendHandleAccess,
+        SkSurface::kFlushWrite_BackendHandleAccess,
+        SkSurface::kDiscardWrite_BackendHandleAccess,
+    };
+
+    for (auto access : accessModes) {
+        test_backend_cow(reporter, surface, access,
+                          [](SkSurface* s, SkSurface::BackendHandleAccess a) -> GrBackendObject {
+            return s->getTextureHandle(a);
+        });
+
+        test_backend_cow(reporter, surface, access,
+                          [](SkSurface* s, SkSurface::BackendHandleAccess a) -> GrBackendObject {
+            GrBackendObject result;
+            if (!s->getRenderTargetHandle(&result, a)) {
+                return 0;
+            }
+            return result;
+        });
+    }
 }
 
 static void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter,