[graphite] Make sure we are flushing work from the Device when needed.

Specifically this adds flushing of the Device when the Device is deleted
and also when we snap a Recording, we flush all Devices connected to a
Recorder.

Bug: skia:12633
Change-Id: Idfecc8cd2a0ecf6a8d39fc81618dd6b13ec87ec2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/494243
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/experimental/graphite/src/Device.cpp b/experimental/graphite/src/Device.cpp
index 534df2b..9c675ab 100644
--- a/experimental/graphite/src/Device.cpp
+++ b/experimental/graphite/src/Device.cpp
@@ -159,6 +159,7 @@
 
 Device::~Device() {
     if (fRecorder) {
+        this->flushPendingWorkToRecorder();
         fRecorder->deregisterDevice(this);
     }
 }
@@ -452,6 +453,8 @@
 }
 
 void Device::flushPendingWorkToRecorder() {
+    SkASSERT(fRecorder);
+
     // TODO: we may need to further split this function up since device->device drawList and
     // DrawPass stealing will need to share some of the same logic w/o becoming a Task.
 
diff --git a/experimental/graphite/src/Device.h b/experimental/graphite/src/Device.h
index 1bf526c..49504d0 100644
--- a/experimental/graphite/src/Device.h
+++ b/experimental/graphite/src/Device.h
@@ -43,6 +43,10 @@
     // when the Recorder is abandoned or deleted.
     void abandonRecorder();
 
+    // Ensures clip elements are drawn that will clip previous draw calls, snaps all pending work
+    // from the DrawContext as a RenderPassTask and records it in the Device's recorder.
+    void flushPendingWorkToRecorder();
+
     bool readPixels(Context*, const SkPixmap& dst, int x, int y);
 
 private:
@@ -163,10 +167,6 @@
     std::pair<Clip, CompressedPaintersOrder>
     applyClipToDraw(const Transform&, const Shape&, const SkStrokeRec&, PaintersDepth z);
 
-    // Ensures clip elements are drawn that will clip previous draw calls, snaps all pending work
-    // from the DrawContext as a RenderPassTask and records it in the Device's recorder.
-    void flushPendingWorkToRecorder();
-
     bool needsFlushBeforeDraw(int numNewDraws) const;
 
     Recorder* fRecorder;
diff --git a/experimental/graphite/src/Recorder.cpp b/experimental/graphite/src/Recorder.cpp
index d57b7a7..ff3d2da 100644
--- a/experimental/graphite/src/Recorder.cpp
+++ b/experimental/graphite/src/Recorder.cpp
@@ -51,6 +51,10 @@
 }
 
 std::unique_ptr<Recording> Recorder::snap() {
+    for (auto& device : fTrackedDevices) {
+        device->flushPendingWorkToRecorder();
+    }
+
     auto gpu = fContext->priv().gpu();
     auto commandBuffer = gpu->resourceProvider()->createCommandBuffer();