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:
parent
08ac84a66a
commit
82d619699d
@ -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"
|
||||
|
||||
|
173
gm/savelayer.cpp
173
gm/savelayer.cpp
@ -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);
|
||||
|
@ -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&);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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; }
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user