In SkCanvas destructor, discard (rather than blit) unbalanced layers

Bug: skia:12267
Change-Id: I6808f62b2385a3466b1a93db905041a6529f58cb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/433360
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Florin Malita <fmalita@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index f04a1c5..fee3a82 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -461,6 +461,17 @@
 #endif
 
 SkCanvas::~SkCanvas() {
+    // Discard all pending layers
+    SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart);
+    for (;;) {
+        MCRec* rec = (MCRec*)iter.next();
+        if (!rec) {
+            break;
+        }
+        rec->fLayer.reset();
+    }
+
+    // free up the contents of our deque
     this->restoreToCount(1);    // restore everything but the last
     this->internalRestore();    // restore the last, since we're going away
 
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index 0f41c7d..df79b11 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -752,7 +752,10 @@
         const SkPMColor pmc = SkPreMultiplyColor(expected);
         for (int y = 0; y < pm.info().height(); ++y) {
             for (int x = 0; x < pm.info().width(); ++x) {
-                REPORTER_ASSERT(reporter, *pm.addr32(x, y) == pmc);
+                if (*pm.addr32(x, y) != pmc) {
+                    ERRORF(reporter, "check_pixels_failed");
+                    return;
+                }
             }
         }
     };
@@ -766,7 +769,7 @@
 
         canvas->saveLayer(nullptr, nullptr);
         canvas->clear(SK_ColorBLUE);
-        // so far, we still expect to see the red
+        // so far, we still expect to see the red, since the blue was drawn in a layer
         check_pixels(SK_ColorRED);
 
         if (doRestore) {
@@ -781,7 +784,7 @@
 
     // Now we're repeat that, but delete the canvas before we restore it
     do_test(false);
-    // *if* we restore the layers in the destructor, we expect to see blue, even though
-    // we didn't call restore() as a client.
-    check_pixels(SK_ColorBLUE);
+    // We now suppress blitting the unbalanced saveLayers, so we expect to see red
+    // (not the layer's blue)
+    check_pixels(SK_ColorRED);
 }