diff --git a/gm/savelayer.cpp b/gm/savelayer.cpp index 510fc2f1f4..6a01edd4f0 100644 --- a/gm/savelayer.cpp +++ b/gm/savelayer.cpp @@ -80,6 +80,8 @@ private: typedef skiagm::GM INHERITED; }; +DEF_GM(return new UnclippedSaveLayerGM(UnclippedSaveLayerGM::Mode::kClipped);) +DEF_GM(return new UnclippedSaveLayerGM(UnclippedSaveLayerGM::Mode::kUnclipped);) DEF_SIMPLE_GM(picture_savelayer, canvas, 320, 640) { SkPaint paint1, paint2, paint3; @@ -99,8 +101,23 @@ DEF_SIMPLE_GM(picture_savelayer, canvas, 320, 640) { } }; -////////////////////////////////////////////////////////////////////////////// +#include "Resources.h" -DEF_GM(return new UnclippedSaveLayerGM(UnclippedSaveLayerGM::Mode::kClipped);) -DEF_GM(return new UnclippedSaveLayerGM(UnclippedSaveLayerGM::Mode::kUnclipped);) +// Test kInitWithPrevious_SaveLayerFlag by drawing an image, save a layer with the flag, which +// should seed the layer with the image (from below). Then we punch a hole in the layer and +// restore with kPlus mode, which should show the mandrill super-bright on the outside, but +// normal where we punched the hole. +DEF_SIMPLE_GM(savelayer_initfromprev, canvas, 256, 256) { + canvas->drawImage(GetResourceAsImage("mandrill_256.png"), 0, 0, nullptr); + + SkCanvas::SaveLayerRec rec; + SkPaint paint; + paint.setBlendMode(SkBlendMode::kPlus); + rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag; + rec.fPaint = &paint; + canvas->saveLayer(rec); + paint.setBlendMode(SkBlendMode::kClear); + canvas->drawCircle(128, 128, 96, paint); + canvas->restore(); +}; diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 403120c80a..9e9d98a587 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -321,6 +321,9 @@ public: kIsOpaque_SaveLayerFlag = 1 << 0, kPreserveLCDText_SaveLayerFlag = 1 << 1, + /** initialize the new layer with the contents of the previous layer */ + kInitWithPrevious_SaveLayerFlag = 1 << 2, + #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag, #endif diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 04cead44fb..5c7039fc50 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1148,7 +1148,9 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt draw.fClipStack = clipStack; SkPaint p; - p.setImageFilter(filter->makeWithLocalMatrix(ctm)); + if (filter) { + p.setImageFilter(filter->makeWithLocalMatrix(ctm)); + } int x = src->getOrigin().x() - dstOrigin.x(); int y = src->getOrigin().y() - dstOrigin.y(); @@ -1275,7 +1277,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra fMCRec->fLayer = layer; fMCRec->fTopLayer = layer; // this field is NOT an owner of layer - if (rec.fBackdrop) { + if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) { DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop }, fMCRec->fMatrix, this->getClipStack()); }