From 9aaec36e45f2a9a84f6a6da0b3d121393763801d Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Fri, 8 May 2020 14:54:37 -0400 Subject: [PATCH] Plumbing SkMatrixProvider into the raster backend Change-Id: Ic5786b995fdb439871f2e3ab94cd07a945de19af Reviewed-on: https://skia-review.googlesource.com/c/skia/+/288776 Reviewed-by: Mike Klein Commit-Queue: Brian Osman --- bench/CoverageBench.cpp | 12 +-- src/codec/SkWuffsCodec.cpp | 4 +- src/core/SkAutoBlitterChoose.h | 21 ++--- src/core/SkBitmapDevice.cpp | 21 ++--- src/core/SkBlitter.cpp | 19 +++-- src/core/SkBlitter.h | 3 +- src/core/SkColorFilter.cpp | 4 +- src/core/SkCoreBlitters.h | 5 +- src/core/SkDraw.cpp | 95 +++++++++++----------- src/core/SkDraw.h | 7 +- src/core/SkDraw_atlas.cpp | 9 +- src/core/SkDraw_text.cpp | 11 ++- src/core/SkDraw_vertices.cpp | 28 ++++--- src/core/SkEffectPriv.h | 15 ++-- src/core/SkMatrixProvider.h | 30 ++++++- src/core/SkPixmap.cpp | 8 +- src/core/SkRasterPipelineBlitter.cpp | 13 +-- src/core/SkRuntimeEffect.cpp | 4 +- src/core/SkScalerContext.cpp | 8 +- src/gpu/GrSWMaskHelper.cpp | 13 ++- src/gpu/SkGpuDevice.cpp | 2 +- src/gpu/ops/GrSmallPathRenderer.cpp | 7 +- src/pdf/SkPDFDevice.cpp | 6 +- src/ports/SkScalerContext_win_dw.cpp | 4 +- src/shaders/SkImageShader.cpp | 4 +- src/shaders/SkLocalMatrixShader.cpp | 4 +- src/shaders/SkPictureShader.cpp | 3 +- src/shaders/SkShader.cpp | 4 +- src/shaders/gradients/SkGradientShader.cpp | 3 +- 29 files changed, 218 insertions(+), 149 deletions(-) diff --git a/bench/CoverageBench.cpp b/bench/CoverageBench.cpp index 512e2eccb8..9d5411ed8e 100644 --- a/bench/CoverageBench.cpp +++ b/bench/CoverageBench.cpp @@ -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: diff --git a/src/codec/SkWuffsCodec.cpp b/src/codec/SkWuffsCodec.cpp index 823087ec5c..88394b3c80 100644 --- a/src/codec/SkWuffsCodec.cpp +++ b/src/codec/SkWuffsCodec.cpp @@ -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; diff --git a/src/core/SkAutoBlitterChoose.h b/src/core/SkAutoBlitterChoose.h index 0f1dc94793..98c76f3a1b 100644 --- a/src/core/SkAutoBlitterChoose.h +++ b/src/core/SkAutoBlitterChoose.h @@ -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(fBlitter, coverageBlitter); } return fBlitter; diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index a1ea742f65..190182f390 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -54,9 +54,9 @@ class SkDrawTiler { SkDraw fDraw; // fCurr... are only used if fNeedTiling - SkMatrix fTileMatrix; - SkRasterClip fTileRC; - SkIPoint fOrigin; + SkTLazy 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(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(), diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index f61bd18def..23373abe76 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -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(device, *paint, shaderContext); } else { - return SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc, clipShader); + return SkCreateRasterPipelineBlitter(device, *paint, matrixProvider, alloc, + clipShader); } default: diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h index 30cd3475a6..4f050a9a04 100644 --- a/src/core/SkBlitter.h +++ b/src/core/SkBlitter.h @@ -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, diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index e83140fa4e..e3af3f46fe 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -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); diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index f6d1c7a332..700ca64ab7 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -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 clipShader); +SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&, + const SkMatrixProvider& matrixProvider, SkArenaAlloc*, + sk_sp 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&, diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 915ea492ff..99c8bd8284 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -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 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 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: diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h index 9dbab98423..a9f778ad70 100644 --- a/src/core/SkDraw.h +++ b/src/core/SkDraw.h @@ -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}; diff --git a/src/core/SkDraw_atlas.cpp b/src/core/SkDraw_atlas.cpp index 2303adf404..fbc934690a 100644 --- a/src/core/SkDraw_atlas.cpp +++ b/src/core/SkDraw_atlas.cpp @@ -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); diff --git a/src/core/SkDraw_text.cpp b/src/core/SkDraw_text.cpp index ce9dee06e0..1d138c43be 100644 --- a/src/core/SkDraw_text.cpp +++ b/src/core/SkDraw_text.cpp @@ -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( - 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 diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp index dcf335ad6d..9f605db64a 100644 --- a/src/core/SkDraw_vertices.cpp +++ b/src/core/SkDraw_vertices.cpp @@ -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 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(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(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 diff --git a/src/core/SkEffectPriv.h b/src/core/SkEffectPriv.h index a56cd47760..edf66e24da 100644 --- a/src/core/SkEffectPriv.h +++ b/src/core/SkEffectPriv.h @@ -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 diff --git a/src/core/SkMatrixProvider.h b/src/core/SkMatrixProvider.h index e3d3f34f4c..e4e902b26c 100644 --- a/src/core/SkMatrixProvider.h +++ b/src/core/SkMatrixProvider.h @@ -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 { diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp index 8d64de9a1e..49ba422871 100644 --- a/src/core/SkPixmap.cpp +++ b/src/core/SkPixmap.cpp @@ -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; diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp index 81bff9c0df..6db71082b5 100644 --- a/src/core/SkRasterPipelineBlitter.cpp +++ b/src/core/SkRasterPipelineBlitter.cpp @@ -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 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(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); diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp index 9fab2fd759..a447405074 100644 --- a/src/core/SkRuntimeEffect.cpp +++ b/src/core/SkRuntimeEffect.cpp @@ -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; } diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index 987ebb5f3e..a2df87c3ef 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -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) { diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 0ccec74e7a..65e6d47529 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -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()) { diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 5a9248b091..fcd15fa7aa 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -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; diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index ab01e9908d..075376d7f1 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -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); diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index dc552383d5..c06bb27299 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -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; } diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp index 2200a74d65..b820890708 100644 --- a/src/ports/SkScalerContext_win_dw.cpp +++ b/src/ports/SkScalerContext_win_dw.cpp @@ -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; diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp index f9d6dab598..93bada2538 100755 --- a/src/shaders/SkImageShader.cpp +++ b/src/shaders/SkImageShader.cpp @@ -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(this, usePersp); return this->doStages(rec, updater) ? updater : nullptr; } diff --git a/src/shaders/SkLocalMatrixShader.cpp b/src/shaders/SkLocalMatrixShader.cpp index 59d98042d5..66ee52be69 100644 --- a/src/shaders/SkLocalMatrixShader.cpp +++ b/src/shaders/SkLocalMatrixShader.cpp @@ -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); } diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp index 1e9c2d5fbf..009ae54d36 100644 --- a/src/shaders/SkPictureShader.cpp +++ b/src/shaders/SkPictureShader.cpp @@ -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>(); - 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; diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp index d69dabd64d..c1c09e7d9a 100644 --- a/src/shaders/SkShader.cpp +++ b/src/shaders/SkShader.cpp @@ -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 shader; diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 87ab5c9686..205a18f05b 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -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);