Plumbing SkMatrixProvider into the raster backend

Change-Id: Ic5786b995fdb439871f2e3ab94cd07a945de19af
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/288776
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2020-05-08 14:54:37 -04:00 committed by Skia Commit-Bot
parent b8d7e00098
commit 9aaec36e45
29 changed files with 218 additions and 149 deletions

View File

@ -21,11 +21,12 @@ class DrawPathBench : public Benchmark {
SkPath fPath;
SkRasterClip fRC;
SkAutoPixmapStorage fPixmap;
SkMatrix fIdentity;
SkSimpleMatrixProvider fIdentityMatrixProvider;
SkDraw fDraw;
bool fDrawCoverage;
public:
DrawPathBench(bool drawCoverage) : fDrawCoverage(drawCoverage) {
DrawPathBench(bool drawCoverage)
: fIdentityMatrixProvider(SkMatrix::I()), fDrawCoverage(drawCoverage) {
fPaint.setAntiAlias(true);
fName.printf("draw_coverage_%s", drawCoverage ? "true" : "false");
@ -40,12 +41,11 @@ public:
fPixmap.erase(0);
}
fIdentity.setIdentity();
fRC.setRect(fPath.getBounds().round());
fDraw.fDst = fPixmap;
fDraw.fMatrix = &fIdentity;
fDraw.fRC = &fRC;
fDraw.fDst = fPixmap;
fDraw.fMatrixProvider = &fIdentityMatrixProvider;
fDraw.fRC = &fRC;
}
protected:

View File

@ -15,6 +15,7 @@
#include "src/codec/SkSampler.h"
#include "src/codec/SkScalingCodec.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkUtils.h"
@ -749,7 +750,8 @@ SkCodec::Result SkWuffsCodec::onIncrementalDecodeTwoPass() {
SkMatrix matrix = SkMatrix::MakeRectToRect(SkRect::Make(this->dimensions()),
SkRect::Make(this->dstInfo().dimensions()),
SkMatrix::kFill_ScaleToFit);
draw.fMatrix = &matrix;
SkSimpleMatrixProvider matrixProvider(matrix);
draw.fMatrixProvider = &matrixProvider;
SkRasterClip rc(SkIRect::MakeSize(this->dstInfo().dimensions()));
draw.fRC = &rc;

View File

@ -21,27 +21,28 @@ class SkPixmap;
class SkAutoBlitterChoose : SkNoncopyable {
public:
SkAutoBlitterChoose() {}
SkAutoBlitterChoose(const SkDraw& draw, const SkMatrix* matrix, const SkPaint& paint,
bool drawCoverage = false) {
this->choose(draw, matrix, paint, drawCoverage);
SkAutoBlitterChoose(const SkDraw& draw, const SkMatrixProvider* matrixProvider,
const SkPaint& paint, bool drawCoverage = false) {
this->choose(draw, matrixProvider, paint, drawCoverage);
}
SkBlitter* operator->() { return fBlitter; }
SkBlitter* get() const { return fBlitter; }
SkBlitter* choose(const SkDraw& draw, const SkMatrix* matrix, const SkPaint& paint,
bool drawCoverage = false) {
SkBlitter* choose(const SkDraw& draw, const SkMatrixProvider* matrixProvider,
const SkPaint& paint, bool drawCoverage = false) {
SkASSERT(!fBlitter);
if (!matrix) {
matrix = draw.fMatrix;
if (!matrixProvider) {
matrixProvider = draw.fMatrixProvider;
}
fBlitter = SkBlitter::Choose(draw.fDst, *matrix, paint, &fAlloc, drawCoverage,
fBlitter = SkBlitter::Choose(draw.fDst, *matrixProvider, paint, &fAlloc, drawCoverage,
draw.fRC->clipShader());
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, draw.fRC->clipShader());
SkBlitter* coverageBlitter =
SkBlitter::Choose(*draw.fCoverage, *matrixProvider, SkPaint(), &fAlloc, true,
draw.fRC->clipShader());
fBlitter = fAlloc.make<SkPairBlitter>(fBlitter, coverageBlitter);
}
return fBlitter;

View File

@ -54,9 +54,9 @@ class SkDrawTiler {
SkDraw fDraw;
// fCurr... are only used if fNeedTiling
SkMatrix fTileMatrix;
SkRasterClip fTileRC;
SkIPoint fOrigin;
SkTLazy<SkPostConcatMatrixProvider> fTileMatrixProvider;
SkRasterClip fTileRC;
SkIPoint fOrigin;
bool fDone, fNeedsTiling;
@ -105,15 +105,14 @@ public:
}
if (fNeedsTiling) {
// fDraw.fDst is reset each time in setupTileDraw()
fDraw.fMatrix = &fTileMatrix;
// fDraw.fDst and fMatrixProvider are reset each time in setupTileDraw()
fDraw.fRC = &fTileRC;
// we'll step/increase it before using it
fOrigin.set(fSrcBounds.fLeft - kMaxDim, fSrcBounds.fTop);
} else {
// don't reference fSrcBounds, as it may not have been set
fDraw.fDst = fRootPixmap;
fDraw.fMatrix = &dev->localToDevice();
fDraw.fMatrixProvider = dev;
fDraw.fRC = &dev->fRCStack.rc();
fOrigin.set(0, 0);
@ -165,8 +164,9 @@ private:
SkASSERT_RELEASE(success);
// now don't use bounds, since fDst has the clipped dimensions.
fTileMatrix = fDevice->localToDevice();
fTileMatrix.postTranslate(SkIntToScalar(-fOrigin.x()), SkIntToScalar(-fOrigin.y()));
fDraw.fMatrixProvider = fTileMatrixProvider.init(
fDevice->asMatrixProvider(),
SkMatrix::MakeTrans(SkIntToScalar(-fOrigin.x()), SkIntToScalar(-fOrigin.y())));
fDevice->fRCStack.rc().translate(-fOrigin.x(), -fOrigin.y(), &fTileRC);
fTileRC.op(SkIRect::MakeWH(fDraw.fDst.width(), fDraw.fDst.height()),
SkRegion::kIntersect_Op);
@ -192,7 +192,7 @@ public:
// NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
fDst.reset(dev->imageInfo(), nullptr, 0);
}
fMatrix = &dev->localToDevice();
fMatrixProvider = dev;
fRC = &dev->fRCStack.rc();
fCoverage = dev->accessCoverage();
}
@ -568,8 +568,9 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPain
SkBitmapDevice* src = static_cast<SkBitmapDevice*>(device);
if (src->fCoverage) {
SkDraw draw;
SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
draw.fDst = fBitmap.pixmap();
draw.fMatrix = &SkMatrix::I();
draw.fMatrixProvider = &matrixProvider;
draw.fRC = &fRCStack.rc();
paint.writable()->setShader(src->fBitmap.makeShader());
draw.drawBitmap(*src->fCoverage.get(),

View File

@ -16,6 +16,7 @@
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkMask.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkRegionPriv.h"
@ -684,7 +685,7 @@ bool SkBlitter::UseRasterPipelineBlitter(const SkPixmap& device, const SkPaint&
}
SkBlitter* SkBlitter::Choose(const SkPixmap& device,
const SkMatrix& matrix,
const SkMatrixProvider& matrixProvider,
const SkPaint& origPaint,
SkArenaAlloc* alloc,
bool drawCoverage,
@ -738,15 +739,17 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
paint.writable()->setDither(false);
}
SkMatrix ctm = matrixProvider.localToDevice();
if (gUseSkVMBlitter) {
if (auto blitter = SkCreateSkVMBlitter(device, *paint, matrix, alloc, clipShader)) {
if (auto blitter = SkCreateSkVMBlitter(device, *paint, ctm, alloc, clipShader)) {
return blitter;
}
}
// We'll end here for many interesting cases: color spaces, color filters, most color types.
if (UseRasterPipelineBlitter(device, *paint, matrix) || clipShader) {
auto blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc, clipShader);
if (UseRasterPipelineBlitter(device, *paint, ctm) || clipShader) {
auto blitter =
SkCreateRasterPipelineBlitter(device, *paint, matrixProvider, alloc, clipShader);
SkASSERT(blitter);
return blitter;
}
@ -762,12 +765,13 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
SkShaderBase::Context* shaderContext = nullptr;
if (paint->getShader()) {
shaderContext = as_SB(paint->getShader())->makeContext(
{*paint, matrix, nullptr, device.colorType(), device.colorSpace()},
{*paint, ctm, nullptr, device.colorType(), device.colorSpace()},
alloc);
// Creating the context isn't always possible... we'll just fall back to raster pipeline.
if (!shaderContext) {
auto blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc, clipShader);
auto blitter = SkCreateRasterPipelineBlitter(device, *paint, matrixProvider, alloc,
clipShader);
SkASSERT(blitter);
return blitter;
}
@ -789,7 +793,8 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
if (shaderContext && SkRGB565_Shader_Blitter::Supports(device, *paint)) {
return alloc->make<SkRGB565_Shader_Blitter>(device, *paint, shaderContext);
} else {
return SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc, clipShader);
return SkCreateRasterPipelineBlitter(device, *paint, matrixProvider, alloc,
clipShader);
}
default:

View File

@ -18,6 +18,7 @@
class SkArenaAlloc;
class SkMatrix;
class SkMatrixProvider;
class SkPaint;
class SkPixmap;
struct SkMask;
@ -140,7 +141,7 @@ public:
Return the correct blitter to use given the specified context.
*/
static SkBlitter* Choose(const SkPixmap& dst,
const SkMatrix& matrix,
const SkMatrixProvider& matrixProvider,
const SkPaint& paint,
SkArenaAlloc*,
bool drawCoverage,

View File

@ -14,6 +14,7 @@
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkVM.h"
@ -75,8 +76,9 @@ SkColor4f SkColorFilter::filterColor4f(const SkColor4f& origSrcColor, SkColorSpa
SkRasterPipeline pipeline(&alloc);
pipeline.append_constant_color(&alloc, color.vec());
SkPaint dummyPaint;
SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
SkStageRec rec = {
&pipeline, &alloc, kRGBA_F32_SkColorType, dstCS, dummyPaint, nullptr, SkMatrix::I()
&pipeline, &alloc, kRGBA_F32_SkColorType, dstCS, dummyPaint, nullptr, matrixProvider
};
this->onAppendStages(rec, color.fA == 1);

View File

@ -165,8 +165,9 @@ private:
///////////////////////////////////////////////////////////////////////////////
// Neither of these ever returns nullptr, but this first factory may return a SkNullBlitter.
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
SkArenaAlloc*, sk_sp<SkShader> clipShader);
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&,
const SkMatrixProvider& matrixProvider, SkArenaAlloc*,
sk_sp<SkShader> clipShader);
// Use this if you've pre-baked a shader pipeline, including modulating with paint alpha.
// This factory never returns an SkNullBlitter.
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&,

View File

@ -56,7 +56,7 @@ bool SkDraw::computeConservativeLocalClipBounds(SkRect* localBounds) const {
}
SkMatrix inverse;
if (!fMatrix->invert(&inverse)) {
if (!fMatrixProvider->localToDevice().invert(&inverse)) {
return false;
}
@ -354,12 +354,12 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
return;
}
SkMatrix ctm = fMatrixProvider->localToDevice();
PtProcRec rec;
if (!device && rec.init(mode, paint, fMatrix, fRC)) {
if (!device && rec.init(mode, paint, &ctm, fRC)) {
SkAutoBlitterChoose blitter(*this, nullptr, paint);
SkPoint devPts[MAX_DEV_PTS];
const SkMatrix* matrix = fMatrix;
SkBlitter* bltr = blitter.get();
PtProcRec::Proc proc = rec.chooseProc(&bltr);
// we have to back up subsequent passes if we're in polygon mode
@ -370,7 +370,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
if (n > MAX_DEV_PTS) {
n = MAX_DEV_PTS;
}
matrix->mapPoints(devPts, pts, n);
ctm.mapPoints(devPts, pts, n);
if (!SkScalarsAreFinite(&devPts[0].fX, n * 2)) {
return;
}
@ -442,8 +442,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
SkRect cullRect = SkRect::Make(fRC->getBounds());
if (paint.getPathEffect()->asPoints(&pointData, path, rec,
*fMatrix, &cullRect)) {
if (paint.getPathEffect()->asPoints(&pointData, path, rec, ctm, &cullRect)) {
// 'asPoints' managed to find some fast path
SkPaint newP(paint);
@ -593,9 +592,9 @@ static SkPoint* rect_points(SkRect& r) {
}
static void draw_rect_as_path(const SkDraw& orig, const SkRect& prePaintRect,
const SkPaint& paint, const SkMatrix* matrix) {
const SkPaint& paint, const SkMatrixProvider* matrixProvider) {
SkDraw draw(orig);
draw.fMatrix = matrix;
draw.fMatrixProvider = matrixProvider;
SkPath tmp;
tmp.addRect(prePaintRect);
tmp.setFillType(SkPathFillType::kWinding);
@ -611,29 +610,28 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
return;
}
const SkMatrix* matrix;
SkMatrix combinedMatrixStorage;
const SkMatrixProvider* matrixProvider = fMatrixProvider;
SkTLazy<SkPreConcatMatrixProvider> preConcatMatrixProvider;
if (paintMatrix) {
SkASSERT(postPaintRect);
combinedMatrixStorage.setConcat(*fMatrix, *paintMatrix);
matrix = &combinedMatrixStorage;
matrixProvider = preConcatMatrixProvider.init(*matrixProvider, *paintMatrix);
} else {
SkASSERT(!postPaintRect);
matrix = fMatrix;
}
SkMatrix ctm = fMatrixProvider->localToDevice();
SkPoint strokeSize;
RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
RectType rtype = ComputeRectType(paint, ctm, &strokeSize);
if (kPath_RectType == rtype) {
draw_rect_as_path(*this, prePaintRect, paint, matrix);
draw_rect_as_path(*this, prePaintRect, paint, matrixProvider);
return;
}
SkRect devRect;
const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
// skip the paintMatrix when transforming the rect by the CTM
fMatrix->mapPoints(rect_points(devRect), rect_points(paintRect), 2);
ctm.mapPoints(rect_points(devRect), rect_points(paintRect), 2);
devRect.sort();
// look for the quick exit, before we build a blitter
@ -646,7 +644,7 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
// For kStroke_RectType, strokeSize is already computed.
const SkPoint& ssize = (kStroke_RectType == rtype)
? strokeSize
: compute_stroke_size(paint, *fMatrix);
: compute_stroke_size(paint, ctm);
bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y()));
}
}
@ -655,7 +653,7 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
}
if (!SkRectPriv::FitsInFixed(bbox) && rtype != kHair_RectType) {
draw_rect_as_path(*this, prePaintRect, paint, matrix);
draw_rect_as_path(*this, prePaintRect, paint, matrixProvider);
return;
}
@ -664,7 +662,7 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
return;
}
SkAutoBlitterChoose blitterStorage(*this, matrix, paint);
SkAutoBlitterChoose blitterStorage(*this, matrixProvider, paint);
const SkRasterClip& clip = *fRC;
SkBlitter* blitter = blitterStorage.get();
@ -707,7 +705,8 @@ void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
SkMask dstM;
if (paint.getMaskFilter() &&
as_MFB(paint.getMaskFilter())->filterMask(&dstM, srcM, *fMatrix, nullptr)) {
as_MFB(paint.getMaskFilter())
->filterMask(&dstM, srcM, fMatrixProvider->localToDevice(), nullptr)) {
mask = &dstM;
}
SkAutoMaskFreeImage ami(dstM.fImage);
@ -769,12 +768,13 @@ void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
return;
}
SkMatrix ctm = fMatrixProvider->localToDevice();
{
// TODO: Investigate optimizing these options. They are in the same
// order as SkDraw::drawPath, which handles each case. It may be
// that there is no way to optimize for these using the SkRRect path.
SkScalar coverage;
if (SkDrawTreatAsHairline(paint, *fMatrix, &coverage)) {
if (SkDrawTreatAsHairline(paint, ctm, &coverage)) {
goto DRAW_PATH;
}
@ -786,11 +786,10 @@ void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
if (paint.getMaskFilter()) {
// Transform the rrect into device space.
SkRRect devRRect;
if (rrect.transform(*fMatrix, &devRRect)) {
if (rrect.transform(ctm, &devRRect)) {
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
if (as_MFB(paint.getMaskFilter())->filterRRect(devRRect, ctm, *fRC, blitter.get())) {
return; // filterRRect() called the blitter, so we're done
}
}
}
@ -831,8 +830,9 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
if (paint.getMaskFilter()) {
SkStrokeRec::InitStyle style = doFill ? SkStrokeRec::kFill_InitStyle
: SkStrokeRec::kHairline_InitStyle;
if (as_MFB(paint.getMaskFilter())->filterPath(devPath, *fMatrix, *fRC, blitter, style)) {
return; // filterPath() called the blitter, so we're done
if (as_MFB(paint.getMaskFilter())
->filterPath(devPath, fMatrixProvider->localToDevice(), *fRC, blitter, style)) {
return; // filterPath() called the blitter, so we're done
}
}
@ -894,8 +894,8 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
bool doFill = true;
SkPath tmpPathStorage;
SkPath* tmpPath = &tmpPathStorage;
SkMatrix tmpMatrix;
const SkMatrix* matrix = fMatrix;
const SkMatrixProvider* matrixProvider = fMatrixProvider;
SkTLazy<SkPreConcatMatrixProvider> preConcatMatrixProvider;
tmpPath->setIsVolatile(true);
if (prePathMatrix) {
@ -909,8 +909,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
pathPtr->transform(*prePathMatrix, result);
pathPtr = result;
} else {
tmpMatrix.setConcat(*matrix, *prePathMatrix);
matrix = &tmpMatrix;
matrixProvider = preConcatMatrixProvider.init(*matrixProvider, *prePathMatrix);
}
}
// at this point we're done with prePathMatrix
@ -920,7 +919,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
{
SkScalar coverage;
if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
if (SkDrawTreatAsHairline(origPaint, matrixProvider->localToDevice(), &coverage)) {
if (SK_Scalar1 == coverage) {
paint.writable()->setStrokeWidth(0);
} else if (SkBlendMode_SupportsCoverageAsAlpha(origPaint.getBlendMode())) {
@ -949,7 +948,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
cullRectPtr = &cullRect;
}
doFill = paint->getFillPath(*pathPtr, tmpPath, cullRectPtr,
ComputeResScaleForStroking(*fMatrix));
ComputeResScaleForStroking(fMatrixProvider->localToDevice()));
pathPtr = tmpPath;
}
@ -957,7 +956,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath;
// transform the path into device space
pathPtr->transform(*matrix, devPathPtr);
pathPtr->transform(matrixProvider->localToDevice(), devPathPtr);
this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill);
}
@ -970,9 +969,10 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons
return;
}
if (SkTreatAsSprite(*fMatrix, bitmap.dimensions(), paint)) {
int ix = SkScalarRoundToInt(fMatrix->getTranslateX());
int iy = SkScalarRoundToInt(fMatrix->getTranslateY());
SkMatrix ctm = fMatrixProvider->localToDevice();
if (SkTreatAsSprite(ctm, bitmap.dimensions(), paint)) {
int ix = SkScalarRoundToInt(ctm.getTranslateX());
int iy = SkScalarRoundToInt(ctm.getTranslateY());
SkPixmap pmap;
if (!bitmap.peekPixels(&pmap)) {
@ -991,7 +991,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons
SkMask mask;
r.setIWH(bitmap.width(), bitmap.height());
fMatrix->mapRect(&r);
ctm.mapRect(&r);
r.round(&mask.fBounds);
// set the mask's bounds to the transformed bitmap-bounds,
@ -1029,7 +1029,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons
// need the unclipped top/left for the translate
c.translate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
c.concat(*fMatrix);
c.concat(ctm);
// We can't call drawBitmap, or we'll infinitely recurse. Instead
// we manually build a shader and draw that into our new mask
@ -1080,8 +1080,8 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
paint.writable()->setStyle(SkPaint::kFill_Style);
}
SkMatrix matrix;
matrix.setConcat(*fMatrix, prematrix);
SkPreConcatMatrixProvider matrixProvider(*fMatrixProvider, prematrix);
SkMatrix matrix = matrixProvider.localToDevice();
if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) {
return;
@ -1116,7 +1116,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
// now make a temp draw on the stack, and use it
//
SkDraw draw(*this);
draw.fMatrix = &matrix;
draw.fMatrixProvider = &matrixProvider;
if (bitmap.colorType() == kAlpha_8_SkColorType && !paint->getColorFilter()) {
draw.drawBitmapAsMask(bitmap, *paint);
@ -1176,8 +1176,8 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& ori
matrix.setTranslate(r.fLeft, r.fTop);
SkPaint paintWithShader = make_paint_with_image(paint, bitmap, &matrix);
SkDraw draw(*this);
matrix.reset();
draw.fMatrix = &matrix;
SkOverrideDeviceMatrixProvider matrixProvider(*fMatrixProvider, SkMatrix::I());
draw.fMatrixProvider = &matrixProvider;
// call ourself with a rect
draw.drawRect(r, paintWithShader);
}
@ -1187,7 +1187,7 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& ori
#ifdef SK_DEBUG
void SkDraw::validate() const {
SkASSERT(fMatrix != nullptr);
SkASSERT(fMatrixProvider != nullptr);
SkASSERT(fRC != nullptr);
const SkIRect& cr = fRC->getBounds();
@ -1259,8 +1259,9 @@ static void draw_into_mask(const SkMask& mask, const SkPath& devPath,
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
draw.fRC = &clip;
draw.fMatrix = &matrix;
SkSimpleMatrixProvider matrixProvider(matrix);
draw.fRC = &clip;
draw.fMatrixProvider = &matrixProvider;
paint.setAntiAlias(true);
switch (style) {
case SkStrokeRec::kHairline_InitStyle:

View File

@ -22,6 +22,7 @@ class SkClipStack;
class SkBaseDevice;
class SkBlitter;
class SkMatrix;
class SkMatrixProvider;
class SkPath;
class SkRegion;
class SkRasterClip;
@ -153,9 +154,9 @@ private:
bool SK_WARN_UNUSED_RESULT computeConservativeLocalClipBounds(SkRect* bounds) const;
public:
SkPixmap fDst;
const SkMatrix* fMatrix{nullptr}; // required
const SkRasterClip* fRC{nullptr}; // required
SkPixmap fDst;
const SkMatrixProvider* fMatrixProvider{nullptr}; // required
const SkRasterClip* fRC{nullptr}; // required
// optional, will be same dimensions as fDst if present
const SkPixmap* fCoverage{nullptr};

View File

@ -12,6 +12,7 @@
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkCoreBlitters.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkScan.h"
@ -61,7 +62,7 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
SkSTArenaAlloc<256> alloc;
SkRasterPipeline pipeline(&alloc);
SkStageRec rec = {
&pipeline, &alloc, fDst.colorType(), fDst.colorSpace(), p, nullptr, *fMatrix
&pipeline, &alloc, fDst.colorType(), fDst.colorSpace(), p, nullptr, *fMatrixProvider
};
SkStageUpdater* updator = as_SB(atlasShader.get())->appendUpdatableStages(rec);
@ -76,8 +77,8 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
SkMatrix mx;
mx.setRSXform(xform[i]);
mx.preTranslate(-textures[i].fLeft, -textures[i].fTop);
mx.postConcat(*fMatrix);
draw.fMatrix = &mx;
SkPreConcatMatrixProvider matrixProvider(*fMatrixProvider, mx);
draw.fMatrixProvider = &matrixProvider;
draw.drawRect(textures[i], p);
}
return;
@ -114,7 +115,7 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
SkMatrix mx;
mx.setRSXform(xform[i]);
mx.preTranslate(-textures[i].fLeft, -textures[i].fTop);
mx.postConcat(*fMatrix);
mx.postConcat(fMatrixProvider->localToDevice());
if (updator->update(mx, nullptr)) {
fill_rect(mx, *fRC, textures[i], blitter, &scratchPath);

View File

@ -7,6 +7,7 @@
#include "src/core/SkDraw.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkScalerCache.h"
@ -37,11 +38,13 @@ void SkDraw::paintMasks(SkDrawableGlyphBuffer* drawables, const SkPaint& paint)
// The size used for a typical blitter.
SkSTArenaAlloc<3308> alloc;
SkBlitter* blitter = SkBlitter::Choose(fDst, *fMatrix, paint, &alloc, false, fRC->clipShader());
SkBlitter* blitter =
SkBlitter::Choose(fDst, *fMatrixProvider, paint, &alloc, false, fRC->clipShader());
if (fCoverage) {
blitter = alloc.make<SkPairBlitter>(
blitter,
SkBlitter::Choose(*fCoverage, *fMatrix, SkPaint(), &alloc, true, fRC->clipShader()));
blitter,
SkBlitter::Choose(
*fCoverage, *fMatrixProvider, SkPaint(), &alloc, true, fRC->clipShader()));
}
SkAAClipBlitterWrapper wrapper{*fRC, blitter};
@ -127,7 +130,7 @@ void SkDraw::drawGlyphRunList(const SkGlyphRunList& glyphRunList,
return;
}
glyphPainter->drawForBitmapDevice(glyphRunList, *fMatrix, this);
glyphPainter->drawForBitmapDevice(glyphRunList, fMatrixProvider->localToDevice(), this);
}
#if defined _WIN32

View File

@ -12,6 +12,7 @@
#include "src/core/SkConvertPixels.h"
#include "src/core/SkCoreBlitters.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkScan.h"
@ -302,7 +303,8 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
To be safe, we just make that determination here, and pass it into the tricolorshader.
*/
const bool usePerspective = fMatrix->hasPerspective();
SkMatrix ctm = fMatrixProvider->localToDevice();
const bool usePerspective = ctm.hasPerspective();
VertState state(vertexCount, indices, indexCount);
VertState::Proc vertProc = state.chooseProc(info.mode());
@ -326,7 +328,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
p.setShader(sk_ref_sp(shader));
if (!textures) { // only tricolor shader
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *fMatrix, outerAlloc,
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *fMatrixProvider, outerAlloc,
this->fRC->clipShader());
while (vertProc(&state)) {
if (triShader &&
@ -340,7 +342,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
SkRasterPipeline pipeline(outerAlloc);
SkStageRec rec = {
&pipeline, outerAlloc, fDst.colorType(), fDst.colorSpace(), p, nullptr, *fMatrix
&pipeline, outerAlloc, fDst.colorType(), fDst.colorSpace(), p, nullptr, *fMatrixProvider
};
if (auto updater = as_SB(shader)->appendUpdatableStages(rec)) {
bool isOpaque = shader->isOpaque();
@ -359,7 +361,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
SkMatrix localM;
if (texture_to_matrix(state, positions, textures, &localM) &&
updater->update(*fMatrix, &localM))
updater->update(ctm, &localM))
{
fill_triangle(state, blitter, *fRC, dev2, dev3);
}
@ -374,18 +376,17 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
SkSTArenaAlloc<2048> innerAlloc;
const SkMatrix* ctm = fMatrix;
SkMatrix tmpCtm;
const SkMatrixProvider* matrixProvider = fMatrixProvider;
SkTLazy<SkPreConcatMatrixProvider> preConcatMatrixProvider;
if (textures) {
SkMatrix localM;
if (!texture_to_matrix(state, positions, textures, &localM)) {
continue;
}
tmpCtm = SkMatrix::Concat(*fMatrix, localM);
ctm = &tmpCtm;
matrixProvider = preConcatMatrixProvider.init(*matrixProvider, localM);
}
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *ctm, &innerAlloc,
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *matrixProvider, &innerAlloc,
this->fRC->clipShader());
fill_triangle(state, blitter, *fRC, dev2, dev3);
}
@ -409,8 +410,9 @@ void SkDraw::drawVertices(const SkVertices* vertices, SkBlendMode bmode,
if (vertexCount < 3 || (indexCount > 0 && indexCount < 3) || fRC->isEmpty()) {
return;
}
SkMatrix ctm = fMatrixProvider->localToDevice();
SkMatrix ctmInv;
if (!fMatrix->invert(&ctmInv)) {
if (!ctm.invert(&ctmInv)) {
return;
}
@ -423,16 +425,16 @@ void SkDraw::drawVertices(const SkVertices* vertices, SkBlendMode bmode,
SkPoint* dev2 = nullptr;
SkPoint3* dev3 = nullptr;
if (fMatrix->hasPerspective()) {
if (ctm.hasPerspective()) {
dev3 = outerAlloc.makeArray<SkPoint3>(vertexCount);
fMatrix->mapHomogeneousPoints(dev3, info.positions(), vertexCount);
ctm.mapHomogeneousPoints(dev3, info.positions(), vertexCount);
// similar to the bounds check for 2d points (below)
if (!SkScalarsAreFinite((const SkScalar*)dev3, vertexCount * 3)) {
return;
}
} else {
dev2 = outerAlloc.makeArray<SkPoint>(vertexCount);
fMatrix->mapPoints(dev2, info.positions(), vertexCount);
ctm.mapPoints(dev2, info.positions(), vertexCount);
SkRect bounds;
// this also sets bounds to empty if we see a non-finite value

View File

@ -13,18 +13,19 @@
class SkArenaAlloc;
class SkColorSpace;
class SkMatrixProvider;
class SkPaint;
class SkRasterPipeline;
// Passed to effects that will add stages to rasterpipeline
struct SkStageRec {
SkRasterPipeline* fPipeline;
SkArenaAlloc* fAlloc;
SkColorType fDstColorType;
SkColorSpace* fDstCS; // may be nullptr
const SkPaint& fPaint;
const SkMatrix* fLocalM; // may be nullptr
const SkMatrix fCTM;
SkRasterPipeline* fPipeline;
SkArenaAlloc* fAlloc;
SkColorType fDstColorType;
SkColorSpace* fDstCS; // may be nullptr
const SkPaint& fPaint;
const SkMatrix* fLocalM; // may be nullptr
const SkMatrixProvider& fMatrixProvider;
};
#endif // SkEffectPriv_DEFINED

View File

@ -30,15 +30,35 @@ public:
virtual bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const = 0;
protected:
private:
friend class SkBaseDevice;
SkM44 fLocalToDevice;
SkMatrix fLocalToDevice33; // Cached SkMatrix version of above, for legacy usage
};
class SkOverrideDeviceMatrixProvider : public SkMatrixProvider {
public:
SkOverrideDeviceMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& localToDevice)
: SkMatrixProvider(localToDevice)
, fParent(parent) {}
bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override {
return fParent.getLocalToMarker(id, localToMarker);
}
private:
const SkMatrixProvider& fParent;
};
class SkPostConcatMatrixProvider : public SkMatrixProvider {
public:
SkPostConcatMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& postMatrix)
#if defined(SK_SUPPORT_LEGACY_MATRIX44)
: SkMatrixProvider(SkMatrix::Concat(postMatrix, parent.localToDevice()))
#else
: SkMatrixProvider(SkM44(postMatrix) * parent.localToDevice44())
#endif
, fParent(parent)
, fPostMatrix(postMatrix) {}
@ -49,13 +69,17 @@ public:
private:
const SkMatrixProvider& fParent;
SkMatrix fPostMatrix;
const SkMatrix fPostMatrix;
};
class SkPreConcatMatrixProvider : public SkMatrixProvider {
public:
SkPreConcatMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& preMatrix)
#if defined(SK_SUPPORT_LEGACY_MATRIX44)
: SkMatrixProvider(SkMatrix::Concat(parent.localToDevice(), preMatrix))
#else
: SkMatrixProvider(parent.localToDevice44() * SkM44(preMatrix))
#endif
, fParent(parent)
, fPreMatrix(preMatrix) {}
@ -71,7 +95,7 @@ public:
private:
const SkMatrixProvider& fParent;
SkMatrix fPreMatrix;
const SkMatrix fPreMatrix;
};
class SkSimpleMatrixProvider : public SkMatrixProvider {

View File

@ -20,6 +20,7 @@
#include "src/core/SkConvertPixels.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMask.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPixmapPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkUtils.h"
@ -186,9 +187,10 @@ bool SkPixmap::erase(const SkColor4f& color, SkColorSpace* cs, const SkIRect* su
SkRasterClip rc{clip};
SkDraw draw;
draw.fDst = *this;
draw.fMatrix = &SkMatrix::I();
draw.fRC = &rc;
SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
draw.fDst = *this;
draw.fMatrixProvider = &matrixProvider;
draw.fRC = &rc;
draw.drawPaint(paint);
return true;

View File

@ -15,6 +15,7 @@
#include "src/core/SkBlitter.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkOpts.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkUtils.h"
@ -86,7 +87,7 @@ private:
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
const SkPaint& paint,
const SkMatrix& ctm,
const SkMatrixProvider& matrixProvider,
SkArenaAlloc* alloc,
sk_sp<SkShader> clipShader) {
// For legacy to keep working, we need to sometimes still distinguish null dstCS from sRGB.
@ -117,7 +118,8 @@ SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
bool is_opaque = shader->isOpaque() && paintColor.fA == 1.0f;
bool is_constant = shader->isConstant();
if (shader->appendStages({&shaderPipeline, alloc, dstCT, dstCS, paint, nullptr, ctm})) {
if (shader->appendStages(
{&shaderPipeline, alloc, dstCT, dstCS, paint, nullptr, matrixProvider})) {
if (paintColor.fA != 1.0f) {
shaderPipeline.append(SkRasterPipeline::scale_1_float,
alloc->make<float>(paintColor.fA));
@ -165,8 +167,8 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
SkPaint clipPaint; // just need default values
SkColorType clipCT = kRGBA_8888_SkColorType;
SkColorSpace* clipCS = nullptr;
SkMatrix clipM = SkMatrix::I();
SkStageRec rec = {clipP, alloc, clipCT, clipCS, clipPaint, nullptr, clipM};
SkSimpleMatrixProvider clipMatrixProvider(SkMatrix::I());
SkStageRec rec = {clipP, alloc, clipCT, clipCS, clipPaint, nullptr, clipMatrixProvider};
if (as_SB(clipShader)->appendStages(rec)) {
struct Storage {
// large enough for highp (float) or lowp(U16)
@ -184,8 +186,9 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
// If there's a color filter it comes next.
if (auto colorFilter = paint.getColorFilter()) {
SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
SkStageRec rec = {
colorPipeline, alloc, dst.colorType(), dst.colorSpace(), paint, nullptr, SkMatrix::I()
colorPipeline, alloc, dst.colorType(), dst.colorSpace(), paint, nullptr, matrixProvider
};
colorFilter->appendStages(rec, is_opaque);
is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);

View File

@ -894,8 +894,10 @@ public:
}
bool onAppendStages(const SkStageRec& rec) const override {
// TODO: Populate dynamic uniforms!
SkMatrix inverse;
if (!this->computeTotalInverse(rec.fCTM, rec.fLocalM, &inverse)) {
if (!this->computeTotalInverse(rec.fMatrixProvider.localToDevice(), rec.fLocalM,
&inverse)) {
return false;
}

View File

@ -21,6 +21,7 @@
#include "src/core/SkFontPriv.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMaskGamma.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkPathPriv.h"
#include "src/core/SkRasterClip.h"
@ -509,9 +510,10 @@ static void generateMask(const SkMask& mask, const SkPath& path,
sk_bzero(dst.writable_addr(), dst.computeByteSize());
SkDraw draw;
draw.fDst = dst;
draw.fRC = &clip;
draw.fMatrix = &matrix;
SkSimpleMatrixProvider matrixProvider(matrix);
draw.fDst = dst;
draw.fRC = &clip;
draw.fMatrixProvider = &matrixProvider;
draw.drawPath(path, paint);
switch (mask.fFormat) {

View File

@ -8,6 +8,7 @@
#include "src/gpu/GrSWMaskHelper.h"
#include "include/private/GrRecordingContext.h"
#include "src/core/SkMatrixProvider.h"
#include "src/gpu/GrBitmapTextureMaker.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrProxyProvider.h"
@ -49,7 +50,8 @@ void GrSWMaskHelper::drawRect(const SkRect& rect, const SkMatrix& matrix, SkRegi
uint8_t alpha) {
SkMatrix translatedMatrix = matrix;
translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
fDraw.fMatrix = &translatedMatrix;
SkSimpleMatrixProvider matrixProvider(translatedMatrix);
fDraw.fMatrixProvider = &matrixProvider;
fDraw.drawRect(rect, get_paint(op, aa, alpha));
}
@ -58,7 +60,8 @@ void GrSWMaskHelper::drawRRect(const SkRRect& rrect, const SkMatrix& matrix, SkR
GrAA aa, uint8_t alpha) {
SkMatrix translatedMatrix = matrix;
translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
fDraw.fMatrix = &translatedMatrix;
SkSimpleMatrixProvider matrixProvider(translatedMatrix);
fDraw.fMatrixProvider = &matrixProvider;
fDraw.drawRRect(rrect, get_paint(op, aa, alpha));
}
@ -74,7 +77,8 @@ void GrSWMaskHelper::drawShape(const GrStyledShape& shape, const SkMatrix& matri
SkMatrix translatedMatrix = matrix;
translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
fDraw.fMatrix = &translatedMatrix;
SkSimpleMatrixProvider matrixProvider(translatedMatrix);
fDraw.fMatrixProvider = &matrixProvider;
SkPath path;
shape.asPath(&path);
@ -92,7 +96,8 @@ void GrSWMaskHelper::drawShape(const GrShape& shape, const SkMatrix& matrix, SkR
SkMatrix translatedMatrix = matrix;
translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
fDraw.fMatrix = &translatedMatrix;
SkSimpleMatrixProvider matrixProvider(translatedMatrix);
fDraw.fMatrixProvider = &matrixProvider;
if (shape.inverted()) {
if (shape.isEmpty() || shape.isLine() || shape.isPoint()) {

View File

@ -315,7 +315,7 @@ void SkGpuDevice::drawPoints(SkCanvas::PointMode mode,
SkRasterClip rc(this->devClipBounds());
SkDraw draw;
draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(this->width(), this->height()), nullptr, 0);
draw.fMatrix = &this->localToDevice();
draw.fMatrixProvider = this;
draw.fRC = &rc;
draw.drawPoints(mode, count, pts, paint, this);
return;

View File

@ -13,6 +13,7 @@
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkDistanceFieldGen.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkPointPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/gpu/GrAuditTrail.h"
@ -608,7 +609,8 @@ private:
SkRasterClip rasterClip;
rasterClip.setRect(devPathBounds);
draw.fRC = &rasterClip;
draw.fMatrix = &drawMatrix;
SkSimpleMatrixProvider matrixProvider(drawMatrix);
draw.fMatrixProvider = &matrixProvider;
draw.fDst = dst;
draw.drawPathCoverage(path, paint);
@ -698,7 +700,8 @@ private:
rasterClip.setRect(devPathBounds);
draw.fRC = &rasterClip;
drawMatrix.postTranslate(translateX, translateY);
draw.fMatrix = &drawMatrix;
SkSimpleMatrixProvider matrixProvider(drawMatrix);
draw.fMatrixProvider = &matrixProvider;
draw.fDst = dst;
draw.drawPathCoverage(path, paint);

View File

@ -154,12 +154,11 @@ static void draw_points(SkCanvas::PointMode mode,
const SkPoint* points,
const SkPaint& paint,
const SkIRect& bounds,
const SkMatrix& ctm,
SkBaseDevice* device) {
SkRasterClip rc(bounds);
SkDraw draw;
draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(bounds.right(), bounds.bottom()), nullptr, 0);
draw.fMatrix = &ctm;
draw.fMatrixProvider = device;
draw.fRC = &rc;
draw.drawPoints(mode, count, points, paint, device);
}
@ -420,8 +419,7 @@ void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
// We only use this when there's a path effect because of the overhead
// of multiple calls to setUpContentEntry it causes.
if (paint->getPathEffect()) {
draw_points(mode, count, points, *paint,
this->devClipBounds(), this->localToDevice(), this);
draw_points(mode, count, points, *paint, this->devClipBounds(), this);
return;
}

View File

@ -20,6 +20,7 @@
#include "src/core/SkEndian.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMaskGamma.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkSharedMutex.h"
@ -1008,7 +1009,8 @@ void SkScalerContext_DW::generateColorGlyphImage(const SkGlyph& glyph) {
draw.fDst = SkPixmap(SkImageInfo::MakeN32(glyph.width(), glyph.height(), kPremul_SkAlphaType),
glyph.fImage,
glyph.rowBytesUsingFormat(SkMask::Format::kARGB32_Format));
draw.fMatrix = &matrix;
SkSimpleMatrixProvider matrixProvider(matrix);
draw.fMatrixProvider = &matrixProvider;
draw.fRC = &rc;
SkPaint paint;

View File

@ -346,7 +346,7 @@ bool SkImageShader::doStages(const SkStageRec& rec, SkImageStageUpdater* updater
auto quality = rec.fPaint.getFilterQuality();
SkMatrix matrix;
if (!this->computeTotalInverse(rec.fCTM, rec.fLocalM, &matrix)) {
if (!this->computeTotalInverse(rec.fMatrixProvider.localToDevice(), rec.fLocalM, &matrix)) {
return false;
}
@ -619,7 +619,7 @@ bool SkImageShader::onAppendStages(const SkStageRec& rec) const {
}
SkStageUpdater* SkImageShader::onAppendUpdatableStages(const SkStageRec& rec) const {
bool usePersp = rec.fCTM.hasPerspective();
bool usePersp = rec.fMatrixProvider.localToDevice().hasPerspective();
auto updater = rec.fAlloc->make<SkImageStageUpdater>(this, usePersp);
return this->doStages(rec, updater) ? updater : nullptr;
}

View File

@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkTLazy.h"
#include "src/core/SkVM.h"
#include "src/shaders/SkLocalMatrixShader.h"
@ -138,6 +139,7 @@ protected:
#endif
bool onAppendStages(const SkStageRec& rec) const override {
SkOverrideDeviceMatrixProvider matrixProvider(rec.fMatrixProvider, fCTM);
SkStageRec newRec = {
rec.fPipeline,
rec.fAlloc,
@ -145,7 +147,7 @@ protected:
rec.fDstCS,
rec.fPaint,
rec.fLocalM,
fCTM,
matrixProvider,
};
return as_SB(fProxyShader)->appendStages(newRec);
}

View File

@ -261,7 +261,8 @@ bool SkPictureShader::onAppendStages(const SkStageRec& rec) const {
// Keep bitmapShader alive by using alloc instead of stack memory
auto& bitmapShader = *rec.fAlloc->make<sk_sp<SkShader>>();
bitmapShader = this->refBitmapShader(rec.fCTM, &lm, rec.fDstColorType, rec.fDstCS);
bitmapShader = this->refBitmapShader(rec.fMatrixProvider.localToDevice(), &lm,
rec.fDstColorType, rec.fDstCS);
if (!bitmapShader) {
return false;

View File

@ -12,6 +12,7 @@
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkTLazy.h"
@ -160,7 +161,8 @@ bool SkShaderBase::onAppendStages(const SkStageRec& rec) const {
opaquePaint.writable()->setAlpha(SK_AlphaOPAQUE);
}
ContextRec cr(*opaquePaint, rec.fCTM, rec.fLocalM, rec.fDstColorType, sk_srgb_singleton());
ContextRec cr(*opaquePaint, rec.fMatrixProvider.localToDevice(), rec.fLocalM, rec.fDstColorType,
sk_srgb_singleton());
struct CallbackCtx : SkRasterPipeline_CallbackCtx {
sk_sp<const SkShader> shader;

View File

@ -12,6 +12,7 @@
#include "include/private/SkVx.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkVM.h"
#include "src/core/SkWriteBuffer.h"
@ -279,7 +280,7 @@ bool SkGradientShaderBase::onAppendStages(const SkStageRec& rec) const {
SkRasterPipeline_DecalTileCtx* decal_ctx = nullptr;
SkMatrix matrix;
if (!this->computeTotalInverse(rec.fCTM, rec.fLocalM, &matrix)) {
if (!this->computeTotalInverse(rec.fMatrixProvider.localToDevice(), rec.fLocalM, &matrix)) {
return false;
}
matrix.postConcat(fPtsToUnit);