aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-04-25 13:04:05 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-25 17:34:27 +0000
commit910ca0fd014ad9263e54e0cfa4199768b6c7fade (patch)
tree4e8556bb2e6f27868dbc32e173c682ce8dc91e42
parentf0db23633f754cc3888494ea8d37e5dd8d495bfd (diff)
Experiment to track coverage in a layer
Bug: skia: Change-Id: I5ed334f63e64991944394dc8103092a2c6280546 Reviewed-on: https://skia-review.googlesource.com/122000 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
-rw-r--r--docs/SkCanvas_Reference.bmh5
-rw-r--r--gm/savelayer.cpp39
-rw-r--r--include/core/SkCanvas.h2
-rw-r--r--src/core/SkAutoBlitterChoose.h29
-rw-r--r--src/core/SkBitmapDevice.cpp44
-rw-r--r--src/core/SkBitmapDevice.h14
-rw-r--r--src/core/SkBlitter.h29
-rw-r--r--src/core/SkCanvas.cpp6
-rw-r--r--src/core/SkDevice.h3
-rw-r--r--src/core/SkDraw.cpp27
-rw-r--r--src/core/SkDraw.h3
-rw-r--r--src/core/SkDraw_vertices.cpp2
-rw-r--r--tests/LayerDrawLooperTest.cpp3
13 files changed, 171 insertions, 35 deletions
diff --git a/docs/SkCanvas_Reference.bmh b/docs/SkCanvas_Reference.bmh
index de33770122..0bce15e947 100644
--- a/docs/SkCanvas_Reference.bmh
+++ b/docs/SkCanvas_Reference.bmh
@@ -1684,6 +1684,7 @@ documentation purposes, this enum is named rather than anonymous
enum {
kPreserveLCDText_SaveLayerFlag = 1 << 1,
kInitWithPrevious_SaveLayerFlag = 1 << 2,
+ kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
};
##
@@ -1700,6 +1701,10 @@ defining how Layer allocated by saveLayer operates.
Initializes Layer with the contents of the previous Layer.
##
+#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
+ Experimental -- don't use
+##
+
#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
#Deprecated soon
##
diff --git a/gm/savelayer.cpp b/gm/savelayer.cpp
index 32f95bfc7d..77218206c7 100644
--- a/gm/savelayer.cpp
+++ b/gm/savelayer.cpp
@@ -238,3 +238,42 @@ DEF_SIMPLE_GM(savelayer_clipmask, canvas, 1200, 1200) {
}
}
}
+
+DEF_SIMPLE_GM(savelayer_coverage, canvas, 500, 500) {
+ canvas->saveLayer(nullptr, nullptr);
+
+ SkRect r = { 0, 0, 200, 200 };
+ SkPaint layerPaint;
+ layerPaint.setBlendMode(SkBlendMode::kModulate);
+
+ auto image = GetResourceAsImage("images/mandrill_128.png");
+
+ auto proc = [layerPaint](SkCanvas* canvas, SkCanvas::SaveLayerRec& rec) {
+ SkPaint paint;
+ paint.setColor(SK_ColorRED);
+
+ canvas->saveLayer(rec);
+ canvas->drawCircle(100, 100, 50, paint);
+ paint.setColor(0x8800FF00);
+ canvas->drawRect({10, 90, 190, 110}, paint);
+ canvas->restore();
+ };
+
+ const int yflags[] = { 0, SkCanvas::kInitWithPrevious_SaveLayerFlag };
+ for (int y = 0; y <= 1; ++y) {
+ const int xflags[] = { 0, SkCanvas::kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag };
+ for (int x = 0; x <= 1; ++x) {
+ canvas->save();
+ canvas->translate(x * 200.f, y * 200.f);
+
+ SkCanvas::SaveLayerRec rec(&r, &layerPaint, yflags[y] | xflags[x]);
+ canvas->drawImageRect(image, r, nullptr);
+ proc(canvas, rec);
+
+ canvas->restore();
+ }
+ }
+
+ canvas->restore();
+}
+
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index a819cda06a..73f7a3e8d9 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -609,6 +609,8 @@ public:
/** Initializes layer with the contents of the previous layer. */
kInitWithPrevious_SaveLayerFlag = 1 << 2,
+ kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
+
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
/** To be deprecated soon. */
kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
diff --git a/src/core/SkAutoBlitterChoose.h b/src/core/SkAutoBlitterChoose.h
index 3c2e8afdb8..b6c0433fbf 100644
--- a/src/core/SkAutoBlitterChoose.h
+++ b/src/core/SkAutoBlitterChoose.h
@@ -10,6 +10,7 @@
#include "SkArenaAlloc.h"
#include "SkBlitter.h"
+#include "SkDraw.h"
class SkMatrix;
class SkPaint;
@@ -17,27 +18,35 @@ class SkPixmap;
class SkAutoBlitterChoose : SkNoncopyable {
public:
- SkAutoBlitterChoose() {
- fBlitter = nullptr;
- }
- SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix,
- const SkPaint& paint, bool drawCoverage = false) {
- fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAlloc, drawCoverage);
+ SkAutoBlitterChoose() {}
+ SkAutoBlitterChoose(const SkDraw& draw, const SkMatrix* matrix, const SkPaint& paint,
+ bool drawCoverage = false) {
+ this->choose(draw, matrix, paint, drawCoverage);
}
SkBlitter* operator->() { return fBlitter; }
SkBlitter* get() const { return fBlitter; }
- SkBlitter* choose(const SkPixmap& dst, const SkMatrix& matrix,
- const SkPaint& paint, bool drawCoverage = false) {
+ SkBlitter* choose(const SkDraw& draw, const SkMatrix* matrix, const SkPaint& paint,
+ bool drawCoverage = false) {
SkASSERT(!fBlitter);
- fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAlloc, drawCoverage);
+ if (!matrix) {
+ matrix = draw.fMatrix;
+ }
+ fBlitter = SkBlitter::Choose(draw.fDst, *matrix, paint, &fAlloc, drawCoverage);
+
+ if (draw.fCoverage) {
+ // hmm, why can't choose ignore the paint if drawCoverage is true?
+ SkBlitter* coverageBlitter = SkBlitter::Choose(*draw.fCoverage, *matrix, SkPaint(),
+ &fAlloc, true);
+ fBlitter = fAlloc.make<SkPairBlitter>(fBlitter, coverageBlitter);
+ }
return fBlitter;
}
private:
// Owned by fAlloc, which will handle the delete.
- SkBlitter* fBlitter;
+ SkBlitter* fBlitter = nullptr;
SkSTArenaAlloc<kSkBlitterContextSize> fAlloc;
};
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 507dd352e4..b49818c2a1 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -10,6 +10,7 @@
#include "SkImageFilter.h"
#include "SkImageFilterCache.h"
#include "SkMallocPixelRef.h"
+#include "SkMakeUnique.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkPath.h"
@@ -104,6 +105,8 @@ public:
fDraw.fMatrix = &dev->ctm();
fDraw.fRC = &dev->fRCStack.rc();
fOrigin.set(0, 0);
+
+ fDraw.fCoverage = dev->accessCoverage();
}
}
@@ -180,6 +183,7 @@ public:
}
fMatrix = &dev->ctm();
fRC = &dev->fRCStack.rc();
+ fCoverage = dev->accessCoverage();
}
};
@@ -238,17 +242,24 @@ SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) {
}
SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps,
- SkRasterHandleAllocator::Handle hndl)
+ SkRasterHandleAllocator::Handle hndl, const SkBitmap* coverage)
: INHERITED(bitmap.info(), surfaceProps)
, fBitmap(bitmap)
, fRasterHandle(hndl)
, fRCStack(bitmap.width(), bitmap.height())
{
SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
+
+ if (coverage) {
+ SkASSERT(coverage->width() == bitmap.width());
+ SkASSERT(coverage->height() == bitmap.height());
+ fCoverage = skstd::make_unique<SkBitmap>(*coverage);
+ }
}
SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
const SkSurfaceProps& surfaceProps,
+ bool trackCoverage,
SkRasterHandleAllocator* allocator) {
SkAlphaType newAT = origInfo.alphaType();
if (!valid_for_bitmap_device(origInfo, &newAT)) {
@@ -282,7 +293,16 @@ SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
}
}
- return new SkBitmapDevice(bitmap, surfaceProps, hndl);
+ SkBitmap coverage;
+ if (trackCoverage) {
+ SkImageInfo ci = SkImageInfo::Make(info.width(), info.height(), kAlpha_8_SkColorType,
+ kPremul_SkAlphaType);
+ if (!coverage.tryAllocPixelsFlags(ci, SkBitmap::kZeroPixels_AllocFlag)) {
+ return nullptr;
+ }
+ }
+
+ return new SkBitmapDevice(bitmap, surfaceProps, hndl, trackCoverage ? &coverage : nullptr);
}
void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
@@ -294,7 +314,8 @@ void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
SkBaseDevice* SkBitmapDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
- return SkBitmapDevice::Create(cinfo.fInfo, surfaceProps, cinfo.fAllocator);
+ return SkBitmapDevice::Create(cinfo.fInfo, surfaceProps, cinfo.fTrackCoverage,
+ cinfo.fAllocator);
}
bool SkBitmapDevice::onAccessPixels(SkPixmap* pmap) {
@@ -593,7 +614,22 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPain
if (paint->getMaskFilter()) {
paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithMatrix(this->ctm()));
}
- this->drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, *paint);
+
+ // hack to test coverage
+ SkBitmapDevice* src = static_cast<SkBitmapDevice*>(device);
+ if (src->fCoverage) {
+ SkDraw draw;
+ draw.fDst = fBitmap.pixmap();
+ draw.fMatrix = &SkMatrix::I();
+ draw.fRC = &fRCStack.rc();
+ SkPaint paint(origPaint);
+ paint.setShader(SkShader::MakeBitmapShader(src->fBitmap, SkShader::kClamp_TileMode,
+ SkShader::kClamp_TileMode, nullptr));
+ draw.drawBitmap(*src->fCoverage.get(),
+ SkMatrix::MakeTrans(SkIntToScalar(x),SkIntToScalar(y)), nullptr, paint);
+ } else {
+ this->drawSprite(src->fBitmap, x, y, *paint);
+ }
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h
index e040b6b0c6..f80cba6ee4 100644
--- a/src/core/SkBitmapDevice.h
+++ b/src/core/SkBitmapDevice.h
@@ -55,10 +55,19 @@ public:
* any drawing to this device will have no effect.
*/
SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps,
- void* externalHandle = nullptr);
+ void* externalHandle, const SkBitmap* coverage);
static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&,
- SkRasterHandleAllocator* = nullptr);
+ bool trackCoverage,
+ SkRasterHandleAllocator*);
+
+ static SkBitmapDevice* Create(const SkImageInfo& info, const SkSurfaceProps& props) {
+ return Create(info, props, false, nullptr);
+ }
+
+ const SkPixmap* accessCoverage() const {
+ return fCoverage ? &fCoverage->pixmap() : nullptr;
+ }
protected:
void* getRasterHandle() const override { return fRasterHandle; }
@@ -165,6 +174,7 @@ private:
SkBitmap fBitmap;
void* fRasterHandle = nullptr;
SkRasterClipStack fRCStack;
+ std::unique_ptr<SkBitmap> fCoverage; // if non-null, will have the same dimensions as fBitmap
typedef SkBaseDevice INHERITED;
};
diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h
index c280ac37b7..cf3edd31eb 100644
--- a/src/core/SkBlitter.h
+++ b/src/core/SkBlitter.h
@@ -297,4 +297,33 @@ private:
SkRgnClipBlitter fRgnBlitter;
};
+#define SHARD(code) fA->code; fB->code;
+
+class SkPairBlitter : public SkBlitter {
+ SkBlitter* fA = nullptr;
+ SkBlitter* fB = nullptr;
+public:
+ SkPairBlitter(SkBlitter* a, SkBlitter* b) : fA(a), fB(b) {}
+
+ void blitH(int x, int y, int width) override { SHARD(blitH(x, y, width)) }
+ void blitAntiH(int x, int y, const SkAlpha alphas[], const int16_t runs[]) override {
+ SHARD(blitAntiH(x, y, alphas, runs))
+ }
+ void blitV(int x, int y, int height, SkAlpha alpha) override {
+ SHARD(blitV(x, y, height, alpha))
+ }
+ void blitRect(int x, int y, int width, int height) override {
+ SHARD(blitRect(x, y, width, height))
+ }
+ void blitAntiRect(int x, int y, int width, int height,
+ SkAlpha leftAlpha, SkAlpha rightAlpha) override {
+ SHARD(blitAntiRect(x, y, width, height, leftAlpha, rightAlpha))
+ }
+ void blitMask(const SkMask& mask, const SkIRect& clip) override { SHARD(blitMask(mask, clip)) }
+ const SkPixmap* justAnOpaqueColor(uint32_t* value) override { return nullptr; }
+ void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override { SHARD(blitAntiH2(x, y, a0, a1)) }
+ void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override { SHARD(blitAntiV2(x, y, a0, a1)) }
+};
+#undef SHARD
+
#endif
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 3f2439d538..52644727a6 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -644,7 +644,7 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
{
inc_canvas();
- sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps));
+ sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, nullptr, nullptr));
this->init(device.get(), kDefault_InitFlags);
}
@@ -656,7 +656,7 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocat
{
inc_canvas();
- sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl));
+ sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl, nullptr));
this->init(device.get(), kDefault_InitFlags);
}
@@ -1058,8 +1058,10 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() ||
(saveLayerFlags & kPreserveLCDText_SaveLayerFlag);
const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
+ const bool trackCoverage = SkToBool(saveLayerFlags & kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag);
const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo,
preserveLCDText,
+ trackCoverage,
fAllocator.get());
newDevice.reset(priorDevice->onCreateDevice(createInfo, paint));
if (!newDevice) {
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index fb91c8a444..40b9589ce5 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -305,16 +305,19 @@ protected:
TileUsage tileUsage,
SkPixelGeometry geo,
bool preserveLCDText,
+ bool trackCoverage,
SkRasterHandleAllocator* allocator)
: fInfo(info)
, fTileUsage(tileUsage)
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText))
+ , fTrackCoverage(trackCoverage)
, fAllocator(allocator)
{}
const SkImageInfo fInfo;
const TileUsage fTileUsage;
const SkPixelGeometry fPixelGeometry;
+ const bool fTrackCoverage = false;
SkRasterHandleAllocator* fAllocator = nullptr;
};
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 71d0d13463..362c8b50fd 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -220,7 +220,7 @@ void SkDraw::drawPaint(const SkPaint& paint) const {
}
// normal case: use a blitter
- SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
+ SkAutoBlitterChoose blitter(*this, nullptr, paint);
SkScan::FillIRect(devRect, *fRC, blitter.get());
}
@@ -497,7 +497,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
PtProcRec rec;
if (!device && rec.init(mode, paint, fMatrix, fRC)) {
- SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
+ SkAutoBlitterChoose blitter(*this, nullptr, paint);
SkPoint devPts[MAX_DEV_PTS];
const SkMatrix* matrix = fMatrix;
@@ -798,7 +798,7 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
return;
}
- SkAutoBlitterChoose blitterStorage(fDst, *matrix, paint);
+ SkAutoBlitterChoose blitterStorage(*this, matrix, paint);
const SkRasterClip& clip = *fRC;
SkBlitter* blitter = blitterStorage.get();
@@ -846,7 +846,7 @@ void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
}
SkAutoMaskFreeImage ami(dstM.fImage);
- SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
+ SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
SkBlitter* blitter = blitterChooser.get();
SkAAClipBlitterWrapper wrapper;
@@ -920,7 +920,7 @@ void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
// Transform the rrect into device space.
SkRRect devRRect;
if (rrect.transform(*fMatrix, &devRRect)) {
- SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
+ SkAutoBlitterChoose blitter(*this, nullptr, paint);
if (as_MFB(paint.getMaskFilter())->filterRRect(devRRect, *fMatrix,
*fRC, blitter.get())) {
return; // filterRRect() called the blitter, so we're done
@@ -954,7 +954,7 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
SkBlitter* blitter = nullptr;
SkAutoBlitterChoose blitterStorage;
if (nullptr == customBlitter) {
- blitter = blitterStorage.choose(fDst, *fMatrix, paint, drawCoverage);
+ blitter = blitterStorage.choose(*this, nullptr, paint, drawCoverage);
} else {
blitter = customBlitter;
}
@@ -1022,9 +1022,8 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
iData->fElement->setDrawFn([proc, devPath, paint, drawCoverage](SkArenaAlloc* alloc,
const SkThreadedBMPDevice::DrawState& ds, const SkIRect& tileBounds) {
SkThreadedBMPDevice::TileDraw tileDraw(ds, tileBounds);
- SkAutoBlitterChoose blitterStorage;
- proc(devPath, *tileDraw.fRC, blitterStorage.choose(tileDraw.fDst, *tileDraw.fMatrix,
- paint, drawCoverage));
+ SkAutoBlitterChoose blitterStorage(tileDraw, nullptr, paint, drawCoverage);
+ proc(devPath, *tileDraw.fRC, blitterStorage.get());
});
} else {
// We can use DAA to do scan conversion in the init-once phase.
@@ -1036,10 +1035,8 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
const SkThreadedBMPDevice::DrawState& ds, const SkIRect& tileBounds) {
SkASSERT(record->fType != SkDAARecord::Type::kToBeComputed);
SkThreadedBMPDevice::TileDraw tileDraw(ds, tileBounds);
- SkAutoBlitterChoose blitterStorage;
- SkBlitter* blitter = blitterStorage.choose(tileDraw.fDst, *tileDraw.fMatrix,
- paint, drawCoverage);
- SkScan::AntiFillPath(devPath, *tileDraw.fRC, blitter, record);
+ SkAutoBlitterChoose blitterStorage(tileDraw, nullptr, paint, drawCoverage);
+ SkScan::AntiFillPath(devPath, *tileDraw.fRC, blitterStorage.get(), record);
});
}
}
@@ -1547,7 +1544,7 @@ void SkDraw::drawText(const char text[], size_t byteLength, SkScalar x, SkScalar
paint, props, this->scalerContextFlags(), fMatrix);
// The Blitter Choose needs to be live while using the blitter below.
- SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
+ SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
DrawOneGlyph drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
@@ -1627,7 +1624,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, const SkScalar po
paint, props, this->scalerContextFlags(), fMatrix);
// The Blitter Choose needs to be live while using the blitter below.
- SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
+ SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
DrawOneGlyph drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
SkPaint::Align textAlignment = paint.getTextAlign();
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index 8598475e2c..eabccf0d8d 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -152,6 +152,9 @@ public:
const SkMatrix* fMatrix; // required
const SkRasterClip* fRC; // required
+ // optional, will be same dimensions as fDst if present
+ const SkPixmap* fCoverage = nullptr;
+
#ifdef SK_DEBUG
void validate() const;
#else
diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp
index 810ded1307..8c1ad1f007 100644
--- a/src/core/SkDraw_vertices.cpp
+++ b/src/core/SkDraw_vertices.cpp
@@ -294,7 +294,7 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int count,
// no colors[] and no texture, stroke hairlines with paint's color.
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
- SkAutoBlitterChoose blitter(fDst, *fMatrix, p);
+ SkAutoBlitterChoose blitter(*this, nullptr, p);
// Abort early if we failed to create a shader context.
if (blitter->isNullBlitter()) {
return;
diff --git a/tests/LayerDrawLooperTest.cpp b/tests/LayerDrawLooperTest.cpp
index f3705b77be..1a1e68b0c8 100644
--- a/tests/LayerDrawLooperTest.cpp
+++ b/tests/LayerDrawLooperTest.cpp
@@ -27,7 +27,8 @@ static SkBitmap make_bm(int w, int h) {
// TODO: can this be derived from SkBaseDevice?
class FakeDevice : public SkBitmapDevice {
public:
- FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry)) {
+ FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry),
+ nullptr, nullptr) {
}
void drawRect(const SkRect& r, const SkPaint& paint) override {