change signature for virtual related to saveLayer, passing SaveLayerRec

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1533953002

NOTREECHECKS=True

Review URL: https://codereview.chromium.org/1533953002
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 003a96c..bf52d1c 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -391,6 +391,27 @@
     SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
     int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, SaveFlags flags);
 
+    enum {
+        kIsOpaque_SaveLayerFlag         = 1 << 0,
+        kPreserveLCDText_SaveLayerFlag  = 1 << 1,
+    };
+    typedef uint32_t SaveLayerFlags;
+
+    struct SaveLayerRec {
+        SaveLayerRec() : fBounds(nullptr), fPaint(nullptr), fSaveLayerFlags(0) {}
+        SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
+            : fBounds(bounds)
+            , fPaint(paint)
+            , fSaveLayerFlags(saveLayerFlags)
+        {}
+
+        const SkRect*   fBounds;    // optional
+        const SkPaint*  fPaint;     // optional
+        SaveLayerFlags  fSaveLayerFlags;
+    };
+
+    int saveLayer(const SaveLayerRec&);
+
     /** This call balances a previous call to save(), and is used to remove all
         modifications to the matrix/clip/drawFilter state since the last save
         call.
@@ -1217,16 +1238,24 @@
 
     // Subclass save/restore notifiers.
     // Overriders should call the corresponding INHERITED method up the inheritance chain.
-    // willSaveLayer()'s return value may suppress full layer allocation.
+    // getSaveLayerStrategy()'s return value may suppress full layer allocation.
     enum SaveLayerStrategy {
         kFullLayer_SaveLayerStrategy,
-        kNoLayer_SaveLayerStrategy
+        kNoLayer_SaveLayerStrategy,
     };
 
     virtual void willSave() {}
+#ifdef SK_SUPPORT_LEGACY_SAVELAYERPARAMS
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) {
         return kFullLayer_SaveLayerStrategy;
     }
+    virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&);
+#else
+    // Overriders should call the corresponding INHERITED method up the inheritance chain.
+    virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) {
+        return kFullLayer_SaveLayerStrategy;
+    }
+#endif
     virtual void willRestore() {}
     virtual void didRestore() {}
     virtual void didConcat(const SkMatrix&) {}
@@ -1304,16 +1333,17 @@
     // returns false if the entire rectangle is entirely clipped out
     // If non-NULL, The imageFilter parameter will be used to expand the clip
     // and offscreen bounds for any margin required by the filter DAG.
-    bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
-                        SkIRect* intersection,
+    bool clipRectBounds(const SkRect* bounds, SaveLayerFlags, SkIRect* intersection,
                         const SkImageFilter* imageFilter = NULL);
 
 private:
-    enum PrivateSaveFlags {
-        // These must not overlap the public flags.
-        kPreserveLCDText_PrivateSaveFlag = 1 << 5,
+    enum PrivateSaveLayerFlags {
+        kDontClipToLayer_PrivateSaveLayerFlag   = 1 << 31,
     };
 
+    static bool BoundsAffectsClip(SaveLayerFlags);
+    static uint32_t SaveFlagsToSaveLayerFlags(SaveFlags);
+
     enum ShaderOverrideOpacity {
         kNone_ShaderOverrideOpacity,        //!< there is no overriding shader (bitmap or image)
         kOpaque_ShaderOverrideOpacity,      //!< the overriding shader is opaque
@@ -1373,6 +1403,7 @@
     friend class SkNoSaveLayerCanvas;   // InitFlags
     friend class SkPictureImageFilter;  // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
     friend class SkPictureRecord;   // predrawNotify (why does it need it? <reed>)
+    friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
 
     enum InitFlags {
         kDefault_InitFlags                  = 0,
@@ -1404,7 +1435,7 @@
                                 const SkRect& dst, const SkPaint* paint,
                                 SrcRectConstraint);
     void internalDrawPaint(const SkPaint& paint);
-    void internalSaveLayer(const SkRect* bounds, const SkPaint*, SaveFlags, SaveLayerStrategy);
+    void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
     void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, bool isBitmapDevice);
 
     // shared by save() and saveLayer()
diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h
index ab9b8a0..a2e9030 100644
--- a/include/private/SkRecords.h
+++ b/include/private/SkRecords.h
@@ -197,7 +197,7 @@
 RECORD(SaveLayer, 0,
        Optional<SkRect> bounds;
        Optional<SkPaint> paint;
-       SkCanvas::SaveFlags flags);
+       SkCanvas::SaveLayerFlags saveLayerFlags);
 
 RECORD(SetMatrix, 0,
         TypedMatrix matrix);
diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h
index 41395e0..d4c6dbf 100644
--- a/include/utils/SkDumpCanvas.h
+++ b/include/utils/SkDumpCanvas.h
@@ -73,7 +73,7 @@
 
 protected:
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override;
 
     void didConcat(const SkMatrix&) override;
diff --git a/include/utils/SkLuaCanvas.h b/include/utils/SkLuaCanvas.h
index 270be8a..37e82be 100644
--- a/include/utils/SkLuaCanvas.h
+++ b/include/utils/SkLuaCanvas.h
@@ -22,7 +22,7 @@
 
 protected:
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override;
 
     void didConcat(const SkMatrix&) override;
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index 02f8c35..8d824d7 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -30,7 +30,7 @@
     SkTDArray<SkCanvas*> fList;
 
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override;
 
     void didConcat(const SkMatrix&) override;
diff --git a/include/utils/SkNoSaveLayerCanvas.h b/include/utils/SkNoSaveLayerCanvas.h
index 0cebeff..3d786c5 100644
--- a/include/utils/SkNoSaveLayerCanvas.h
+++ b/include/utils/SkNoSaveLayerCanvas.h
@@ -21,9 +21,8 @@
     {}
 
 protected:
-    virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                            SaveFlags flags) override {
-        this->INHERITED::willSaveLayer(bounds, paint, flags);
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
+        (void)this->INHERITED::getSaveLayerStrategy(rec);
         return kNoLayer_SaveLayerStrategy;
     }
 
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 414e94e..09fef0b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -481,7 +481,7 @@
                 // Make rawBounds include all paint outsets except for those due to image filters.
                 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage);
             }
-            (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag,
+            (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp, 0),
                                             SkCanvas::kFullLayer_SaveLayerStrategy);
             fTempLayerForImageFilter = true;
             // we remove the imagefilter/xfermode inside doNext()
@@ -1053,15 +1053,15 @@
     fClipStack->save();
 }
 
-static bool bounds_affects_clip(SkCanvas::SaveFlags flags) {
+bool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) {
 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
-    return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0;
+    return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag);
 #else
     return true;
 #endif
 }
 
-bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
+bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags,
                               SkIRect* intersection, const SkImageFilter* imageFilter) {
     SkIRect clipBounds;
     if (!this->getClipDeviceBounds(&clipBounds)) {
@@ -1098,7 +1098,7 @@
         r.roundOut(&ir);
         // early exit if the layer's bounds are clipped out
         if (!ir.intersect(clipBounds)) {
-            if (bounds_affects_clip(flags)) {
+            if (BoundsAffectsClip(saveLayerFlags)) {
                 fCachedLocalClipBoundsDirty = true;
                 fMCRec->fRasterClip.setEmpty();
             }
@@ -1109,7 +1109,7 @@
     }
     SkASSERT(!ir.isEmpty());
 
-    if (bounds_affects_clip(flags)) {
+    if (BoundsAffectsClip(saveLayerFlags)) {
         // Simplify the current clips since they will be applied properly during restore()
         fCachedLocalClipBoundsDirty = true;
         fClipStack->clipDevRect(ir, SkRegion::kReplace_Op);
@@ -1122,29 +1122,53 @@
     return true;
 }
 
-int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
-    if (gIgnoreSaveLayerBounds) {
-        bounds = nullptr;
+uint32_t SkCanvas::SaveFlagsToSaveLayerFlags(SaveFlags flags) {
+    uint32_t layerFlags = 0;
+
+    if (0 == (flags & kClipToLayer_SaveFlag)) {
+        layerFlags |= kDontClipToLayer_PrivateSaveLayerFlag;
     }
-    SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag);
-    fSaveCount += 1;
-    this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy);
-    return this->getSaveCount() - 1;
+    if (0 == (flags & kHasAlphaLayer_SaveFlag)) {
+        layerFlags |= kIsOpaque_SaveLayerFlag;
+    }
+    return layerFlags;
+}
+
+#ifdef SK_SUPPORT_LEGACY_SAVELAYERPARAMS
+SkCanvas::SaveLayerStrategy SkCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
+    uint32_t flags = 0;
+
+    if (0 == (rec.fSaveLayerFlags & kDontClipToLayer_PrivateSaveLayerFlag)) {
+        flags |= kClipToLayer_SaveFlag;
+    }
+    if (0 == (rec.fSaveLayerFlags & kIsOpaque_SaveLayerFlag)) {
+        flags |= kHasAlphaLayer_SaveFlag;
+    }
+    return this->willSaveLayer(rec.fBounds, rec.fPaint, (SaveFlags)flags);
+}
+#endif
+
+int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
+    return this->saveLayer(SaveLayerRec(bounds, paint, 0));
 }
 
 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) {
-    if (gIgnoreSaveLayerBounds) {
-        bounds = nullptr;
-    }
-    SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags);
-    fSaveCount += 1;
-    this->internalSaveLayer(bounds, paint, flags, strategy);
-    return this->getSaveCount() - 1;
+    return this->saveLayer(SaveLayerRec(bounds, paint, SaveFlagsToSaveLayerFlags(flags)));
 }
 
 int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) {
-    unsigned flags = kARGB_ClipLayer_SaveFlag | kPreserveLCDText_PrivateSaveFlag;
-    return this->saveLayer(bounds, paint, (SaveFlags)flags);
+    return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag));
+}
+
+int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
+    SaveLayerRec rec(origRec);
+    if (gIgnoreSaveLayerBounds) {
+        rec.fBounds = nullptr;
+    }
+    SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec);
+    fSaveCount += 1;
+    this->internalSaveLayer(rec, strategy);
+    return this->getSaveCount() - 1;
 }
 
 static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, SkBaseDevice* dst) {
@@ -1177,10 +1201,13 @@
     c.drawBitmap(srcBM, 0, 0, &p);
 }
 
-void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags,
-                                 SaveLayerStrategy strategy) {
+void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) {
+    const SkRect* bounds = rec.fBounds;
+    const SkPaint* paint = rec.fPaint;
+    SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags;
+
 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
-    flags |= kClipToLayer_SaveFlag;
+    saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag;
 #endif
 
     // do this before we create the layer. We don't call the public save() since
@@ -1190,7 +1217,7 @@
     fDeviceCMDirty = true;
 
     SkIRect ir;
-    if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : nullptr)) {
+    if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, paint ? paint->getImageFilter() : nullptr)) {
         return;
     }
 
@@ -1200,7 +1227,7 @@
         return;
     }
 
-    bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag);
+    bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag);
     SkPixelGeometry geo = fProps.pixelGeometry();
     if (paint) {
         // TODO: perhaps add a query to filters so we might preserve opaqueness...
@@ -1221,7 +1248,7 @@
     bool forceSpriteOnRestore = false;
     {
         const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
-                                     SkToBool(flags & kPreserveLCDText_PrivateSaveFlag);
+                                     (saveLayerFlags & kPreserveLCDText_SaveLayerFlag);
         const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
         const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo,
                                                                             preserveLCDText, false);
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 8befca0..cbacc8e 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -51,7 +51,7 @@
     RESTORE,
     ROTATE,
     SAVE,
-    SAVE_LAYER,
+    SAVE_LAYER_SAVEFLAGS_DEPRECATED,
     SCALE,
     SET_MATRIX,
     SKEW,
@@ -75,7 +75,9 @@
     DRAW_IMAGE_NINE,
     DRAW_IMAGE_RECT,
 
-    LAST_DRAWTYPE_ENUM = DRAW_IMAGE_RECT
+    SAVE_LAYER_SAVELAYERFLAGS,
+
+    LAST_DRAWTYPE_ENUM = SAVE_LAYER_SAVELAYERFLAGS,
 };
 
 // In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 9b27a3d..187eeb9 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -455,10 +455,17 @@
             }
             canvas->save();
             break;
-        case SAVE_LAYER: {
+        case SAVE_LAYER_SAVEFLAGS_DEPRECATED: {
             const SkRect* boundsPtr = get_rect_ptr(reader);
             const SkPaint* paint = fPictureData->getPaint(reader);
-            canvas->saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader->readInt());
+            const SkCanvas::SaveFlags flags = (SkCanvas::SaveFlags)reader->readInt();
+            canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint,
+                                           SkCanvas::SaveFlagsToSaveLayerFlags(flags)));
+        } break;
+        case SAVE_LAYER_SAVELAYERFLAGS: {
+            const SkRect* boundsPtr = get_rect_ptr(reader);
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, reader->readInt()));
         } break;
         case SCALE: {
             SkScalar sx = reader->readScalar();
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index f9ab0c9..36b8d37 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -83,7 +83,7 @@
         0,  // RESTORE - no paint
         0,  // ROTATE - no paint
         0,  // SAVE - no paint
-        0,  // SAVE_LAYER - see below - this paint's location varies
+        0,  // SAVE_LAYER_SAVEFLAGS_DEPRECATED - see below - this paint's location varies
         0,  // SCALE - no paint
         0,  // SET_MATRIX - no paint
         0,  // SKEW - no paint
@@ -103,6 +103,7 @@
         1,  // DRAW_ATLAS - right after op code
         1,  // DRAW_IMAGE_NINE - right after op code
         1,  // DRAW_IMAGE_RECT - right after op code
+        0,  // SAVE_LAYER_SAVELAYERFLAGS - see below - this paint's location varies
     };
 
     static_assert(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, "need_to_be_in_sync");
@@ -115,7 +116,8 @@
         overflow = sizeof(uint32_t);
     }
 
-    if (SAVE_LAYER == op) {
+    SkASSERT(SAVE_LAYER_SAVEFLAGS_DEPRECATED != op);
+    if (SAVE_LAYER_SAVELAYERFLAGS == op) {
         static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size;
         static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect);
 
@@ -151,14 +153,13 @@
     this->validate(initialOffset, size);
 }
 
-SkCanvas::SaveLayerStrategy SkPictureRecord::willSaveLayer(const SkRect* bounds,
-                                                           const SkPaint* paint, SaveFlags flags) {
+SkCanvas::SaveLayerStrategy SkPictureRecord::getSaveLayerStrategy(const SaveLayerRec& rec) {
     // record the offset to us, making it non-positive to distinguish a save
     // from a clip entry.
     fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten());
-    this->recordSaveLayer(bounds, paint, flags);
+    this->recordSaveLayer(rec);
 
-    this->INHERITED::willSaveLayer(bounds, paint, flags);
+    (void)this->INHERITED::getSaveLayerStrategy(rec);
     /*  No need for a (potentially very big) layer which we don't actually need
         at this time (and may not be able to afford since during record our
         clip starts out the size of the picture, which is often much larger
@@ -167,25 +168,24 @@
     return kNoLayer_SaveLayerStrategy;
 }
 
-void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                      SaveFlags flags) {
+void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) {
     fContentInfo.onSaveLayer();
 
     // op + bool for 'bounds'
     size_t size = 2 * kUInt32Size;
-    if (bounds) {
-        size += sizeof(*bounds); // + rect
+    if (rec.fBounds) {
+        size += sizeof(*rec.fBounds); // + rect
     }
     // + paint index + flags
     size += 2 * kUInt32Size;
 
     SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size);
 
-    size_t initialOffset = this->addDraw(SAVE_LAYER, &size);
-    this->addRectPtr(bounds);
-    SkASSERT(initialOffset+get_paint_offset(SAVE_LAYER, size) == fWriter.bytesWritten());
-    this->addPaintPtr(paint);
-    this->addInt(flags);
+    size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERFLAGS, &size);
+    this->addRectPtr(rec.fBounds);
+    SkASSERT(initialOffset+get_paint_offset(SAVE_LAYER_SAVELAYERFLAGS, size) == fWriter.bytesWritten());
+    this->addPaintPtr(rec.fPaint);
+    this->addInt(rec.fSaveLayerFlags);
 
     this->validate(initialOffset, size);
 }
@@ -321,7 +321,8 @@
         // assert that the final offset value points to a save verb
         uint32_t opSize;
         DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize);
-        SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp);
+        SkASSERT(SAVE_LAYER_SAVEFLAGS_DEPRECATED != drawOp);
+        SkASSERT(SAVE == drawOp || SAVE_LAYER_SAVELAYERFLAGS == drawOp);
     }
 #endif
 }
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 3dcaa6c..2e1e62a 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -153,7 +153,7 @@
     bool onPeekPixels(SkPixmap*) override { return false; }
 
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override;
 
     void didConcat(const SkMatrix&) override;
@@ -218,7 +218,7 @@
     size_t recordClipPath(int pathID, SkRegion::Op op, bool doAA);
     size_t recordClipRegion(const SkRegion& region, SkRegion::Op op);
     void recordSave();
-    void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
+    void recordSaveLayer(const SaveLayerRec&);
     void recordRestore(bool fillInSkips = true);
 
 private:
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index f512ecf..0184667 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -78,7 +78,7 @@
 #define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; }
 DRAW(Restore, restore());
 DRAW(Save, save());
-DRAW(SaveLayer, saveLayer(r.bounds, r.paint, r.flags));
+DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds, r.paint, r.saveLayerFlags)));
 DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
 DRAW(Concat, concat(r.matrix));
 
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index c7a826f..67429a6 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -336,10 +336,8 @@
     APPEND(Save);
 }
 
-SkCanvas::SaveLayerStrategy SkRecorder::willSaveLayer(const SkRect* bounds,
-                                                      const SkPaint* paint,
-                                                      SkCanvas::SaveFlags flags) {
-    APPEND(SaveLayer, this->copy(bounds), this->copy(paint), flags);
+SkCanvas::SaveLayerStrategy SkRecorder::getSaveLayerStrategy(const SaveLayerRec& rec) {
+    APPEND(SaveLayer, this->copy(rec.fBounds), this->copy(rec.fPaint), rec.fSaveLayerFlags);
     return SkCanvas::kNoLayer_SaveLayerStrategy;
 }
 
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 6bde375..cd5bc8a 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -54,7 +54,7 @@
     void forgetRecord();
 
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override {}
     void didRestore() override;
 
diff --git a/src/core/SkRemote.cpp b/src/core/SkRemote.cpp
index 1209be0..22185cd 100644
--- a/src/core/SkRemote.cpp
+++ b/src/core/SkRemote.cpp
@@ -163,18 +163,17 @@
 
         void   willSave() override { fEncoder->   save(); }
         void didRestore() override { fEncoder->restore(); }
-        SaveLayerStrategy willSaveLayer(const SkRect* bounds,
-                                        const SkPaint* paint,
-                                        SaveFlags flags) override {
+        SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
             SkPath path;
-            if (bounds) {
-                path.addRect(*bounds);
+            if (rec.fBounds) {
+                path.addRect(*rec.fBounds);
             }
             const SkPaint defaultPaint;
+            const SkPaint* paint = rec.fPaint;
             if (!paint) {
                 paint = &defaultPaint;
             }
-            fEncoder->saveLayer(this->id(path), this->commonIDs(*paint), flags);
+            fEncoder->saveLayer(this->id(path), this->commonIDs(*paint), rec.fSaveLayerFlags);
             return kNoLayer_SaveLayerStrategy;
         }
 
@@ -500,11 +499,13 @@
 
         void    save() override { fCanvas->save(); }
         void restore() override { fCanvas->restore(); }
-        void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveFlags flags) override {
+        void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveLayerFlags flags) override {
             SkPaint paint;
             this->applyCommon(common, &paint);
             SkRect rect;
-            fCanvas->saveLayer(fPath.find(bounds).isRect(&rect) ? &rect : nullptr, &paint, flags);
+
+            fCanvas->saveLayer({ fPath.find(bounds).isRect(&rect) ? &rect : nullptr,
+                                 &paint, flags });
         }
 
         void setMatrix(ID matrix) override { fCanvas->setMatrix(fMatrix.find(matrix)); }
@@ -684,7 +685,7 @@
 
         void    save() override { fWrapped->   save(); }
         void restore() override { fWrapped->restore(); }
-        void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveFlags flags) override {
+        void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveLayerFlags flags) override {
             fWrapped->saveLayer(bounds, common, flags);
         }
 
diff --git a/src/core/SkRemote.h b/src/core/SkRemote.h
index 924e63e..a1b1405 100644
--- a/src/core/SkRemote.h
+++ b/src/core/SkRemote.h
@@ -91,7 +91,7 @@
 
         virtual void    save() = 0;
         virtual void restore() = 0;
-        virtual void saveLayer(ID bounds, CommonIDs, SkCanvas::SaveFlags) = 0;
+        virtual void saveLayer(ID bounds, CommonIDs, uint32_t saveLayerFlags) = 0;
 
         virtual void setMatrix(ID matrix) = 0;
 
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 24f3e2d..b48389a 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -335,7 +335,7 @@
 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
                          SkGPipeState* state) {
     unsigned flags = DrawOp_unpackFlags(op32);
-    SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
+    SkCanvas::SaveLayerFlags saveLayerFlags = DrawOp_unpackData(op32);
 
     const SkRect* bounds = nullptr;
     if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
@@ -345,7 +345,7 @@
     if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
         paint = &state->paint();
     }
-    canvas->saveLayer(bounds, paint, saveFlags);
+    canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, saveLayerFlags));
 }
 
 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 2cab09c..5147cd6 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -248,7 +248,7 @@
 
 protected:
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override;
 
     void didConcat(const SkMatrix&) override;
@@ -542,29 +542,28 @@
     this->INHERITED::willSave();
 }
 
-SkCanvas::SaveLayerStrategy SkGPipeCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                                         SaveFlags saveFlags) {
+SkCanvas::SaveLayerStrategy SkGPipeCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
     NOTIFY_SETUP(this);
     size_t size = 0;
     unsigned opFlags = 0;
 
-    if (bounds) {
+    if (rec.fBounds) {
         opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
         size += sizeof(SkRect);
     }
-    if (paint) {
+    if (rec.fPaint) {
         opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
-        this->writePaint(*paint);
+        this->writePaint(*rec.fPaint);
     }
 
     if (this->needOpBytes(size)) {
-        this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
-        if (bounds) {
-            fWriter.writeRect(*bounds);
+        this->writeOp(kSaveLayer_DrawOp, opFlags, rec.fSaveLayerFlags);
+        if (rec.fBounds) {
+            fWriter.writeRect(*rec.fBounds);
         }
     }
 
-    this->INHERITED::willSaveLayer(bounds, paint, saveFlags);
+    (void)this->INHERITED::getSaveLayerStrategy(rec);
     // we don't create a layer
     return kNoLayer_SaveLayerStrategy;
 }
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index a500561..916c32a 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -199,14 +199,14 @@
     this->INHERITED::willSave();
 }
 
-SkCanvas::SaveLayerStrategy SkDumpCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                                        SaveFlags flags) {
+SkCanvas::SaveLayerStrategy SkDumpCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
     SkString str;
-    str.printf("saveLayer(0x%X)", flags);
-    if (bounds) {
+    str.printf("saveLayer(0x%X)", rec.fSaveLayerFlags);
+    if (rec.fBounds) {
         str.append(" bounds");
-        toString(*bounds, &str);
+        toString(*rec.fBounds, &str);
     }
+    const SkPaint* paint = rec.fPaint;
     if (paint) {
         if (paint->getAlpha() != 0xFF) {
             str.appendf(" alpha:0x%02X", paint->getAlpha());
@@ -216,7 +216,7 @@
         }
     }
     this->dump(kSave_Verb, paint, str.c_str());
-    return this->INHERITED::willSaveLayer(bounds, paint, flags);
+    return this->INHERITED::getSaveLayerStrategy(rec);
 }
 
 void SkDumpCanvas::willRestore() {
diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp
index 4916dec..c51b0d8 100644
--- a/src/utils/SkLuaCanvas.cpp
+++ b/src/utils/SkLuaCanvas.cpp
@@ -86,17 +86,16 @@
     this->INHERITED::willSave();
 }
 
-SkCanvas::SaveLayerStrategy SkLuaCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                                       SaveFlags flags) {
+SkCanvas::SaveLayerStrategy SkLuaCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
     AUTO_LUA("saveLayer");
-    if (bounds) {
-        lua.pushRect(*bounds, "bounds");
+    if (rec.fBounds) {
+        lua.pushRect(*rec.fBounds, "bounds");
     }
-    if (paint) {
-        lua.pushPaint(*paint, "paint");
+    if (rec.fPaint) {
+        lua.pushPaint(*rec.fPaint, "paint");
     }
 
-    this->INHERITED::willSaveLayer(bounds, paint, flags);
+    (void)this->INHERITED::getSaveLayerStrategy(rec);
     // No need for a layer.
     return kNoLayer_SaveLayerStrategy;
 }
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 05909a3..4f60ca3 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -66,14 +66,13 @@
     this->INHERITED::willSave();
 }
 
-SkCanvas::SaveLayerStrategy SkNWayCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                                        SaveFlags flags) {
+SkCanvas::SaveLayerStrategy SkNWayCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
     Iter iter(fList);
     while (iter.next()) {
-        iter->saveLayer(bounds, paint, flags);
+        iter->saveLayer(rec);
     }
 
-    this->INHERITED::willSaveLayer(bounds, paint, flags);
+    this->INHERITED::getSaveLayerStrategy(rec);
     // No need for a layer.
     return kNoLayer_SaveLayerStrategy;
 }
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 8693739..560976c 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -524,10 +524,9 @@
     this->INHERITED::willSave();
 }
 
-SkCanvas::SaveLayerStrategy SkDebugCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                                         SaveFlags flags) {
-    this->addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags));
-    this->INHERITED::willSaveLayer(bounds, paint, flags);
+SkCanvas::SaveLayerStrategy SkDebugCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
+    this->addDrawCommand(new SkSaveLayerCommand(rec));
+    (void)this->INHERITED::getSaveLayerStrategy(rec);
     // No need for a full layer.
     return kNoLayer_SaveLayerStrategy;
 }
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index 7de2b59..217b52e 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -165,7 +165,7 @@
 
 protected:
     void willSave() override;
-    SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
     void willRestore() override;
 
     void didConcat(const SkMatrix&) override;
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 9ebb81e..bb9f2f8 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -925,36 +925,35 @@
     canvas->save();
 }
 
-SkSaveLayerCommand::SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
-                                       SkCanvas::SaveFlags flags)
+SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
     : INHERITED(kSaveLayer_OpType) {
-    if (bounds) {
-        fBounds = *bounds;
+    if (rec.fBounds) {
+        fBounds = *rec.fBounds;
     } else {
         fBounds.setEmpty();
     }
 
-    if (paint) {
-        fPaint = *paint;
+    if (rec.fPaint) {
+        fPaint = *rec.fPaint;
         fPaintPtr = &fPaint;
     } else {
         fPaintPtr = nullptr;
     }
-    fFlags = flags;
+    fSaveLayerFlags = rec.fSaveLayerFlags;
 
-    if (bounds) {
-        fInfo.push(SkObjectParser::RectToString(*bounds, "Bounds: "));
+    if (rec.fBounds) {
+        fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
     }
-    if (paint) {
-        fInfo.push(SkObjectParser::PaintToString(*paint));
+    if (rec.fPaint) {
+        fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
     }
-    fInfo.push(SkObjectParser::SaveFlagsToString(flags));
+    fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
 }
 
 void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
-    canvas->saveLayer(fBounds.isEmpty() ? nullptr : &fBounds,
-                      fPaintPtr,
-                      fFlags);
+    canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
+                                             fPaintPtr,
+                                             fSaveLayerFlags));
 }
 
 void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index 9da05ee..f67df92 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -551,8 +551,7 @@
 
 class SkSaveLayerCommand : public SkDrawCommand {
 public:
-    SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
-                       SkCanvas::SaveFlags flags);
+    SkSaveLayerCommand(const SkCanvas::SaveLayerRec&);
     void execute(SkCanvas* canvas) const override;
     void vizExecute(SkCanvas* canvas) const override;
     Action action() const override{ return kPushLayer_Action; }
@@ -562,12 +561,12 @@
     const SkPaint* paint() const { return fPaintPtr; }
 
 private:
-    SkRect              fBounds;
-    SkPaint             fPaint;
-    SkPaint*            fPaintPtr;
-    SkCanvas::SaveFlags fFlags;
+    SkRect      fBounds;
+    SkPaint     fPaint;
+    SkPaint*    fPaintPtr;
+    uint32_t    fSaveLayerFlags;
 
-    bool                fActive;
+    bool        fActive;
 
     typedef SkDrawCommand INHERITED;
 };
diff --git a/src/utils/debugger/SkObjectParser.cpp b/src/utils/debugger/SkObjectParser.cpp
index 3dbc039..6d71a38 100644
--- a/src/utils/debugger/SkObjectParser.cpp
+++ b/src/utils/debugger/SkObjectParser.cpp
@@ -338,16 +338,13 @@
     return mRegion;
 }
 
-SkString* SkObjectParser::SaveFlagsToString(SkCanvas::SaveFlags flags) {
+SkString* SkObjectParser::SaveLayerFlagsToString(SkCanvas::SaveLayerFlags saveLayerFlags) {
     SkString* mFlags = new SkString("SkCanvas::SaveFlags: ");
-    if (flags & SkCanvas::kHasAlphaLayer_SaveFlag) {
-        mFlags->append("kHasAlphaLayer_SaveFlag ");
+    if (saveLayerFlags & SkCanvas::kIsOpaque_SaveLayerFlag) {
+        mFlags->append("kIsOpaque_SaveLayerFlag ");
     }
-    if (flags & SkCanvas::kFullColorLayer_SaveFlag) {
-        mFlags->append("kFullColorLayer_SaveFlag ");
-    }
-    if (flags & SkCanvas::kClipToLayer_SaveFlag) {
-        mFlags->append("kClipToLayer_SaveFlag ");
+    if (saveLayerFlags & SkCanvas::kPreserveLCDText_SaveLayerFlag) {
+        mFlags->append("kPreserveLCDText_SaveLayerFlag ");
     }
     return mFlags;
 }
diff --git a/src/utils/debugger/SkObjectParser.h b/src/utils/debugger/SkObjectParser.h
index 4c04935..9bdfad5 100644
--- a/src/utils/debugger/SkObjectParser.h
+++ b/src/utils/debugger/SkObjectParser.h
@@ -110,10 +110,10 @@
     static SkString* RegionToString(const SkRegion& region);
 
     /**
-        Returns a string representation of the SkCanvas::SaveFlags enum.
-        @param flags  SkCanvas::SaveFlags enum
+        Returns a string representation of the SkCanvas::SaveLayerFlags enum.
+        @param flags  SkCanvas::SaveLayerFlags enum
      */
-    static SkString* SaveFlagsToString(SkCanvas::SaveFlags flags);
+    static SkString* SaveLayerFlagsToString(uint32_t saveLayerFlags);
 
     /**
         Returns a string representation of an SkScalar with the text parameter
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index 45a0505..fdb2de4 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -559,10 +559,9 @@
         , fRestoreCount(0){
     }
 
-    virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds, const SkPaint* paint,
-                                            SaveFlags flags) override {
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
         ++fSaveLayerCount;
-        return this->INHERITED::willSaveLayer(bounds, paint, flags);
+        return this->INHERITED::getSaveLayerStrategy(rec);
     }
 
     void willSave() override {