Move canvas helper structs to header

This is necessary cleanup before changing the type of the matrix and
clip stack. That work has landed and reverted several times, so landing
this piece separately, first.

Change-Id: I147e4cc4260fa5e07a0712503f879da120f8466a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/435278
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index db16b5b..34efd72 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -57,6 +57,7 @@
 class SkRegion;
 class SkRRect;
 struct SkRSXform;
+class SkSpecialImage;
 class SkSurface;
 class SkSurface_Base;
 class SkTextBlob;
@@ -2288,7 +2289,48 @@
     // operations should route to this device.
     SkBaseDevice* topDevice() const;
 
-    class MCRec;
+    // Canvases maintain a sparse stack of layers, where the top-most layer receives the drawing,
+    // clip, and matrix commands. There is a layer per call to saveLayer() using the
+    // kFullLayer_SaveLayerStrategy.
+    struct Layer {
+        sk_sp<SkBaseDevice>  fDevice;
+        sk_sp<SkImageFilter> fImageFilter; // applied to layer *before* being drawn by paint
+        SkPaint              fPaint;
+
+        Layer(sk_sp<SkBaseDevice> device, sk_sp<SkImageFilter> imageFilter, const SkPaint& paint);
+    };
+
+    // Encapsulate state needed to restore from saveBehind()
+    struct BackImage {
+        sk_sp<SkSpecialImage> fImage;
+        SkIPoint              fLoc;
+    };
+
+    class MCRec {
+    public:
+        // If not null, this MCRec corresponds with the saveLayer() record that made the layer.
+        // The base "layer" is not stored here, since it is stored inline in SkCanvas and has no
+        // restoration behavior.
+        std::unique_ptr<Layer> fLayer;
+
+        // This points to the device of the top-most layer (which may be lower in the stack), or
+        // to the canvas's fBaseDevice. The MCRec does not own the device.
+        SkBaseDevice* fDevice;
+
+        std::unique_ptr<BackImage> fBackImage;
+        SkM44 fMatrix;
+        int fDeferredSaveCount = 0;
+
+        MCRec(SkBaseDevice* device);
+        MCRec(const MCRec* prev);
+        ~MCRec();
+
+        void newLayer(sk_sp<SkBaseDevice> layerDevice,
+                      sk_sp<SkImageFilter> filter,
+                      const SkPaint& restorePaint);
+
+        void reset(SkBaseDevice* device);
+    };
 
     SkDeque     fMCStack;
     // points to top of stack
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 3ba13f1..f04a1c5 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -184,31 +184,6 @@
 
 namespace {
 
-// Canvases maintain a sparse stack of layers, where the top-most layer receives the drawing,
-// clip, and matrix commands. There is a layer per call to saveLayer() using the
-// kFullLayer_SaveLayerStrategy.
-struct Layer {
-    sk_sp<SkBaseDevice>  fDevice;
-    sk_sp<SkImageFilter> fImageFilter; // applied to layer *before* being drawn by paint
-    SkPaint              fPaint;
-
-    Layer(sk_sp<SkBaseDevice> device, sk_sp<SkImageFilter> imageFilter, const SkPaint& paint)
-            : fDevice(std::move(device))
-            , fImageFilter(std::move(imageFilter))
-            , fPaint(paint) {
-        SkASSERT(fDevice);
-        // Any image filter should have been pulled out and stored in 'imageFilter' so that 'paint'
-        // can be used as-is to draw the result of the filter to the dst device.
-        SkASSERT(!fPaint.getImageFilter());
-    }
-};
-
-// Encapsulate state needed to restore from saveBehind()
-struct BackImage {
-    sk_sp<SkSpecialImage> fImage;
-    SkIPoint              fLoc;
-};
-
 enum class CheckForOverwrite : bool {
     kNo = false,
     kYes = true
@@ -216,65 +191,43 @@
 
 }  // namespace
 
-/*  This is the record we keep for each save/restore level in the stack.
-    Since a level optionally copies the matrix and/or stack, we have pointers
-    for these fields. If the value is copied for this level, the copy is
-    stored in the ...Storage field, and the pointer points to that. If the
-    value is not copied for this level, we ignore ...Storage, and just point
-    at the corresponding value in the previous level in the stack.
-*/
-class SkCanvas::MCRec {
-public:
-    // If not null, this MCRec corresponds with the saveLayer() record that made the layer.
-    // The base "layer" is not stored here, since it is stored inline in SkCanvas and has no
-    // restoration behavior.
-    std::unique_ptr<Layer> fLayer;
+SkCanvas::Layer::Layer(sk_sp<SkBaseDevice> device,
+                       sk_sp<SkImageFilter> imageFilter,
+                       const SkPaint& paint)
+        : fDevice(std::move(device)), fImageFilter(std::move(imageFilter)), fPaint(paint) {
+    SkASSERT(fDevice);
+    // Any image filter should have been pulled out and stored in 'imageFilter' so that 'paint'
+    // can be used as-is to draw the result of the filter to the dst device.
+    SkASSERT(!fPaint.getImageFilter());
+}
 
-    // This points to the device of the top-most layer (which may be lower in the stack), or
-    // to the canvas's fBaseDevice. The MCRec does not own the device.
-    SkBaseDevice* fDevice;
+SkCanvas::MCRec::MCRec(SkBaseDevice* device) : fDevice(device) {
+    SkASSERT(fDevice);
+    inc_rec();
+}
 
-    std::unique_ptr<BackImage> fBackImage;
-    SkM44 fMatrix;
-    int fDeferredSaveCount;
+SkCanvas::MCRec::MCRec(const MCRec* prev) : fDevice(prev->fDevice), fMatrix(prev->fMatrix) {
+    SkASSERT(fDevice);
+    inc_rec();
+}
 
-    MCRec(SkBaseDevice* device)
-            : fLayer(nullptr)
-            , fDevice(device)
-            , fBackImage(nullptr)
-            , fDeferredSaveCount(0) {
-        SkASSERT(fDevice);
-        fMatrix.setIdentity();
-        inc_rec();
-    }
+SkCanvas::MCRec::~MCRec() { dec_rec(); }
 
-    MCRec(const MCRec& prev)
-            : fLayer(nullptr)
-            , fDevice(prev.fDevice)
-            , fMatrix(prev.fMatrix)
-            , fDeferredSaveCount(0) {
-        SkASSERT(fDevice);
-        inc_rec();
-    }
-    ~MCRec() {
-        dec_rec();
-    }
+void SkCanvas::MCRec::newLayer(sk_sp<SkBaseDevice> layerDevice,
+                               sk_sp<SkImageFilter> filter,
+                               const SkPaint& restorePaint) {
+    SkASSERT(!fBackImage);
+    fLayer = std::make_unique<Layer>(std::move(layerDevice), std::move(filter), restorePaint);
+    fDevice = fLayer->fDevice.get();
+}
 
-    void newLayer(sk_sp<SkBaseDevice> layerDevice, sk_sp<SkImageFilter> filter,
-                  const SkPaint& restorePaint) {
-        SkASSERT(!fBackImage);
-        fLayer = std::make_unique<Layer>(std::move(layerDevice), std::move(filter), restorePaint);
-        fDevice = fLayer->fDevice.get();
-    }
-
-    void reset(SkBaseDevice* device) {
-        SkASSERT(!fLayer);
-        SkASSERT(device);
-        SkASSERT(fDeferredSaveCount == 0);
-        fDevice = device;
-        fMatrix.setIdentity();
-    }
-};
+void SkCanvas::MCRec::reset(SkBaseDevice* device) {
+    SkASSERT(!fLayer);
+    SkASSERT(device);
+    SkASSERT(fDeferredSaveCount == 0);
+    fDevice = device;
+    fMatrix.setIdentity();
+}
 
 class SkCanvas::AutoUpdateQRBounds {
 public:
@@ -445,27 +398,21 @@
     fQuickRejectBounds = this->computeDeviceClipBounds();
 }
 
-SkCanvas::SkCanvas()
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
-    , fProps()
-{
+SkCanvas::SkCanvas() : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) {
     inc_canvas();
     this->init(nullptr);
 }
 
 SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
-    , fProps(SkSurfacePropsCopyOrDefault(props))
-{
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+        , fProps(SkSurfacePropsCopyOrDefault(props)) {
     inc_canvas();
     this->init(sk_make_sp<SkNoPixelsDevice>(
             SkIRect::MakeWH(std::max(width, 0), std::max(height, 0)), fProps));
 }
 
 SkCanvas::SkCanvas(const SkIRect& bounds)
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
-    , fProps()
-{
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) {
     inc_canvas();
 
     SkIRect r = bounds.isEmpty() ? SkIRect::MakeEmpty() : bounds;
@@ -473,30 +420,26 @@
 }
 
 SkCanvas::SkCanvas(sk_sp<SkBaseDevice> device)
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
-    , fProps(device->surfaceProps())
-{
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+        , fProps(device->surfaceProps()) {
     inc_canvas();
 
     this->init(device);
 }
 
 SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
-    , fProps(props)
-{
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)), fProps(props) {
     inc_canvas();
 
     sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, nullptr, nullptr));
     this->init(device);
 }
 
-SkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocator> alloc,
+SkCanvas::SkCanvas(const SkBitmap& bitmap,
+                   std::unique_ptr<SkRasterHandleAllocator> alloc,
                    SkRasterHandleAllocator::Handle hndl)
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
-    , fProps()
-    , fAllocator(std::move(alloc))
-{
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+        , fAllocator(std::move(alloc)) {
     inc_canvas();
 
     sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl, nullptr));
@@ -507,8 +450,7 @@
 
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
 SkCanvas::SkCanvas(const SkBitmap& bitmap, ColorBehavior)
-    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)), fProps(), fAllocator(nullptr)
-{
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) {
     inc_canvas();
 
     SkBitmap tmp(bitmap);
@@ -519,9 +461,7 @@
 #endif
 
 SkCanvas::~SkCanvas() {
-    // 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
 
     dec_canvas();
@@ -668,7 +608,7 @@
 }
 
 void SkCanvas::internalSave() {
-    fMCRec = new (fMCStack.push_back()) MCRec(*fMCRec);
+    fMCRec = new (fMCStack.push_back()) MCRec(fMCRec);
 
     this->topDevice()->save();
 }
@@ -1178,7 +1118,7 @@
 }
 
 void SkCanvas::internalRestore() {
-    SkASSERT(fMCStack.count() != 0);
+    SkASSERT(!fMCStack.empty());
 
     // now detach these from fMCRec so we can pop(). Gets freed after its drawn
     std::unique_ptr<Layer> layer = std::move(fMCRec->fLayer);
diff --git a/tools/MSKPPlayer.cpp b/tools/MSKPPlayer.cpp
index 3ba6ab3..7639dfd 100644
--- a/tools/MSKPPlayer.cpp
+++ b/tools/MSKPPlayer.cpp
@@ -75,7 +75,7 @@
 void MSKPPlayer::DrawLayerCmd::draw(SkCanvas* canvas,
                                     const LayerMap& layerMap,
                                     LayerStateMap* layerStateMap) const {
-    const Layer& layer = layerMap.at(fLayerId);
+    const LayerCmds& layer = layerMap.at(fLayerId);
     LayerState* layerState = &(*layerStateMap)[fLayerId];
     if (!layerState->fSurface) {
         layerState->fCurrCmd = 0;
@@ -119,7 +119,7 @@
 
 class MSKPPlayer::CmdRecordCanvas : public SkCanvasVirtualEnforcer<SkCanvas> {
 public:
-    CmdRecordCanvas(Layer* dst, LayerMap* offscreenLayers, const SkIRect* clipRect = nullptr)
+    CmdRecordCanvas(LayerCmds* dst, LayerMap* offscreenLayers, const SkIRect* clipRect = nullptr)
             : fDst(dst), fOffscreenLayers(offscreenLayers) {
         if (clipRect) {
             fClipRect = *clipRect;
@@ -332,7 +332,7 @@
         if (fNextDrawPictureToLayerID != -1) {
             SkASSERT(!matrix);
             SkASSERT(!paint);
-            Layer* layer = &fOffscreenLayers->at(fNextDrawPictureToLayerID);
+            LayerCmds* layer = &fOffscreenLayers->at(fNextDrawPictureToLayerID);
             CmdRecordCanvas sc(layer, fOffscreenLayers, &fNextDrawPictureToLayerClipRect);
             picture->playback(&sc);
             fNextDrawPictureToLayerID = -1;
@@ -371,7 +371,7 @@
     }
 
     SkPictureRecorder fRecorder; // accumulates draws until we draw an offscreen into this layer.
-    Layer*            fDst                            = nullptr;
+    LayerCmds*        fDst                            = nullptr;
     SkIRect           fClipRect                       = SkIRect::MakeEmpty();
     int               fNextDrawPictureToLayerID       = -1;
     SkIRect           fNextDrawPictureToLayerClipRect = SkIRect::MakeEmpty();
@@ -438,14 +438,14 @@
     }
 
     // Replay all the commands for this frame to the caller's canvas.
-    const Layer& layer = fRootLayers[i];
+    const LayerCmds& layer = fRootLayers[i];
     for (const auto& cmd : layer.fCmds) {
         cmd->draw(canvas, fOffscreenLayers, &fOffscreenLayerStates);
     }
     return true;
 }
 
-sk_sp<SkSurface> MSKPPlayer::MakeSurfaceForLayer(const Layer& layer, SkCanvas* rootCanvas) {
+sk_sp<SkSurface> MSKPPlayer::MakeSurfaceForLayer(const LayerCmds& layer, SkCanvas* rootCanvas) {
     // Assume layer has same surface props and info as this (mskp doesn't currently record this
     // data).
     SkSurfaceProps props;
@@ -497,7 +497,7 @@
     return iter->second.fSurface->makeImageSnapshot();
 }
 
-void MSKPPlayer::collectReferencedLayers(const Layer& layer, std::vector<int>* out) const {
+void MSKPPlayer::collectReferencedLayers(const LayerCmds& layer, std::vector<int>* out) const {
     for (const auto& cmd : layer.fCmds) {
         if (int id = cmd->layerID(); id >= 0) {
             // Linear, but we'd need to have a lot of layers to actually care.
diff --git a/tools/MSKPPlayer.h b/tools/MSKPPlayer.h
index 1b66852..e7014f6 100644
--- a/tools/MSKPPlayer.h
+++ b/tools/MSKPPlayer.h
@@ -95,9 +95,9 @@
     struct DrawLayerCmd;
 
     // The commands for a root/offscreen layer and dimensions of the layer.
-    struct Layer {
-        Layer() = default;
-        Layer(Layer&&) = default;
+    struct LayerCmds {
+        LayerCmds() = default;
+        LayerCmds(LayerCmds&&) = default;
         SkISize fDimensions;
         std::vector<std::unique_ptr<Cmd>> fCmds;
     };
@@ -108,19 +108,19 @@
         sk_sp<SkSurface> fSurface;
     };
 
-    static sk_sp<SkSurface> MakeSurfaceForLayer(const Layer&, SkCanvas* rootCanvas);
+    static sk_sp<SkSurface> MakeSurfaceForLayer(const LayerCmds&, SkCanvas* rootCanvas);
 
-    void collectReferencedLayers(const Layer& layer, std::vector<int>*) const;
+    void collectReferencedLayers(const LayerCmds& layer, std::vector<int>*) const;
 
-    // MSKP layer ID -> Layer
-    using LayerMap = std::unordered_map<int, Layer>;
+    // MSKP layer ID -> LayerCmds
+    using LayerMap = std::unordered_map<int, LayerCmds>;
     // MSKP layer ID -> LayerState
     using LayerStateMap = std::unordered_map<int, LayerState>;
 
     /**
      * A SkCanvas that consumes the SkPicture and records Cmds into a Layer. It will spawn
      * additional Layers and record nested SkPictures into those using additional CmdRecordCanvas
-     * CmdRecordCanvas instances. It needs access to fOffscreenLayers to create and update Layer
+     * CmdRecordCanvas instances. It needs access to fOffscreenLayers to create and update LayerCmds
      * structs for offscreen layers.
      */
     class CmdRecordCanvas;
@@ -129,7 +129,7 @@
     LayerMap           fOffscreenLayers;         // All the offscreen layers for all frames.
     LayerStateMap      fOffscreenLayerStates;    // Current surfaces and command idx for offscreen
                                                  // layers
-    std::vector<Layer> fRootLayers;              // One root layer for each frame.
+    std::vector<LayerCmds> fRootLayers;          // One root layer for each frame.
 };
 
 #endif