Initial clip-mask-layer support
SkBitmapDevice-only implementation. Will add A8 fast path specializations in a follow-up. Change-Id: I2ccb1ffba3689e92ac90a23e94737471dfb121a1 BUG=skia:6005 Change-Id: I2ccb1ffba3689e92ac90a23e94737471dfb121a1 Reviewed-on: https://skia-review.googlesource.com/14183 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
57061eea44
commit
53f77bd4fd
@ -123,7 +123,7 @@ static void draw_set(SkCanvas* canvas, sk_sp<SkImageFilter> filters[], int count
|
||||
canvas->save();
|
||||
SkRRect rr = SkRRect::MakeRectXY(r.makeOffset(dx, dy), 20, 20);
|
||||
canvas->clipRRect(rr, true);
|
||||
canvas->saveLayer({ &rr.getBounds(), nullptr, filters[i].get(), 0 });
|
||||
canvas->saveLayer({ &rr.getBounds(), nullptr, filters[i].get(), nullptr, nullptr, 0 });
|
||||
canvas->drawColor(0x40FFFFFF);
|
||||
canvas->restore();
|
||||
canvas->restore();
|
||||
|
123
gm/savelayer.cpp
123
gm/savelayer.cpp
@ -8,7 +8,6 @@
|
||||
#include "gm.h"
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
|
||||
static const uint32_t SkCanvas_kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31;
|
||||
|
||||
// This GM tests out the deprecated Android-specific unclipped saveLayer "feature".
|
||||
@ -17,7 +16,8 @@ static const uint32_t SkCanvas_kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31;
|
||||
static void save_layer_unclipped(SkCanvas* canvas,
|
||||
SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
|
||||
SkRect rect = SkRect::MakeLTRB(l, t, r, b);
|
||||
canvas->saveLayer({ &rect, nullptr, nullptr, SkCanvas_kDontClipToLayer_PrivateSaveLayerFlag });
|
||||
canvas->saveLayer({ &rect, nullptr, nullptr, nullptr, nullptr,
|
||||
SkCanvas_kDontClipToLayer_PrivateSaveLayerFlag });
|
||||
}
|
||||
|
||||
static void do_draw(SkCanvas* canvas) {
|
||||
@ -94,8 +94,8 @@ DEF_SIMPLE_GM(picture_savelayer, canvas, 320, 640) {
|
||||
for(int i = 1; i < 2; ++i) {
|
||||
canvas->translate(100 * i, 0);
|
||||
auto flag = i ? SkCanvas_kDontClipToLayer_PrivateSaveLayerFlag : 0;
|
||||
canvas->saveLayer({ &rect1, &paint1, nullptr, flag});
|
||||
canvas->saveLayer({ &rect2, &paint2, nullptr, flag});
|
||||
canvas->saveLayer({ &rect1, &paint1, nullptr, nullptr, nullptr, flag});
|
||||
canvas->saveLayer({ &rect2, &paint2, nullptr, nullptr, nullptr, flag});
|
||||
canvas->drawRect(rect3, paint3);
|
||||
canvas->restore();
|
||||
canvas->restore();
|
||||
@ -122,3 +122,118 @@ DEF_SIMPLE_GM(savelayer_initfromprev, canvas, 256, 256) {
|
||||
canvas->restore();
|
||||
};
|
||||
|
||||
#include "SkBlurImageFilter.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPictureRecorder.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
static void draw_mask(SkCanvas* canvas, int size) {
|
||||
const SkScalar cx = size * SK_ScalarHalf,
|
||||
cy = cx;
|
||||
const SkColor colors[] = { 0x00000000, 0xffff0000, 0x00000000, 0xffff0000, 0x00000000,
|
||||
0xffff0000, 0x00000000, 0xffff0000, 0x00000000 };
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setShader(SkGradientShader::MakeSweep(cx, cy, colors, nullptr, SK_ARRAY_COUNT(colors)));
|
||||
canvas->drawPaint(paint);
|
||||
|
||||
paint.setShader(SkGradientShader::MakeRadial({cx, cy}, size / 4, colors, nullptr, 2,
|
||||
SkShader::kClamp_TileMode));
|
||||
canvas->drawCircle(cx, cy, size / 4, paint);
|
||||
}
|
||||
|
||||
DEF_SIMPLE_GM(savelayer_clipmask, canvas, 1200, 1200) {
|
||||
static constexpr int kSize = 100;
|
||||
static constexpr SkRect kLayerBounds = { kSize * 0.25f, kSize * 0.25f,
|
||||
kSize * 0.75f, kSize * 0.75f };
|
||||
static constexpr struct {
|
||||
const SkRect* bounds;
|
||||
const SkScalar matrix[9];
|
||||
} kConfigs[] = {
|
||||
{ nullptr, { 1 , 0 , 0, 0 , 1 , 0, 0, 0, 1 } },
|
||||
{ nullptr, { 2 , 0 , 0, 0 , 2 , 0, 0, 0, 1 } },
|
||||
{ nullptr, { 2 , 0 , -50, 0 , 2 , -50, 0, 0, 1 } },
|
||||
{ nullptr, { 0.707f, -0.707f, 50, 0.707f, 0.707f, -20, 0, 0, 1 } },
|
||||
{ nullptr, { 0.5f , 0 , 25, 0 , 0.5f , 25, 0, 0, 1 } },
|
||||
|
||||
{ &kLayerBounds, { 1 , 0 , 0, 0 , 1 , 0, 0, 0, 1 } },
|
||||
{ &kLayerBounds, { 2 , 0 , 0, 0 , 2 , 0, 0, 0, 1 } },
|
||||
{ &kLayerBounds, { 2 , 0 , -50, 0 , 2 , -50, 0, 0, 1 } },
|
||||
{ &kLayerBounds, { 0.707f, -0.707f, 50, 0.707f, 0.707f, -20, 0, 0, 1 } },
|
||||
{ &kLayerBounds, { 0.5f , 0 , 25, 0 , 0.5f , 25, 0, 0, 1 } },
|
||||
};
|
||||
|
||||
using MaskMakerFunc = sk_sp<SkImage> (*)(int size);
|
||||
static const MaskMakerFunc kMaskMakers[] = {
|
||||
[](int size) -> sk_sp<SkImage> {
|
||||
auto surf = SkSurface::MakeRaster(SkImageInfo::MakeA8(size, size));
|
||||
draw_mask(surf->getCanvas(), size);
|
||||
return surf->makeImageSnapshot();
|
||||
},
|
||||
|
||||
[](int size) -> sk_sp<SkImage> {
|
||||
auto surf = SkSurface::MakeRasterN32Premul(size, size);
|
||||
draw_mask(surf->getCanvas(), size);
|
||||
return surf->makeImageSnapshot();
|
||||
},
|
||||
|
||||
[](int size) -> sk_sp<SkImage> {
|
||||
SkPictureRecorder recorder;
|
||||
draw_mask(recorder.beginRecording(size, size), size);
|
||||
return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(),
|
||||
SkISize::Make(size, size),
|
||||
nullptr, nullptr,
|
||||
SkImage::BitDepth::kU8,
|
||||
SkColorSpace::MakeSRGB());
|
||||
}
|
||||
};
|
||||
|
||||
using PaintMakerFunc = SkPaint (*)();
|
||||
static const PaintMakerFunc kPaintMakers[] = {
|
||||
[]() -> SkPaint { return SkPaint(); },
|
||||
[]() -> SkPaint {
|
||||
SkPaint p; p.setImageFilter(SkBlurImageFilter::Make(2, 2, nullptr)); return p;
|
||||
},
|
||||
[]() -> SkPaint { SkPaint p; p.setBlendMode(SkBlendMode::kSrcOut); return p; },
|
||||
};
|
||||
|
||||
canvas->drawColor(0xffcccccc);
|
||||
|
||||
SkMatrix clipMatrix;
|
||||
SkCanvas::SaveLayerRec rec;
|
||||
rec.fClipMatrix = &clipMatrix;
|
||||
|
||||
for (const auto& paintMaker : kPaintMakers) {
|
||||
auto layerPaint = paintMaker();
|
||||
rec.fPaint = &layerPaint;
|
||||
|
||||
for (const auto& maskMaker : kMaskMakers) {
|
||||
maskMaker(kSize);
|
||||
rec.fClipMask = maskMaker(kSize);
|
||||
|
||||
canvas->save();
|
||||
for (const auto cfg : kConfigs) {
|
||||
rec.fBounds = cfg.bounds;
|
||||
clipMatrix.set9(cfg.matrix);
|
||||
canvas->saveLayer(rec);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(0xff0000ff);
|
||||
canvas->drawRect(SkRect::MakeWH(50, 50), paint);
|
||||
paint.setColor(0xffff0000);
|
||||
canvas->drawRect(SkRect::MakeXYWH(50, 0, 50, 50), paint);
|
||||
paint.setColor(0xff00ff00);
|
||||
canvas->drawRect(SkRect::MakeXYWH(50, 50, 50, 50), paint);
|
||||
paint.setColor(0xffffff00);
|
||||
canvas->drawRect(SkRect::MakeXYWH(0, 50, 50, 50), paint);
|
||||
|
||||
canvas->restore();
|
||||
canvas->translate(120, 0);
|
||||
}
|
||||
canvas->restore();
|
||||
canvas->translate(0, 120);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,27 +323,29 @@ public:
|
||||
typedef uint32_t SaveLayerFlags;
|
||||
|
||||
struct SaveLayerRec {
|
||||
SaveLayerRec()
|
||||
: fBounds(nullptr), fPaint(nullptr), fBackdrop(nullptr), fSaveLayerFlags(0)
|
||||
{}
|
||||
SaveLayerRec() {}
|
||||
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
|
||||
: fBounds(bounds)
|
||||
, fPaint(paint)
|
||||
, fBackdrop(nullptr)
|
||||
, fSaveLayerFlags(saveLayerFlags)
|
||||
{}
|
||||
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
|
||||
sk_sp<SkImage> clipMask, const SkMatrix* clipMatrix,
|
||||
SaveLayerFlags saveLayerFlags)
|
||||
: fBounds(bounds)
|
||||
, fPaint(paint)
|
||||
, fBackdrop(backdrop)
|
||||
, fClipMask(std::move(clipMask))
|
||||
, fClipMatrix(clipMatrix)
|
||||
, fSaveLayerFlags(saveLayerFlags)
|
||||
{}
|
||||
|
||||
const SkRect* fBounds; // optional
|
||||
const SkPaint* fPaint; // optional
|
||||
const SkImageFilter* fBackdrop; // optional
|
||||
SaveLayerFlags fSaveLayerFlags;
|
||||
const SkRect* fBounds = nullptr; // optional
|
||||
const SkPaint* fPaint = nullptr; // optional
|
||||
const SkImageFilter* fBackdrop = nullptr; // optional
|
||||
sk_sp<SkImage> fClipMask; // optional
|
||||
const SkMatrix* fClipMatrix = nullptr; // optional -- only used with fClipMask
|
||||
SaveLayerFlags fSaveLayerFlags = 0;
|
||||
};
|
||||
|
||||
int saveLayer(const SaveLayerRec&);
|
||||
@ -1489,7 +1491,7 @@ private:
|
||||
enum {
|
||||
kMCRecSize = 128, // most recent measurement
|
||||
kMCRecCount = 32, // common depth for save/restores
|
||||
kDeviceCMSize = 184, // most recent measurement
|
||||
kDeviceCMSize = 224, // most recent measurement
|
||||
};
|
||||
intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
|
||||
intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
|
||||
@ -1561,7 +1563,8 @@ private:
|
||||
SrcRectConstraint);
|
||||
void internalDrawPaint(const SkPaint& paint);
|
||||
void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, SkImage* clipImage,
|
||||
const SkMatrix& clipMatrix);
|
||||
|
||||
// shared by save() and saveLayer()
|
||||
void internalSave();
|
||||
|
@ -200,10 +200,11 @@ private:
|
||||
// V50: SkXfermode -> SkBlendMode
|
||||
// V51: more SkXfermode -> SkBlendMode
|
||||
// V52: Remove SkTextBlob::fRunCount
|
||||
// V53: SaveLayerRec clip mask
|
||||
|
||||
// Only SKPs within the min/current picture version range (inclusive) can be read.
|
||||
static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39.
|
||||
static const uint32_t CURRENT_PICTURE_VERSION = 52;
|
||||
static const uint32_t CURRENT_PICTURE_VERSION = 53;
|
||||
|
||||
static_assert(MIN_PICTURE_VERSION <= 41,
|
||||
"Remove kFontFileName and related code from SkFontDescriptor.cpp.");
|
||||
|
@ -180,6 +180,8 @@ RECORD(SaveLayer, kHasPaint_Tag,
|
||||
Optional<SkRect> bounds;
|
||||
Optional<SkPaint> paint;
|
||||
sk_sp<const SkImageFilter> backdrop;
|
||||
sk_sp<SkImage> clipMask;
|
||||
Optional<SkMatrix> clipMatrix;
|
||||
SkCanvas::SaveLayerFlags saveLayerFlags);
|
||||
|
||||
RECORD(SetMatrix, 0,
|
||||
|
@ -260,7 +260,7 @@ protected:
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAlpha(0xCC);
|
||||
canvas->saveLayer({ &bounds, &paint, fFilter.get(), 0 });
|
||||
canvas->saveLayer({ &bounds, &paint, fFilter.get(), nullptr, nullptr, 0 });
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "SkShader.h"
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkTLazy.h"
|
||||
#include "SkVertices.h"
|
||||
|
||||
class SkColorTable;
|
||||
@ -387,35 +388,71 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPain
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(!srcImg->isTextureBacked());
|
||||
void SkBitmapDevice::drawSpecial(SkSpecialImage* src, int x, int y, const SkPaint& origPaint,
|
||||
SkImage* clipImage, const SkMatrix& clipMatrix) {
|
||||
SkASSERT(!src->isTextureBacked());
|
||||
|
||||
SkBitmap resultBM;
|
||||
sk_sp<SkSpecialImage> filteredImage;
|
||||
SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
|
||||
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
if (filter) {
|
||||
if (SkImageFilter* filter = paint->getImageFilter()) {
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkMatrix matrix = this->ctm();
|
||||
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
const SkMatrix matrix = SkMatrix::Concat(
|
||||
SkMatrix::MakeTrans(SkIntToScalar(-x), SkIntToScalar(-y)), this->ctm());
|
||||
const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
|
||||
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
|
||||
SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
|
||||
|
||||
sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
|
||||
if (resultImg) {
|
||||
SkPaint tmpUnfiltered(paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
if (resultImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (srcImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x, y, paint);
|
||||
filteredImage = filter->filterImage(src, ctx, &offset);
|
||||
if (!filteredImage) {
|
||||
return;
|
||||
}
|
||||
|
||||
src = filteredImage.get();
|
||||
paint.writable()->setImageFilter(nullptr);
|
||||
x += offset.x();
|
||||
y += offset.y();
|
||||
}
|
||||
|
||||
if (!clipImage) {
|
||||
SkBitmap resultBM;
|
||||
if (src->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x, y, *paint);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Clip image case.
|
||||
sk_sp<SkImage> srcImage(src->asImage());
|
||||
if (!srcImage) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SkMatrix totalMatrix = SkMatrix::Concat(this->ctm(), clipMatrix);
|
||||
|
||||
SkRect clipBounds;
|
||||
totalMatrix.mapRect(&clipBounds, SkRect::Make(clipImage->bounds()));
|
||||
const SkIRect srcBounds = srcImage->bounds().makeOffset(x, y);
|
||||
|
||||
SkIRect maskBounds = fRCStack.rc().getBounds();
|
||||
if (!maskBounds.intersect(clipBounds.roundOut()) || !maskBounds.intersect(srcBounds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sk_sp<SkSurface> surf = SkSurface::MakeRaster(SkImageInfo::MakeA8(maskBounds.width(),
|
||||
maskBounds.height()));
|
||||
SkCanvas* canvas = surf->getCanvas();
|
||||
canvas->translate(-maskBounds.x(), -maskBounds.y());
|
||||
canvas->concat(totalMatrix);
|
||||
canvas->drawImage(clipImage, 0, 0);
|
||||
sk_sp<SkImage> mask = surf->makeImageSnapshot();
|
||||
|
||||
const SkMatrix m = SkMatrix::MakeTrans(x - maskBounds.x(), y - maskBounds.y());
|
||||
paint.writable()->setShader(srcImage->makeShader(&m));
|
||||
|
||||
SkAutoDeviceCTMRestore adctmr(this, SkMatrix::I());
|
||||
this->drawImage(mask.get(), maskBounds.x(), maskBounds.y(), *paint);
|
||||
}
|
||||
|
||||
sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {
|
||||
|
@ -112,7 +112,8 @@ protected:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
|
||||
SkImage*, const SkMatrix&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
sk_sp<SkSpecialImage> snapSpecial() override;
|
||||
|
@ -253,12 +253,17 @@ struct DeviceCM {
|
||||
SkRasterClip fClip;
|
||||
std::unique_ptr<const SkPaint> fPaint; // may be null (in the future)
|
||||
SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
|
||||
sk_sp<SkImage> fClipImage;
|
||||
SkMatrix fClipMatrix;
|
||||
|
||||
DeviceCM(sk_sp<SkBaseDevice> device, const SkPaint* paint, const SkMatrix& stashed)
|
||||
DeviceCM(sk_sp<SkBaseDevice> device, const SkPaint* paint, const SkMatrix& stashed,
|
||||
sk_sp<SkImage> clipImage, const SkMatrix* clipMatrix)
|
||||
: fNext(nullptr)
|
||||
, fDevice(std::move(device))
|
||||
, fPaint(paint ? skstd::make_unique<SkPaint>(*paint) : nullptr)
|
||||
, fStashedMatrix(stashed)
|
||||
, fClipImage(std::move(clipImage))
|
||||
, fClipMatrix(clipMatrix ? *clipMatrix : SkMatrix::I())
|
||||
{}
|
||||
|
||||
void reset(const SkIRect& bounds) {
|
||||
@ -649,7 +654,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
|
||||
|
||||
SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
|
||||
fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
|
||||
new (fDeviceCMStorage) DeviceCM(sk_ref_sp(device), nullptr, fMCRec->fMatrix);
|
||||
new (fDeviceCMStorage) DeviceCM(sk_ref_sp(device), nullptr, fMCRec->fMatrix, nullptr, nullptr);
|
||||
|
||||
fMCRec->fTopLayer = fMCRec->fLayer;
|
||||
|
||||
@ -1010,13 +1015,14 @@ int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPai
|
||||
}
|
||||
|
||||
int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
|
||||
SaveLayerRec rec(origRec);
|
||||
SkTCopyOnFirstWrite<SaveLayerRec> rec(origRec);
|
||||
if (gIgnoreSaveLayerBounds) {
|
||||
rec.fBounds = nullptr;
|
||||
rec.writable()->fBounds = nullptr;
|
||||
}
|
||||
SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec);
|
||||
|
||||
SaveLayerStrategy strategy = this->getSaveLayerStrategy(*rec);
|
||||
fSaveCount += 1;
|
||||
this->internalSaveLayer(rec, strategy);
|
||||
this->internalSaveLayer(*rec, strategy);
|
||||
return this->getSaveCount() - 1;
|
||||
}
|
||||
|
||||
@ -1041,7 +1047,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
|
||||
int y = src->getOrigin().y() - dstOrigin.y();
|
||||
auto special = src->snapSpecial();
|
||||
if (special) {
|
||||
dst->drawSpecial(special.get(), x, y, p);
|
||||
dst->drawSpecial(special.get(), x, y, p, nullptr, SkMatrix::I());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1148,7 +1154,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
|
||||
return;
|
||||
}
|
||||
}
|
||||
DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix);
|
||||
DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix, rec.fClipMask, rec.fClipMatrix);
|
||||
|
||||
// only have a "next" if this new layer doesn't affect the clip (rare)
|
||||
layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
|
||||
@ -1209,7 +1215,8 @@ void SkCanvas::internalRestore() {
|
||||
if (fMCRec) {
|
||||
const SkIPoint& origin = layer->fDevice->getOrigin();
|
||||
this->internalDrawDevice(layer->fDevice.get(), origin.x(), origin.y(),
|
||||
layer->fPaint.get());
|
||||
layer->fPaint.get(),
|
||||
layer->fClipImage.get(), layer->fClipMatrix);
|
||||
// restore what we smashed in internalSaveLayer
|
||||
fMCRec->fMatrix = layer->fStashedMatrix;
|
||||
// reset this, since internalDrawDevice will have set it to true
|
||||
@ -1302,7 +1309,8 @@ bool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint) {
|
||||
void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint,
|
||||
SkImage* clipImage, const SkMatrix& clipMatrix) {
|
||||
SkPaint tmp;
|
||||
if (nullptr == paint) {
|
||||
paint = &tmp;
|
||||
@ -1315,10 +1323,11 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
|
||||
paint = &looper.paint();
|
||||
SkImageFilter* filter = paint->getImageFilter();
|
||||
SkIPoint pos = { x - iter.getX(), y - iter.getY() };
|
||||
if (filter) {
|
||||
if (filter || clipImage) {
|
||||
sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
|
||||
if (specialImage) {
|
||||
dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint);
|
||||
dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint,
|
||||
clipImage, clipMatrix);
|
||||
}
|
||||
} else {
|
||||
dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
|
||||
@ -2219,7 +2228,8 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
|
||||
iter.fDevice->ctm().mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(special.get(),
|
||||
SkScalarRoundToInt(pt.fX),
|
||||
SkScalarRoundToInt(pt.fY), pnt);
|
||||
SkScalarRoundToInt(pt.fY), pnt,
|
||||
nullptr, SkMatrix::I());
|
||||
} else {
|
||||
iter.fDevice->drawImage(image, x, y, pnt);
|
||||
}
|
||||
@ -2300,7 +2310,8 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
|
||||
iter.fDevice->ctm().mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(special.get(),
|
||||
SkScalarRoundToInt(pt.fX),
|
||||
SkScalarRoundToInt(pt.fY), pnt);
|
||||
SkScalarRoundToInt(pt.fY), pnt,
|
||||
nullptr, SkMatrix::I());
|
||||
} else {
|
||||
iter.fDevice->drawBitmap(bitmap, matrix, looper.paint());
|
||||
}
|
||||
|
@ -229,10 +229,13 @@ public:
|
||||
|
||||
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
|
||||
sk_sp<SkImageFilter> backdrop = rec.fBackdrop ? fXformer->apply(rec.fBackdrop) : nullptr;
|
||||
sk_sp<SkImage> clipMask = rec.fClipMask ? fXformer->apply(rec.fClipMask.get()) : nullptr;
|
||||
fTarget->saveLayer({
|
||||
rec.fBounds,
|
||||
MaybePaint(rec.fPaint, fXformer.get()),
|
||||
backdrop.get(),
|
||||
std::move(clipMask),
|
||||
rec.fClipMatrix,
|
||||
rec.fSaveLayerFlags,
|
||||
});
|
||||
return kNoLayer_SaveLayerStrategy;
|
||||
|
@ -282,7 +282,8 @@ void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) {}
|
||||
void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
|
||||
SkImage*, const SkMatrix&) {}
|
||||
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkBitmap&) { return nullptr; }
|
||||
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkImage*) { return nullptr; }
|
||||
sk_sp<SkSpecialImage> SkBaseDevice::snapSpecial() { return nullptr; }
|
||||
|
@ -258,7 +258,8 @@ protected:
|
||||
virtual void drawTextRSXform(const void* text, size_t len, const SkRSXform[],
|
||||
const SkPaint&);
|
||||
|
||||
virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&);
|
||||
virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
|
||||
SkImage* clipImage, const SkMatrix& clipMatrix);
|
||||
virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
|
||||
virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
|
||||
virtual sk_sp<SkSpecialImage> snapSpecial();
|
||||
|
@ -96,6 +96,8 @@ public:
|
||||
SkMask* mask, SkMask::CreateMode mode,
|
||||
SkStrokeRec::InitStyle style);
|
||||
|
||||
void drawDevMask(const SkMask& mask, const SkPaint&) const;
|
||||
|
||||
enum RectType {
|
||||
kHair_RectType,
|
||||
kFill_RectType,
|
||||
@ -122,7 +124,6 @@ public:
|
||||
const SkPaint&, const SkSurfaceProps*) const;
|
||||
static SkScalar ComputeResScaleForStroking(const SkMatrix& );
|
||||
private:
|
||||
void drawDevMask(const SkMask& mask, const SkPaint&) const;
|
||||
void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
|
||||
|
||||
void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix,
|
||||
|
@ -91,18 +91,24 @@ namespace {
|
||||
struct SaveLayer final : Op {
|
||||
static const auto kType = Type::SaveLayer;
|
||||
SaveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) {
|
||||
const SkImageFilter* backdrop, sk_sp<SkImage> clipMask,
|
||||
const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
|
||||
if (bounds) { this->bounds = *bounds; }
|
||||
if (paint) { this->paint = *paint; }
|
||||
this->backdrop = sk_ref_sp(backdrop);
|
||||
this->clipMask = std::move(clipMask);
|
||||
this->clipMatrix = clipMatrix ? *clipMatrix : SkMatrix::I();
|
||||
this->flags = flags;
|
||||
}
|
||||
SkRect bounds = kUnset;
|
||||
SkPaint paint;
|
||||
sk_sp<const SkImageFilter> backdrop;
|
||||
sk_sp<SkImage> clipMask;
|
||||
SkMatrix clipMatrix;
|
||||
SkCanvas::SaveLayerFlags flags;
|
||||
void draw(SkCanvas* c, const SkMatrix&) const {
|
||||
c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags });
|
||||
c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), clipMask,
|
||||
clipMatrix.isIdentity() ? nullptr : &clipMatrix, flags });
|
||||
}
|
||||
};
|
||||
|
||||
@ -544,8 +550,9 @@ void SkLiteDL::setDrawFilter(SkDrawFilter* df) {
|
||||
void SkLiteDL:: save() { this->push <Save>(0); }
|
||||
void SkLiteDL::restore() { this->push<Restore>(0); }
|
||||
void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) {
|
||||
this->push<SaveLayer>(0, bounds, paint, backdrop, flags);
|
||||
const SkImageFilter* backdrop, sk_sp<SkImage> clipMask,
|
||||
const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
|
||||
this->push<SaveLayer>(0, bounds, paint, backdrop, std::move(clipMask), clipMatrix, flags);
|
||||
}
|
||||
|
||||
void SkLiteDL:: concat(const SkMatrix& matrix) { this->push <Concat>(0, matrix); }
|
||||
|
@ -29,7 +29,8 @@ public:
|
||||
#endif
|
||||
|
||||
void save();
|
||||
void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, SkCanvas::SaveLayerFlags);
|
||||
void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, sk_sp<SkImage>,
|
||||
const SkMatrix*, SkCanvas::SaveLayerFlags);
|
||||
void restore();
|
||||
|
||||
void concat (const SkMatrix&);
|
||||
|
@ -31,7 +31,8 @@ SkDrawFilter* SkLiteRecorder::setDrawFilter(SkDrawFilter* df) {
|
||||
|
||||
void SkLiteRecorder::willSave() { fDL->save(); }
|
||||
SkCanvas::SaveLayerStrategy SkLiteRecorder::getSaveLayerStrategy(const SaveLayerRec& rec) {
|
||||
fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fSaveLayerFlags);
|
||||
fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fClipMask, rec.fClipMatrix,
|
||||
rec.fSaveLayerFlags);
|
||||
return SkCanvas::kNoLayer_SaveLayerStrategy;
|
||||
}
|
||||
void SkLiteRecorder::willRestore() { fDL->restore(); }
|
||||
|
@ -122,6 +122,8 @@ enum SaveLayerRecFlatFlags {
|
||||
SAVELAYERREC_HAS_PAINT = 1 << 1,
|
||||
SAVELAYERREC_HAS_BACKDROP = 1 << 2,
|
||||
SAVELAYERREC_HAS_FLAGS = 1 << 3,
|
||||
SAVELAYERREC_HAS_CLIPMASK = 1 << 4,
|
||||
SAVELAYERREC_HAS_CLIPMATRIX = 1 << 5,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -724,7 +724,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
||||
canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
|
||||
} break;
|
||||
case SAVE_LAYER_SAVELAYERREC: {
|
||||
SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0);
|
||||
SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, nullptr, nullptr, 0);
|
||||
SkMatrix clipMatrix;
|
||||
const uint32_t flatFlags = reader->readInt();
|
||||
SkRect bounds;
|
||||
if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
|
||||
@ -742,6 +743,13 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
||||
if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
|
||||
rec.fSaveLayerFlags = reader->readInt();
|
||||
}
|
||||
if (flatFlags & SAVELAYERREC_HAS_CLIPMASK) {
|
||||
rec.fClipMask = sk_ref_sp(const_cast<SkImage*>(fPictureData->getImage(reader)));
|
||||
}
|
||||
if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX) {
|
||||
reader->readMatrix(&clipMatrix);
|
||||
rec.fClipMatrix = &clipMatrix;
|
||||
}
|
||||
BREAK_ON_READ_ERROR(reader);
|
||||
|
||||
canvas->saveLayer(rec);
|
||||
|
@ -98,6 +98,14 @@ void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) {
|
||||
flatFlags |= SAVELAYERREC_HAS_FLAGS;
|
||||
size += sizeof(uint32_t);
|
||||
}
|
||||
if (rec.fClipMask) {
|
||||
flatFlags |= SAVELAYERREC_HAS_CLIPMASK;
|
||||
size += sizeof(uint32_t); // clip image index
|
||||
}
|
||||
if (rec.fClipMatrix) {
|
||||
flatFlags |= SAVELAYERREC_HAS_CLIPMATRIX;
|
||||
size += rec.fClipMatrix->writeToMemory(nullptr);
|
||||
}
|
||||
|
||||
const size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERREC, &size);
|
||||
this->addInt(flatFlags);
|
||||
@ -116,6 +124,12 @@ void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) {
|
||||
if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
|
||||
this->addInt(rec.fSaveLayerFlags);
|
||||
}
|
||||
if (flatFlags & SAVELAYERREC_HAS_CLIPMASK) {
|
||||
this->addImage(rec.fClipMask.get());
|
||||
}
|
||||
if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX) {
|
||||
this->addMatrix(*rec.fClipMatrix);
|
||||
}
|
||||
this->validate(initialOffset, size);
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,8 @@ DRAW(Save, save());
|
||||
DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds,
|
||||
r.paint,
|
||||
r.backdrop.get(),
|
||||
r.clipMask,
|
||||
r.clipMatrix,
|
||||
r.saveLayerFlags)));
|
||||
DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
|
||||
DRAW(Concat, concat(r.matrix));
|
||||
|
@ -188,8 +188,8 @@ struct SaveLayerDrawRestoreNooper {
|
||||
typedef Pattern<Is<SaveLayer>, IsDraw, Is<Restore>> Match;
|
||||
|
||||
bool onMatch(SkRecord* record, Match* match, int begin, int end) {
|
||||
if (match->first<SaveLayer>()->backdrop) {
|
||||
// can't throw away the layer if we have a backdrop
|
||||
if (match->first<SaveLayer>()->backdrop || match->first<SaveLayer>()->clipMask) {
|
||||
// can't throw away the layer if we have a backdrop or clip mask
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -366,6 +366,8 @@ SkCanvas::SaveLayerStrategy SkRecorder::getSaveLayerStrategy(const SaveLayerRec&
|
||||
APPEND(SaveLayer, this->copy(rec.fBounds)
|
||||
, this->copy(rec.fPaint)
|
||||
, sk_ref_sp(rec.fBackdrop)
|
||||
, rec.fClipMask
|
||||
, this->copy(rec.fClipMatrix)
|
||||
, rec.fSaveLayerFlags);
|
||||
return SkCanvas::kNoLayer_SaveLayerStrategy;
|
||||
}
|
||||
|
@ -1125,17 +1125,18 @@ void SkGpuDevice::drawSprite(const SkBitmap& bitmap,
|
||||
return;
|
||||
}
|
||||
|
||||
this->drawSpecial(srcImg.get(), left, top, paint);
|
||||
this->drawSpecial(srcImg.get(), left, top, paint, nullptr, SkMatrix::I());
|
||||
}
|
||||
|
||||
|
||||
void SkGpuDevice::drawSpecial(SkSpecialImage* special1,
|
||||
int left, int top,
|
||||
const SkPaint& paint) {
|
||||
void SkGpuDevice::drawSpecial(SkSpecialImage* special1, int left, int top, const SkPaint& paint,
|
||||
SkImage* clipImage,const SkMatrix& clipMatrix) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSpecial", fContext.get());
|
||||
|
||||
// TODO: clipImage support.
|
||||
|
||||
SkIPoint offset = { 0, 0 };
|
||||
|
||||
sk_sp<SkSpecialImage> result;
|
||||
@ -1354,7 +1355,7 @@ void SkGpuDevice::drawDevice(SkBaseDevice* device,
|
||||
return;
|
||||
}
|
||||
|
||||
this->drawSpecial(srcImg.get(), left, top, paint);
|
||||
this->drawSpecial(srcImg.get(), left, top, paint, nullptr, SkMatrix::I());
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
|
||||
|
@ -110,8 +110,8 @@ public:
|
||||
void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&) override;
|
||||
|
||||
void drawSpecial(SkSpecialImage*,
|
||||
int left, int top, const SkPaint& paint) override;
|
||||
void drawSpecial(SkSpecialImage*, int left, int top, const SkPaint& paint,
|
||||
SkImage*, const SkMatrix&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
sk_sp<SkSpecialImage> snapSpecial() override;
|
||||
|
@ -2202,10 +2202,12 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkImageFilter.h"
|
||||
|
||||
void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y, const SkPaint& paint,
|
||||
SkImage* clipImage, const SkMatrix& clipMatrix) {
|
||||
SkASSERT(!srcImg->isTextureBacked());
|
||||
|
||||
//TODO: clipImage support
|
||||
|
||||
SkBitmap resultBM;
|
||||
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
|
@ -170,7 +170,8 @@ protected:
|
||||
|
||||
void drawAnnotation(const SkRect&, const char key[], SkData* value) override;
|
||||
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
|
||||
SkImage*, const SkMatrix&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
sk_sp<SkSpecialImage> snapSpecial() override;
|
||||
|
@ -240,6 +240,12 @@ SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRe
|
||||
if (rec.fBackdrop) {
|
||||
extra |= kHasBackdrop_SaveLayerMask;
|
||||
}
|
||||
if (rec.fClipMask) {
|
||||
extra |= kHasClipMask_SaveLayerMask;
|
||||
}
|
||||
if (rec.fClipMatrix) {
|
||||
extra |= kHasClipMatrix_SaveLayerMask;
|
||||
}
|
||||
|
||||
writer.write32(pack_verb(SkPipeVerb::kSaveLayer, extra));
|
||||
if (rec.fBounds) {
|
||||
@ -251,6 +257,13 @@ SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRe
|
||||
if (rec.fBackdrop) {
|
||||
writer.writeFlattenable(rec.fBackdrop);
|
||||
}
|
||||
if (rec.fClipMask) {
|
||||
writer.writeImage(rec.fClipMask.get());
|
||||
}
|
||||
if (rec.fClipMatrix) {
|
||||
writer.writeMatrix(*rec.fClipMatrix);
|
||||
}
|
||||
|
||||
return kNoLayer_SaveLayerStrategy;
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,8 @@ enum {
|
||||
kHasPaint_SaveLayerMask = 1 << 9,
|
||||
kHasBackdrop_SaveLayerMask = 1 << 10,
|
||||
kDontClipToLayer_SaveLayerMask = 1 << 11,
|
||||
kHasClipMask_SaveLayerMask = 1 << 12,
|
||||
kHasClipMatrix_SaveLayerMask = 1 << 13,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -244,6 +244,14 @@ static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva
|
||||
if (extra & kHasBackdrop_SaveLayerMask) {
|
||||
backdrop = reader.readImageFilter();
|
||||
}
|
||||
sk_sp<SkImage> clipMask;
|
||||
if (extra & kHasClipMask_SaveLayerMask) {
|
||||
clipMask = reader.readImage();
|
||||
}
|
||||
SkMatrix clipMatrix;
|
||||
if (extra & kHasClipMatrix_SaveLayerMask) {
|
||||
reader.readMatrix(&clipMatrix);
|
||||
}
|
||||
SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask);
|
||||
|
||||
// unremap this wacky flag
|
||||
@ -251,7 +259,8 @@ static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva
|
||||
flags |= (1 << 31);//SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag;
|
||||
}
|
||||
|
||||
canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), flags));
|
||||
canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), std::move(clipMask),
|
||||
(extra & kHasClipMatrix_SaveLayerMask) ? &clipMatrix : nullptr, flags));
|
||||
}
|
||||
|
||||
static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
|
||||
|
@ -190,10 +190,19 @@ DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
|
||||
|
||||
// saveLayer w/ backdrop should NOT go away
|
||||
sk_sp<SkImageFilter> filter(SkBlurImageFilter::Make(3, 3, nullptr));
|
||||
recorder.saveLayer({ nullptr, nullptr, filter.get(), 0});
|
||||
recorder.saveLayer({ nullptr, nullptr, filter.get(), nullptr, nullptr, 0});
|
||||
recorder.drawRect(draw, opaqueDrawPaint);
|
||||
recorder.restore();
|
||||
assert_savelayer_draw_restore(r, &record, 18, false);
|
||||
|
||||
// saveLayer w/ clip mask should also NOT go away
|
||||
{
|
||||
sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(10, 10));
|
||||
recorder.saveLayer({ nullptr, nullptr, nullptr, surface->makeImageSnapshot(), nullptr, 0});
|
||||
recorder.drawRect(draw, opaqueDrawPaint);
|
||||
recorder.restore();
|
||||
assert_savelayer_draw_restore(r, &record, 21, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -265,10 +274,12 @@ DEF_TEST(RecordOpts_MergeSvgOpacityAndFilterLayers, r) {
|
||||
for (size_t m = 0; m < SK_ARRAY_COUNT(secondPaints); ++m) {
|
||||
bool innerNoOped = !secondBounds[k] && !secondPaints[m] && !innerF;
|
||||
|
||||
recorder.saveLayer({firstBounds[i], firstPaints[j], outerF, 0});
|
||||
recorder.saveLayer({firstBounds[i], firstPaints[j], outerF,
|
||||
nullptr, nullptr, 0});
|
||||
recorder.save();
|
||||
recorder.clipRect(clip);
|
||||
recorder.saveLayer({secondBounds[k], secondPaints[m], innerF, 0});
|
||||
recorder.saveLayer({secondBounds[k], secondPaints[m], innerF,
|
||||
nullptr, nullptr, 0});
|
||||
recorder.restore();
|
||||
recorder.restore();
|
||||
recorder.restore();
|
||||
|
Loading…
Reference in New Issue
Block a user