remove (unused) clipmask from savelayer

Change-Id: I44f64a8c98c019a8f4878b0b6f6d82489aa8252c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/296179
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-06-13 10:02:53 -04:00 committed by Skia Commit-Bot
parent 08ac84a66a
commit 82d619699d
20 changed files with 32 additions and 510 deletions

View File

@ -14,61 +14,6 @@
#include "include/core/SkSurface.h"
#include "tools/ToolUtils.h"
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
static void DrawMask(SkCanvas* canvas) {
ToolUtils::draw_checkerboard(canvas, SK_ColorTRANSPARENT, SK_ColorGREEN, 10);
}
class ClipMaskBench : public Benchmark {
public:
using MaskMakerFunc = sk_sp<SkImage> (*)(int);
ClipMaskBench(const char name[], const MaskMakerFunc maskMaker)
: fName(SkStringPrintf("clipmask_%s", name))
, fClip(maskMaker(kSize)) {}
protected:
const char* onGetName() override { return fName.c_str(); }
void onDraw(int loops, SkCanvas* canvas) override {
SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, fClip.get(), nullptr, 0);
for (int i = 0; i < loops; ++i) {
canvas->saveLayer(rec);
canvas->drawColor(SK_ColorBLUE);
canvas->restore();
}
}
private:
static constexpr int kSize = 400;
SkString fName;
sk_sp<SkImage> fClip;
};
DEF_BENCH(return new ClipMaskBench("a8", [](int size) -> sk_sp<SkImage> {
sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeA8(size, size));
DrawMask(surface->getCanvas());
return surface->makeImageSnapshot();
});)
DEF_BENCH(return new ClipMaskBench("8888", [](int size) -> sk_sp<SkImage> {
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(size, size);
DrawMask(surface->getCanvas());
return surface->makeImageSnapshot();
});)
DEF_BENCH(return new ClipMaskBench("picture", [](int size) -> sk_sp<SkImage> {
SkPictureRecorder recorder;
DrawMask(recorder.beginRecording(size, size));
return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), SkISize::Make(size, size),
nullptr, nullptr, SkImage::BitDepth::kU8,
SkColorSpace::MakeSRGB());
});)
#endif
/////////
#include "include/core/SkPath.h"
#include "include/core/SkSurface.h"

View File

@ -134,118 +134,6 @@ DEF_SIMPLE_GM(savelayer_initfromprev, canvas, 256, 256) {
canvas->restore();
};
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
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,
SkTileMode::kClamp));
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(SkImageFilters::Blur(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) {
sk_sp<SkImage> mask = maskMaker(kSize);
rec.fClipMask = mask.get();
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);
}
}
}
#endif
DEF_SIMPLE_GM(savelayer_coverage, canvas, 500, 500) {
canvas->saveLayer(nullptr, nullptr);
@ -284,67 +172,6 @@ DEF_SIMPLE_GM(savelayer_coverage, canvas, 500, 500) {
canvas->restore();
}
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
DEF_SIMPLE_GM(savelayer_clipmask_maskfilter, canvas, 500, 500) {
// Offscreen surface for making the clip mask and mask filter images
auto surf = SkSurface::MakeRaster(SkImageInfo::MakeA8(100, 100));
SkPaint maskPaint;
maskPaint.setColor(SK_ColorWHITE);
maskPaint.setAntiAlias(true);
// Draw a centered circle for the mask filter
surf->getCanvas()->clear(SK_ColorTRANSPARENT);
surf->getCanvas()->drawCircle(50.f, 50.f, 50.f, maskPaint);
auto maskFilterImage = surf->makeImageSnapshot();
sk_sp<SkMaskFilter> maskFilter = SkShaderMaskFilter::Make(maskFilterImage->makeShader());
// Cut out a cross for the clip mask
surf->getCanvas()->clear(SK_ColorTRANSPARENT);
surf->getCanvas()->drawRect(SkRect::MakeLTRB(0.f, 0.f, 40.f, 40.f), maskPaint);
surf->getCanvas()->drawRect(SkRect::MakeLTRB(60.f, 0.f, 100.f, 40.f), maskPaint);
surf->getCanvas()->drawRect(SkRect::MakeLTRB(0.f, 60.f, 40.f, 100.f), maskPaint);
surf->getCanvas()->drawRect(SkRect::MakeLTRB(60.f, 60.f, 100.f, 100.f), maskPaint);
auto clipMaskImage = surf->makeImageSnapshot();
SkMatrix clipMatrix = SkMatrix::I();
SkRect clipBounds = SkRect::MakeWH(100, 100);
// On the main canvas, save a 100x100 layer three times, applying clip mask, mask filter, or
// both, translating across the GM for each configuration. Since the mask filter is provided
// on the layer restore paint, it must be ignored by the restore since coverage is not well
// defined.
canvas->clear(SK_ColorGRAY);
canvas->translate(25.f, 0.f);
// Clip mask only
SkCanvas::SaveLayerRec rec;
rec.fBounds = &clipBounds;
rec.fClipMask = clipMaskImage.get();
rec.fClipMatrix = &clipMatrix;
canvas->saveLayer(rec);
canvas->clear(SK_ColorWHITE);
canvas->restore();
canvas->translate(125.f, 0.f);
// Mask filter only (should be ignored, producing a white square)
maskPaint.setMaskFilter(maskFilter);
rec.fClipMask = nullptr;
rec.fPaint = &maskPaint;
canvas->saveLayer(rec);
canvas->clear(SK_ColorWHITE);
canvas->restore();
canvas->translate(125.f, 0.f);
// Both (mask filter is ignored, but clip mask should not, so should look like first draw)
rec.fClipMask = clipMaskImage.get();
canvas->saveLayer(rec);
canvas->clear(SK_ColorWHITE);
canvas->restore();
}
#endif
static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkScalar w, SkScalar h,
bool useDrawBehind) {
SkRect r = SkRect::MakeWH(w, h);

View File

@ -684,37 +684,6 @@ public:
, fSaveLayerFlags(saveLayerFlags)
{}
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
/** Experimental. Not ready for general use.
Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
clipMatrix uses alpha channel of image, transformed by clipMatrix, to clip
layer when drawn to SkCanvas.
@param bounds layer dimensions; may be nullptr
@param paint graphics state applied to layer when overlaying prior
layer; may be nullptr
@param backdrop If not null, this causes the current layer to be filtered by
backdrop, and then drawn into the new layer
(respecting the current clip).
If null, the new layer is initialized with transparent-black.
@param clipMask clip applied to layer; may be nullptr
@param clipMatrix matrix applied to clipMask; may be nullptr to use
identity matrix
@param saveLayerFlags SaveLayerRec options to modify layer
@return SaveLayerRec fully specified
*/
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
const SkImage* clipMask, const SkMatrix* clipMatrix,
SaveLayerFlags saveLayerFlags)
: fBounds(bounds)
, fPaint(paint)
, fBackdrop(backdrop)
, fClipMask(clipMask)
, fClipMatrix(clipMatrix)
, fSaveLayerFlags(saveLayerFlags)
{}
#endif
/** hints at layer size limit */
const SkRect* fBounds = nullptr;
@ -729,13 +698,6 @@ public:
*/
const SkImageFilter* fBackdrop = nullptr;
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
/** clips layer with mask alpha */
const SkImage* fClipMask = nullptr;
/** transforms mask alpha used to clip */
const SkMatrix* fClipMatrix = nullptr;
#endif
/** preserves LCD text, creates with prior layer contents */
SaveLayerFlags fSaveLayerFlags = 0;
};
@ -2759,8 +2721,7 @@ private:
void internalDrawPaint(const SkPaint& paint);
void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
void internalSaveBehind(const SkRect*);
void internalDrawDevice(SkBaseDevice*, const SkPaint*, SkImage* clipImage,
const SkMatrix& clipMatrix);
void internalDrawDevice(SkBaseDevice*, const SkPaint*);
void internalConcat44(const SkM44&);

View File

@ -593,32 +593,7 @@ void SkBitmapDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
///////////////////////////////////////////////////////////////////////////////
namespace {
class SkAutoDeviceClipRestore {
public:
SkAutoDeviceClipRestore(SkBaseDevice* device, const SkIRect& clip)
: fDevice(device)
, fPrevLocalToDevice(device->localToDevice44()) {
fDevice->save();
fDevice->setLocalToDevice(SkM44());
fDevice->clipRect(SkRect::Make(clip), SkClipOp::kIntersect, false);
fDevice->setLocalToDevice(fPrevLocalToDevice);
}
~SkAutoDeviceClipRestore() {
fDevice->restoreLocal(fPrevLocalToDevice);
}
private:
SkBaseDevice* fDevice;
const SkM44 fPrevLocalToDevice;
};
} // anonymous ns
void SkBitmapDevice::drawSpecial(SkSpecialImage* src, int x, int y, const SkPaint& origPaint,
SkImage* clipImage, const SkMatrix& clipMatrix) {
void SkBitmapDevice::drawSpecial(SkSpecialImage* src, int x, int y, const SkPaint& origPaint) {
SkASSERT(!src->isTextureBacked());
SkASSERT(!origPaint.getMaskFilter());
@ -645,68 +620,10 @@ void SkBitmapDevice::drawSpecial(SkSpecialImage* src, int x, int y, const SkPain
y += offset.y();
}
if (!clipImage) {
SkBitmap resultBM;
if (src->getROPixels(&resultBM)) {
BDDraw(this).drawSprite(resultBM, x, y, *paint);
}
return;
SkBitmap resultBM;
if (src->getROPixels(&resultBM)) {
BDDraw(this).drawSprite(resultBM, x, y, *paint);
}
// Clip image case.
sk_sp<SkImage> srcImage(src->asImage());
if (!srcImage) {
return;
}
const SkMatrix totalMatrix = SkMatrix::Concat(this->localToDevice(), 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<SkImage> mask;
SkMatrix maskMatrix, shaderMatrix;
SkTLazy<SkAutoDeviceClipRestore> autoClipRestore;
SkMatrix totalInverse;
if (clipImage->isAlphaOnly() && totalMatrix.invert(&totalInverse)) {
// If the mask is already in A8 format, we can draw it directly
// (while compensating in the shader matrix).
mask = sk_ref_sp(clipImage);
maskMatrix = totalMatrix;
shaderMatrix = totalInverse * SkMatrix::Translate(x, y);
// If the mask is not fully contained within the src layer, we must clip.
if (!srcBounds.contains(clipBounds)) {
autoClipRestore.init(this, srcBounds);
}
maskBounds.offsetTo(0, 0);
} else {
// Otherwise, we convert the mask to A8 explicitly.
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);
mask = surf->makeImageSnapshot();
maskMatrix = SkMatrix::I();
shaderMatrix = SkMatrix::Translate(x - maskBounds.x(), y - maskBounds.y());
}
SkAutoDeviceTransformRestore adr(this, maskMatrix);
paint.writable()->setShader(srcImage->makeShader(&shaderMatrix));
this->drawImageRect(mask.get(), nullptr,
SkRect::MakeXYWH(maskBounds.x(), maskBounds.y(),
mask->width(), mask->height()),
*paint, SkCanvas::kFast_SrcRectConstraint);
}
sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {

View File

@ -101,8 +101,7 @@ protected:
///////////////////////////////////////////////////////////////////////////
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
SkImage*, const SkMatrix&) override;
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
sk_sp<SkSpecialImage> snapSpecial(const SkIRect&, bool = false) override;

View File

@ -191,17 +191,12 @@ 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,
const SkImage* clipImage, const SkMatrix* clipMatrix)
DeviceCM(sk_sp<SkBaseDevice> device, const SkPaint* paint, const SkMatrix& stashed)
: fNext(nullptr)
, fDevice(std::move(device))
, fPaint(paint ? std::make_unique<SkPaint>(*paint) : nullptr)
, fStashedMatrix(stashed)
, fClipImage(sk_ref_sp(const_cast<SkImage*>(clipImage)))
, fClipMatrix(clipMatrix ? *clipMatrix : SkMatrix::I())
{}
void reset(const SkIRect& bounds) {
@ -506,7 +501,7 @@ void SkCanvas::init(sk_sp<SkBaseDevice> device) {
SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
new (fDeviceCMStorage) DeviceCM(device, nullptr, fMCRec->fMatrix.asM33(), nullptr, nullptr);
new (fDeviceCMStorage) DeviceCM(device, nullptr, fMCRec->fMatrix.asM33());
fMCRec->fTopLayer = fMCRec->fLayer;
@ -918,7 +913,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
if (special) {
// The image is drawn at 1-1 scale with integer translation, so no filtering is needed.
SkPaint p;
dst->drawSpecial(special.get(), 0, 0, p, nullptr, SkMatrix::I());
dst->drawSpecial(special.get(), 0, 0, p);
}
return;
}
@ -1177,13 +1172,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
}
newDevice->setMarkerStack(fMarkerStack.get());
}
DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix,
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
rec.fClipMask, rec.fClipMatrix
#else
nullptr, nullptr
#endif
);
DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix);
// only have a "next" if this new layer doesn't affect the clip (rare)
layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
@ -1287,8 +1276,7 @@ void SkCanvas::internalRestore() {
paint.setBlendMode(SkBlendMode::kDstOver);
const int x = backImage->fLoc.x();
const int y = backImage->fLoc.y();
this->getTopDevice()->drawSpecial(backImage->fImage.get(), x, y, paint,
nullptr, SkMatrix::I());
this->getTopDevice()->drawSpecial(backImage->fImage.get(), x, y, paint);
}
/* Time to draw the layer's offscreen. We can't call the public drawSprite,
@ -1300,8 +1288,7 @@ void SkCanvas::internalRestore() {
layer->fDevice->setImmutable();
// At this point, 'layer' has been removed from the device stack, so the devices that
// internalDrawDevice sees are the destinations that 'layer' is drawn into.
this->internalDrawDevice(layer->fDevice.get(), layer->fPaint.get(),
layer->fClipImage.get(), layer->fClipMatrix);
this->internalDrawDevice(layer->fDevice.get(), layer->fPaint.get());
// restore what we smashed in internalSaveLayer
this->internalSetMatrix(layer->fStashedMatrix);
delete layer;
@ -1411,8 +1398,7 @@ static void check_drawdevice_colorspaces(SkColorSpace* src, SkColorSpace* dst) {
SkASSERT(src == dst);
}
void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, const SkPaint* paint,
SkImage* clipImage, const SkMatrix& clipMatrix) {
void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, const SkPaint* paint) {
SkPaint tmp;
if (nullptr == paint) {
paint = &tmp;
@ -1430,13 +1416,12 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, const SkPaint* paint,
// so it should always be possible to use the relative origin. Once drawDevice() and
// drawSpecial() take an SkMatrix, this can switch to getRelativeTransform() instead.
SkIPoint pos = srcDev->getOrigin() - dstDev->getOrigin();
if (filter || clipImage) {
if (filter) {
sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
if (specialImage) {
check_drawdevice_colorspaces(dstDev->imageInfo().colorSpace(),
specialImage->getColorSpace());
dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint,
clipImage, clipMatrix);
dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint);
}
} else {
dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
@ -2516,8 +2501,7 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
iter.fDevice->localToDevice().mapXY(x, y, &pt);
iter.fDevice->drawSpecial(special.get(),
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt,
nullptr, SkMatrix::I());
SkScalarRoundToInt(pt.fY), pnt);
} else {
iter.fDevice->drawImageRect(
image, nullptr, SkRect::MakeXYWH(x, y, image->width(), image->height()), pnt,

View File

@ -315,8 +315,7 @@ void SkBaseDevice::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix, Sk
///////////////////////////////////////////////////////////////////////////////////////////////////
void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
SkImage*, const SkMatrix&) {}
void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) {}
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkBitmap&) { return nullptr; }
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkImage*) { return nullptr; }
sk_sp<SkSpecialImage> SkBaseDevice::snapSpecial(const SkIRect&, bool) { return nullptr; }

View File

@ -295,8 +295,7 @@ protected:
virtual void drawDrawable(SkDrawable*, const SkMatrix*, SkCanvas*);
virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
SkImage* clipImage, const SkMatrix& clipMatrix);
virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&);
virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
// Get a view of the entire device's current contents as an image.

View File

@ -132,8 +132,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,
SAVELAYERREC_HAS_CLIPMASK_OBSOLETE = 1 << 4, // 6/13/2020
SAVELAYERREC_HAS_CLIPMATRIX_OBSOLETE = 1 << 5, // 6/13/2020
};
enum SaveBehindFlatFlags {

View File

@ -602,7 +602,6 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
} break;
case SAVE_LAYER_SAVELAYERREC: {
SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0);
SkMatrix clipMatrix;
const uint32_t flatFlags = reader->readInt();
SkRect bounds;
if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
@ -620,17 +619,12 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
rec.fSaveLayerFlags = reader->readInt();
}
if (flatFlags & SAVELAYERREC_HAS_CLIPMASK) {
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
rec.fClipMask =
#endif
fPictureData->getImage(reader);
if (flatFlags & SAVELAYERREC_HAS_CLIPMASK_OBSOLETE) {
(void)fPictureData->getImage(reader);
}
if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX) {
reader->readMatrix(&clipMatrix);
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
rec.fClipMatrix = &clipMatrix;
#endif
if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX_OBSOLETE) {
SkMatrix clipMatrix_ignored;
reader->readMatrix(&clipMatrix_ignored);
}
BREAK_ON_READ_ERROR(reader);

View File

@ -129,16 +129,6 @@ void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) {
flatFlags |= SAVELAYERREC_HAS_FLAGS;
size += sizeof(uint32_t);
}
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
if (rec.fClipMask) {
flatFlags |= SAVELAYERREC_HAS_CLIPMASK;
size += sizeof(uint32_t); // clip image index
}
if (rec.fClipMatrix) {
flatFlags |= SAVELAYERREC_HAS_CLIPMATRIX;
size += SkMatrixPriv::WriteToMemory(*rec.fClipMatrix, nullptr);
}
#endif
const size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERREC, &size);
this->addInt(flatFlags);
@ -157,14 +147,6 @@ void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) {
if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
this->addInt(rec.fSaveLayerFlags);
}
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
if (flatFlags & SAVELAYERREC_HAS_CLIPMASK) {
this->addImage(rec.fClipMask);
}
if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX) {
this->addMatrix(*rec.fClipMatrix);
}
#endif
this->validate(initialOffset, size);
}

View File

@ -78,19 +78,10 @@ template <> void Draw::draw(const NoOp&) {}
DRAW(Flush, flush());
DRAW(Restore, restore());
DRAW(Save, save());
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds,
r.paint,
r.backdrop.get(),
r.clipMask.get(),
r.clipMatrix,
r.saveLayerFlags)));
#else
DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds,
r.paint,
r.backdrop.get(),
r.saveLayerFlags)));
#endif
template <> void Draw::draw(const SaveBehind& r) {
SkCanvasPriv::SaveBehind(fCanvas, r.subset);

View File

@ -185,8 +185,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 || match->first<SaveLayer>()->clipMask) {
// can't throw away the layer if we have a backdrop or clip mask
if (match->first<SaveLayer>()->backdrop) {
// can't throw away the layer if we have a backdrop
return false;
}

View File

@ -316,12 +316,6 @@ SkCanvas::SaveLayerStrategy SkRecorder::getSaveLayerStrategy(const SaveLayerRec&
this->append<SkRecords::SaveLayer>(this->copy(rec.fBounds)
, this->copy(rec.fPaint)
, sk_ref_sp(rec.fBackdrop)
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
, sk_ref_sp(rec.fClipMask)
, this->copy(rec.fClipMatrix)
#else
, nullptr, nullptr
#endif
, rec.fSaveLayerFlags);
return SkCanvas::kNoLayer_SaveLayerStrategy;
}

View File

@ -166,8 +166,6 @@ RECORD(SaveLayer, kHasPaint_Tag,
Optional<SkRect> bounds;
Optional<SkPaint> paint;
sk_sp<const SkImageFilter> backdrop;
sk_sp<const SkImage> clipMask;
Optional<SkMatrix> clipMatrix;
SkCanvas::SaveLayerFlags saveLayerFlags);
RECORD(SaveBehind, 0,

View File

@ -628,8 +628,7 @@ void SkGpuDevice::drawPath(const SkPath& origSrcPath, const SkPaint& paint, bool
paint, this->asMatrixProvider(), shape);
}
void SkGpuDevice::drawSpecial(SkSpecialImage* special, int left, int top, const SkPaint& paint,
SkImage* clipImage, const SkMatrix& clipMatrix) {
void SkGpuDevice::drawSpecial(SkSpecialImage* special, int left, int top, const SkPaint& paint) {
SkASSERT(!paint.getMaskFilter());
ASSERT_SINGLE_OWNER
@ -685,59 +684,7 @@ void SkGpuDevice::drawSpecial(SkSpecialImage* special, int left, int top, const
const SkIRect& subset = result->subset();
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(left, top, subset.width(), subset.height()));
SkRect srcRect = SkRect::Make(subset);
if (clipImage) {
// Add the image as a simple texture effect applied to coverage. Accessing content outside
// of the clip image should behave as if it were a decal (i.e. zero coverage). However, to
// limit pixels touched and hardware checks, we draw the clip image geometry to get the
// decal effect.
auto filter = paint.getFilterQuality() > kNone_SkFilterQuality
? GrSamplerState::Filter::kBilerp
: GrSamplerState::Filter::kNearest;
GrSurfaceProxyView clipView = as_IB(clipImage)->refView(this->context(), GrMipMapped::kNo);
// Fold clip matrix into ctm
ctm.preConcat(clipMatrix);
SkMatrix inverseClipMatrix;
std::unique_ptr<GrFragmentProcessor> cfp;
if (clipView && ctm.invert(&inverseClipMatrix)) {
GrColorType srcColorType = SkColorTypeToGrColorType(clipImage->colorType());
cfp = GrTextureEffect::Make(std::move(clipView), clipImage->alphaType(),
inverseClipMatrix, filter);
if (srcColorType != GrColorType::kAlpha_8) {
cfp = GrFragmentProcessor::SwizzleOutput(std::move(cfp), GrSwizzle::AAAA());
}
}
if (cfp) {
// If the grPaint already has coverage, this adds an additional stage that multiples
// the image's alpha channel with the prior coverage.
grPaint.addCoverageFragmentProcessor(std::move(cfp));
// Undo the offset that was needed for shader coord transforms to get the transform for
// the actual drawn geometry.
ctm.postTranslate(SkIntToScalar(left), SkIntToScalar(top));
inverseClipMatrix.preTranslate(-SkIntToScalar(left), -SkIntToScalar(top));
SkRect clipGeometry = SkRect::MakeWH(clipImage->width(), clipImage->height());
if (!clipGeometry.contains(inverseClipMatrix.mapRect(dstRect))) {
// Draw the clip geometry since it is smaller, using dstRect as an extra scissor
SkClipStack dstRectClip(this->cs());
dstRectClip.clipDevRect(
SkIRect::MakeXYWH(left, top, subset.width(), subset.height()),
SkClipOp::kIntersect);
GrClipStackClip clip(fRenderTargetContext->dimensions(), &dstRectClip,
&this->asMatrixProvider());
SkMatrix local = SkMatrix::Concat(SkMatrix::MakeRectToRect(
dstRect, srcRect, SkMatrix::kFill_ScaleToFit), ctm);
fRenderTargetContext->fillRectWithLocalMatrix(&clip, std::move(grPaint),
GrAA(paint.isAntiAlias()), ctm,
clipGeometry, local);
return;
}
// Else fall through and draw the subset since that is contained in the clip geometry
}
// Else some issue configuring the coverage FP, so just draw without the clip mask image
}
// Draw directly in screen space, possibly with an extra coverage processor
fRenderTargetContext->fillRectToRect(this->clip(), std::move(grPaint),
GrAA(paint.isAntiAlias()), SkMatrix::I(), dstRect, srcRect);
@ -846,7 +793,7 @@ void SkGpuDevice::drawDevice(SkBaseDevice* device,
return;
}
this->drawSpecial(srcImg.get(), left, top, paint, nullptr, SkMatrix::I());
this->drawSpecial(srcImg.get(), left, top, paint);
}
void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,

View File

@ -101,8 +101,7 @@ public:
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
void drawSpecial(SkSpecialImage*, int left, int top, const SkPaint& paint,
SkImage*, const SkMatrix&) override;
void drawSpecial(SkSpecialImage*, int left, int top, const SkPaint&) override;
void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags,
const SkColor4f& color, SkBlendMode mode) override;

View File

@ -1722,8 +1722,7 @@ void SkPDFDevice::internalDrawImageRect(SkKeyedImage imageSubset,
#include "include/core/SkImageFilter.h"
#include "src/core/SkSpecialImage.h"
void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y, const SkPaint& paint,
SkImage* clipImage, const SkMatrix& clipMatrix) {
void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y, const SkPaint& paint) {
if (this->hasEmptyClip()) {
return;
}

View File

@ -111,8 +111,7 @@ protected:
void drawAnnotation(const SkRect&, const char key[], SkData* value) override;
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
SkImage*, const SkMatrix&) override;
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
SkImageFilterCache* getImageFilterCache() override;

View File

@ -193,18 +193,6 @@ DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
recorder.drawRect(draw, opaqueDrawPaint);
recorder.restore();
assert_savelayer_draw_restore(r, &record, 18, false);
// saveLayer w/ clip mask should also NOT go away
#ifdef SK_SUPPORT_LEGACY_LAYERCLIPMASK
{
sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(10, 10));
recorder.saveLayer({ nullptr, nullptr, nullptr, surface->makeImageSnapshot().get(),
nullptr, 0});
recorder.drawRect(draw, opaqueDrawPaint);
recorder.restore();
assert_savelayer_draw_restore(r, &record, 21, false);
}
#endif
}
#endif