Remove SkCanvas::LayerIter used in SkCanvasStateUtils

The LayerIter existed to iterate over the top-most device and any
unclipped layers connected to it. With unclipped layers gone,
SkCanvasStateUtils can just access the top-most device using other
APIs.

Bug: skia:10986
Change-Id: I260ec37fcc8e39d1ec2972a3297521d714649cb5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/339991
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
diff --git a/src/utils/SkCanvasStateUtils.cpp b/src/utils/SkCanvasStateUtils.cpp
index d0b9239..8f208d3 100644
--- a/src/utils/SkCanvasStateUtils.cpp
+++ b/src/utils/SkCanvasStateUtils.cpp
@@ -163,8 +163,6 @@
     }
 }
 
-
-
 SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
     SkASSERT(canvas);
 
@@ -177,51 +175,53 @@
 
     setup_MC_state(&canvasState->mcState, canvas->getTotalMatrix(), canvas->getDeviceClipBounds());
 
-    /*
-     * decompose the layers
-     *
-     * storage is allocated on the stack for the first 3 layers. It is common in
-     * some view systems (e.g. Android) that a few non-clipped layers are present
-     * and we will not need to malloc any additional memory in those cases.
-     */
-    SkSWriter32<3*sizeof(SkCanvasLayerState)> layerWriter;
-    int layerCount = 0;
-    for (SkCanvas::LayerIter layer(canvas); !layer.done(); layer.next()) {
-
-        // we currently only work for bitmap backed devices
-        SkPixmap pmap;
-        if (!layer.device()->accessPixels(&pmap) || 0 == pmap.width() || 0 == pmap.height()) {
-            return nullptr;
-        }
-
-        SkCanvasLayerState* layerState =
-                (SkCanvasLayerState*) layerWriter.reserve(sizeof(SkCanvasLayerState));
-        layerState->type = kRaster_CanvasBackend;
-        layerState->x = layer.x();
-        layerState->y = layer.y();
-        layerState->width = pmap.width();
-        layerState->height = pmap.height();
-
-        switch (pmap.colorType()) {
-            case kN32_SkColorType:
-                layerState->raster.config = kARGB_8888_RasterConfig;
-                break;
-            case kRGB_565_SkColorType:
-                layerState->raster.config = kRGB_565_RasterConfig;
-                break;
-            default:
-                return nullptr;
-        }
-        layerState->raster.rowBytes = pmap.rowBytes();
-        layerState->raster.pixels = pmap.writable_addr();
-
-        setup_MC_state(&layerState->mcState, layer.matrix(), layer.clipBounds());
-        layerCount++;
+    // Historically, the canvas state could report multiple top-level layers because SkCanvas
+    // supported unclipped layers. With that feature removed, there is only ever 0 to 1 "layers",
+    // and all required information is contained by the canvas' top-most device.
+    SkBaseDevice* device = canvas->getTopDevice();
+    if (!device) {
+        return nullptr;
     }
 
+    SkSWriter32<sizeof(SkCanvasLayerState)> layerWriter;
+    // we currently only work for bitmap backed devices
+    SkPixmap pmap;
+    if (!device->accessPixels(&pmap) || 0 == pmap.width() || 0 == pmap.height()) {
+        return nullptr;
+    }
+    // and for axis-aligned devices (so not transformed for an image filter)
+    if (!device->isPixelAlignedToGlobal()) {
+        return nullptr;
+    }
+
+    SkIPoint origin = device->getOrigin(); // safe since it's pixel aligned
+
+    SkCanvasLayerState* layerState =
+            (SkCanvasLayerState*) layerWriter.reserve(sizeof(SkCanvasLayerState));
+    layerState->type = kRaster_CanvasBackend;
+    layerState->x = origin.x();
+    layerState->y = origin.y();
+    layerState->width = pmap.width();
+    layerState->height = pmap.height();
+
+    switch (pmap.colorType()) {
+        case kN32_SkColorType:
+            layerState->raster.config = kARGB_8888_RasterConfig;
+            break;
+        case kRGB_565_SkColorType:
+            layerState->raster.config = kRGB_565_RasterConfig;
+            break;
+        default:
+            return nullptr;
+    }
+    layerState->raster.rowBytes = pmap.rowBytes();
+    layerState->raster.pixels = pmap.writable_addr();
+
+    setup_MC_state(&layerState->mcState, device->localToDevice(), device->devClipBounds());
+
     // allocate memory for the layers and then and copy them to the struct
-    SkASSERT(layerWriter.bytesWritten() == layerCount * sizeof(SkCanvasLayerState));
-    canvasState->layerCount = layerCount;
+    SkASSERT(layerWriter.bytesWritten() == sizeof(SkCanvasLayerState));
+    canvasState->layerCount = 1;
     canvasState->layers = (SkCanvasLayerState*) sk_malloc_throw(layerWriter.bytesWritten());
     layerWriter.flatten(canvasState->layers);
 
@@ -302,7 +302,9 @@
     // setup the matrix and clip on the n-way canvas
     setup_canvas_from_MC_state(state_v1->mcState, canvas.get());
 
-    // Iterate over the layers and add them to the n-way canvas
+    // Iterate over the layers and add them to the n-way canvas. New clients will only send one
+    // layer since unclipped layers are no longer supported, but old canvas clients may still
+    // create them.
     for (int i = state_v1->layerCount - 1; i >= 0; --i) {
         std::unique_ptr<SkCanvas> canvasLayer = make_canvas_from_canvas_layer(state_v1->layers[i]);
         if (!canvasLayer) {