diff options
Diffstat (limited to 'src/shaders')
-rw-r--r-- | src/shaders/SkImageShader.cpp | 14 | ||||
-rw-r--r-- | src/shaders/SkLocalMatrixShader.cpp | 7 | ||||
-rw-r--r-- | src/shaders/SkPerlinNoiseShader.cpp | 13 | ||||
-rw-r--r-- | src/shaders/SkPictureShader.cpp | 67 | ||||
-rw-r--r-- | src/shaders/SkPictureShader.h | 4 | ||||
-rw-r--r-- | src/shaders/SkShader.cpp | 23 | ||||
-rw-r--r-- | src/shaders/SkShaderBase.h | 14 | ||||
-rw-r--r-- | src/shaders/gradients/SkLinearGradient.cpp | 9 | ||||
-rw-r--r-- | src/shaders/gradients/SkRadialGradient.cpp | 11 | ||||
-rw-r--r-- | src/shaders/gradients/SkSweepGradient.cpp | 9 | ||||
-rw-r--r-- | src/shaders/gradients/SkTwoPointConicalGradient.cpp | 8 | ||||
-rw-r--r-- | src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp | 13 |
12 files changed, 88 insertions, 104 deletions
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp index 265f7e6013..1838e9e498 100644 --- a/src/shaders/SkImageShader.cpp +++ b/src/shaders/SkImageShader.cpp @@ -213,19 +213,11 @@ static GrSamplerState::WrapMode tile_mode_to_wrap_mode(const SkShader::TileMode std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor( const GrFPArgs& args) const { - SkMatrix lm = this->getLocalMatrix(); + const auto lm = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix); SkMatrix lmInverse; - if (!lm.invert(&lmInverse)) { + if (!lm->invert(&lmInverse)) { return nullptr; } - if (args.fLocalMatrix) { - SkMatrix inv; - if (!args.fLocalMatrix->invert(&inv)) { - return nullptr; - } - lmInverse.postConcat(inv); - lm.preConcat(*args.fLocalMatrix); - } GrSamplerState::WrapMode wrapModes[] = {tile_mode_to_wrap_mode(fTileModeX), tile_mode_to_wrap_mode(fTileModeY)}; @@ -236,7 +228,7 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor( // are provided by the caller. bool doBicubic; GrSamplerState::Filter textureFilterMode = GrSkFilterQualityToGrFilterMode( - args.fFilterQuality, *args.fViewMatrix, lm, + args.fFilterQuality, *args.fViewMatrix, *lm, args.fContext->contextPriv().sharpenMipmappedTextures(), &doBicubic); GrSamplerState samplerState(wrapModes, textureFilterMode); sk_sp<SkColorSpace> texColorSpace; diff --git a/src/shaders/SkLocalMatrixShader.cpp b/src/shaders/SkLocalMatrixShader.cpp index ca99af1bef..78110f5821 100644 --- a/src/shaders/SkLocalMatrixShader.cpp +++ b/src/shaders/SkLocalMatrixShader.cpp @@ -15,13 +15,8 @@ #if SK_SUPPORT_GPU std::unique_ptr<GrFragmentProcessor> SkLocalMatrixShader::asFragmentProcessor( const GrFPArgs& args) const { - SkMatrix tmp = this->getLocalMatrix(); - if (args.fLocalMatrix) { - tmp.preConcat(*args.fLocalMatrix); - } return as_SB(fProxyShader) - ->asFragmentProcessor(GrFPArgs(args.fContext, args.fViewMatrix, &tmp, - args.fFilterQuality, args.fDstColorSpaceInfo)); + ->asFragmentProcessor(args.makeWithPreLocalMatrix(this->getLocalMatrix())); } #endif diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp index 6179da3d32..8f6c85a494 100644 --- a/src/shaders/SkPerlinNoiseShader.cpp +++ b/src/shaders/SkPerlinNoiseShader.cpp @@ -1394,13 +1394,8 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso const GrFPArgs& args) const { SkASSERT(args.fContext); - SkMatrix localMatrix = this->getLocalMatrix(); - if (args.fLocalMatrix) { - localMatrix.preConcat(*args.fLocalMatrix); - } - - SkMatrix matrix = *args.fViewMatrix; - matrix.preConcat(localMatrix); + const auto localMatrix = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix); + const auto matrix = SkMatrix::Concat(*args.fViewMatrix, *localMatrix); // Either we don't stitch tiles, either we have a valid tile size SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); @@ -1413,8 +1408,8 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso matrix); SkMatrix m = *args.fViewMatrix; - m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); - m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); + m.setTranslateX(-localMatrix->getTranslateX() + SK_Scalar1); + m.setTranslateY(-localMatrix->getTranslateY() + SK_Scalar1); auto proxyProvider = args.fContext->contextPriv().proxyProvider(); if (fType == kImprovedNoise_Type) { diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp index 1d19b04721..de642a7dda 100644 --- a/src/shaders/SkPictureShader.cpp +++ b/src/shaders/SkPictureShader.cpp @@ -175,24 +175,20 @@ void SkPictureShader::flatten(SkWriteBuffer& buffer) const { // // 1) a cached image shader, which wraps a single picture tile at the given CTM/local matrix // -// 2) a "composite" local matrix, to be passed down when dispatching createContext(), +// 2) a tile scale adjustment, to be applied downstream when dispatching createContext(), // appendStages() and asFragmentProcessor() in callers // // The composite local matrix includes the actual local matrix, any inherited/outer local matrix // and a scale component (to mape the actual tile bitmap size -> fTile size). // sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, - const SkMatrix* outerLocalMatrix, + const SkMatrix& localMatrix, SkColorSpace* dstColorSpace, - SkMatrix* compositeLocalMatrix, + SkVector* scaleAdjust, const int maxTextureSize) const { SkASSERT(fPicture && !fPicture->cullRect().isEmpty()); - *compositeLocalMatrix = this->getLocalMatrix(); - if (outerLocalMatrix) { - compositeLocalMatrix->preConcat(*outerLocalMatrix); - } - const SkMatrix m = SkMatrix::Concat(viewMatrix, *compositeLocalMatrix); + const SkMatrix m = SkMatrix::Concat(viewMatrix, localMatrix); // Use a rotation-invariant scale SkPoint scale; @@ -274,37 +270,52 @@ sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, fAddedToCache.store(true); } - compositeLocalMatrix->preScale(1 / tileScale.width(), 1 / tileScale.height()); + scaleAdjust->set(1 / tileScale.width(), 1 / tileScale.height()); return tileShader; } bool SkPictureShader::onAppendStages(const StageRec& rec) const { + auto lm = this->totalLocalMatrix(rec.fLocalM); + SkVector scaleAdjust; + // Keep bitmapShader alive by using alloc instead of stack memory auto& bitmapShader = *rec.fAlloc->make<sk_sp<SkShader>>(); - SkMatrix compositeLocalMatrix; - bitmapShader = this->refBitmapShader(rec.fCTM, rec.fLocalM, rec.fDstCS, &compositeLocalMatrix); + bitmapShader = this->refBitmapShader(rec.fCTM, *lm, rec.fDstCS, &scaleAdjust); + + if (!bitmapShader) { + return false; + } + + if (scaleAdjust != SkVector::Make(1, 1)) { + lm.writable()->preScale(scaleAdjust.fX, scaleAdjust.fY); + } StageRec localRec = rec; - localRec.fLocalM = compositeLocalMatrix.isIdentity() ? nullptr : &compositeLocalMatrix; + localRec.fLocalM = lm->isIdentity() ? nullptr : &(*lm); - return bitmapShader && as_SB(bitmapShader)->appendStages(localRec); + return as_SB(bitmapShader)->appendStages(localRec); } ///////////////////////////////////////////////////////////////////////////////////////// SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { - SkMatrix compositeLocalMatrix; + auto lm = this->totalLocalMatrix(rec.fLocalMatrix); + SkVector scaleAdjust; sk_sp<SkShader> bitmapShader = this->refBitmapShader(*rec.fMatrix, - rec.fLocalMatrix, + *lm, rec.fDstColorSpace, - &compositeLocalMatrix); + &scaleAdjust); if (!bitmapShader) { return nullptr; } + if (scaleAdjust != SkVector::Make(1, 1)) { + lm.writable()->preScale(scaleAdjust.fX, scaleAdjust.fY); + } + ContextRec localRec = rec; - localRec.fLocalMatrix = compositeLocalMatrix.isIdentity() ? nullptr : &compositeLocalMatrix; + localRec.fLocalMatrix = lm->isIdentity() ? nullptr : &(*lm); PictureShaderContext* ctx = alloc->make<PictureShaderContext>(*this, localRec, std::move(bitmapShader), alloc); @@ -369,20 +380,22 @@ std::unique_ptr<GrFragmentProcessor> SkPictureShader::asFragmentProcessor( if (args.fContext) { maxTextureSize = args.fContext->caps()->maxTextureSize(); } - SkMatrix compositeLocalMatrix; - sk_sp<SkShader> bitmapShader(this->refBitmapShader(*args.fViewMatrix, args.fLocalMatrix, + + auto lm = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix); + SkVector scaleAdjust; + sk_sp<SkShader> bitmapShader(this->refBitmapShader(*args.fViewMatrix,*lm, args.fDstColorSpaceInfo->colorSpace(), - &compositeLocalMatrix, - maxTextureSize)); + &scaleAdjust, maxTextureSize)); if (!bitmapShader) { return nullptr; } - return as_SB(bitmapShader)->asFragmentProcessor( - GrFPArgs(args.fContext, - args.fViewMatrix, - compositeLocalMatrix.isIdentity() ? nullptr : &compositeLocalMatrix, - args.fFilterQuality, - args.fDstColorSpaceInfo)); + if (scaleAdjust != SkVector::Make(1, 1)) { + lm.writable()->preScale(scaleAdjust.fX, scaleAdjust.fY); + } + + GrFPArgs newArgs(args.fContext, args.fViewMatrix, args.fFilterQuality, args.fDstColorSpaceInfo); + + return as_SB(bitmapShader)->asFragmentProcessor(newArgs.makeWithPreLocalMatrix(*lm)); } #endif diff --git a/src/shaders/SkPictureShader.h b/src/shaders/SkPictureShader.h index 4970dac81b..5f28b6074b 100644 --- a/src/shaders/SkPictureShader.h +++ b/src/shaders/SkPictureShader.h @@ -46,9 +46,9 @@ private: SkPictureShader(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*, const SkRect*, sk_sp<SkColorSpace>); - sk_sp<SkShader> refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix, + sk_sp<SkShader> refBitmapShader(const SkMatrix&, const SkMatrix& localMatrix, SkColorSpace* dstColorSpace, - SkMatrix* compositeLocalMatrix, + SkVector* scaleAdjust, const int maxTextureSize = 0) const; class PictureShaderContext : public Context { diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp index 265f22beaa..f3ffd26ef4 100644 --- a/src/shaders/SkShader.cpp +++ b/src/shaders/SkShader.cpp @@ -67,15 +67,26 @@ void SkShaderBase::flatten(SkWriteBuffer& buffer) const { } } +SkTCopyOnFirstWrite<SkMatrix> +SkShaderBase::totalLocalMatrix(const SkMatrix* preLocalMatrix, + const SkMatrix* postLocalMatrix) const { + SkTCopyOnFirstWrite<SkMatrix> m(fLocalMatrix); + + if (preLocalMatrix) { + m.writable()->preConcat(*preLocalMatrix); + } + + if (postLocalMatrix) { + m.writable()->postConcat(*postLocalMatrix); + } + + return m; +} + bool SkShaderBase::computeTotalInverse(const SkMatrix& ctm, const SkMatrix* outerLocalMatrix, SkMatrix* totalInverse) const { - SkMatrix total = SkMatrix::Concat(ctm, fLocalMatrix); - if (outerLocalMatrix) { - total.preConcat(*outerLocalMatrix); - } - - return total.invert(totalInverse); + return SkMatrix::Concat(ctm, *this->totalLocalMatrix(outerLocalMatrix)).invert(totalInverse); } bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const { diff --git a/src/shaders/SkShaderBase.h b/src/shaders/SkShaderBase.h index 89674a6ebb..cddc5540ee 100644 --- a/src/shaders/SkShaderBase.h +++ b/src/shaders/SkShaderBase.h @@ -12,6 +12,7 @@ #include "SkMask.h" #include "SkMatrix.h" #include "SkShader.h" +#include "SkTLazy.h" #if SK_SUPPORT_GPU #include "GrFPArgs.h" @@ -185,9 +186,16 @@ public: // If this returns false, then we draw nothing (do not fall back to shader context) bool appendStages(const StageRec&) const; - bool computeTotalInverse(const SkMatrix& ctm, - const SkMatrix* outerLocalMatrix, - SkMatrix* totalInverse) const; + bool SK_WARN_UNUSED_RESULT computeTotalInverse(const SkMatrix& ctm, + const SkMatrix* outerLocalMatrix, + SkMatrix* totalInverse) const; + + // Returns the total local matrix for this shader: + // + // M = postLocalMatrix x shaderLocalMatrix x preLocalMatrix + // + SkTCopyOnFirstWrite<SkMatrix> totalLocalMatrix(const SkMatrix* preLocalMatrix, + const SkMatrix* postLocalMatrix = nullptr) const; #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const { diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp index b6436ca801..a377442dc4 100644 --- a/src/shaders/gradients/SkLinearGradient.cpp +++ b/src/shaders/gradients/SkLinearGradient.cpp @@ -195,16 +195,9 @@ std::unique_ptr<GrFragmentProcessor> SkLinearGradient::asFragmentProcessor( SkASSERT(args.fContext); SkMatrix matrix; - if (!this->getLocalMatrix().invert(&matrix)) { + if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) { return nullptr; } - if (args.fLocalMatrix) { - SkMatrix inv; - if (!args.fLocalMatrix->invert(&inv)) { - return nullptr; - } - matrix.postConcat(inv); - } matrix.postConcat(fPtsToUnit); return GrLinearGradient::Make(GrGradientEffect::CreateArgs( diff --git a/src/shaders/gradients/SkRadialGradient.cpp b/src/shaders/gradients/SkRadialGradient.cpp index 3f71f38c1f..6d193615a4 100644 --- a/src/shaders/gradients/SkRadialGradient.cpp +++ b/src/shaders/gradients/SkRadialGradient.cpp @@ -162,19 +162,10 @@ void GrRadialGradient::GLSLRadialProcessor::emitCode(EmitArgs& args) { std::unique_ptr<GrFragmentProcessor> SkRadialGradient::asFragmentProcessor( const GrFPArgs& args) const { - SkASSERT(args.fContext); - SkMatrix matrix; - if (!this->getLocalMatrix().invert(&matrix)) { + if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) { return nullptr; } - if (args.fLocalMatrix) { - SkMatrix inv; - if (!args.fLocalMatrix->invert(&inv)) { - return nullptr; - } - matrix.postConcat(inv); - } matrix.postConcat(fPtsToUnit); return GrRadialGradient::Make(GrGradientEffect::CreateArgs( diff --git a/src/shaders/gradients/SkSweepGradient.cpp b/src/shaders/gradients/SkSweepGradient.cpp index e9c4450b00..3f605d7761 100644 --- a/src/shaders/gradients/SkSweepGradient.cpp +++ b/src/shaders/gradients/SkSweepGradient.cpp @@ -216,16 +216,9 @@ void GrSweepGradient::GLSLSweepProcessor::emitCode(EmitArgs& args) { std::unique_ptr<GrFragmentProcessor> SkSweepGradient::asFragmentProcessor( const GrFPArgs& args) const { SkMatrix matrix; - if (!this->getLocalMatrix().invert(&matrix)) { + if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) { return nullptr; } - if (args.fLocalMatrix) { - SkMatrix inv; - if (!args.fLocalMatrix->invert(&inv)) { - return nullptr; - } - matrix.postConcat(inv); - } matrix.postConcat(fPtsToUnit); return GrSweepGradient::Make( diff --git a/src/shaders/gradients/SkTwoPointConicalGradient.cpp b/src/shaders/gradients/SkTwoPointConicalGradient.cpp index cce25d00b7..88f0f82245 100644 --- a/src/shaders/gradients/SkTwoPointConicalGradient.cpp +++ b/src/shaders/gradients/SkTwoPointConicalGradient.cpp @@ -175,9 +175,13 @@ void SkTwoPointConicalGradient::flatten(SkWriteBuffer& buffer) const { std::unique_ptr<GrFragmentProcessor> SkTwoPointConicalGradient::asFragmentProcessor( const GrFPArgs& args) const { - SkASSERT(args.fContext); + SkMatrix matrix; + if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) { + return nullptr; + } + return Gr2PtConicalGradientEffect::Make( - GrGradientEffect::CreateArgs(args.fContext, this, args.fLocalMatrix, fTileMode, + GrGradientEffect::CreateArgs(args.fContext, this, &matrix, fTileMode, args.fDstColorSpaceInfo->colorSpace())); } diff --git a/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp index c242895f1c..9d447785ed 100644 --- a/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp +++ b/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp @@ -388,18 +388,7 @@ std::unique_ptr<GrFragmentProcessor> Gr2PtConicalGradientEffect::Make( const SkTwoPointConicalGradient& shader = *static_cast<const SkTwoPointConicalGradient*>(args.fShader); - SkMatrix matrix; - if (!shader.getLocalMatrix().invert(&matrix)) { - return nullptr; - } - if (args.fMatrix) { - SkMatrix inv; - if (!args.fMatrix->invert(&inv)) { - return nullptr; - } - matrix.postConcat(inv); - } - + SkMatrix matrix = *args.fMatrix; GrGradientEffect::CreateArgs newArgs(args.fContext, args.fShader, &matrix, args.fWrapMode, args.fDstColorSpace); // Data and matrix has to be prepared before constructing TwoPointConicalEffect so its parent |