diff options
author | Florin Malita <fmalita@chromium.org> | 2018-04-04 13:46:35 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-04 18:13:48 +0000 |
commit | af2769d00b70ca456452e4e88bdf5abecd320f68 (patch) | |
tree | 83fef5b2e2a4d66ec9de911cfc33fdc2d5ffe6dd /src/shaders | |
parent | bf74a460814a7912ed3d2e1af000afd2c45cd318 (diff) |
Banish SkShaderBase::isRasterPipelineOnly()
Keeping related heuristics in sync with actual shader capabilities is somewhat tricky,
and overall fragile.
So how about this: instead of an explicit opt-in mechanism, try to instantiate a legacy
shader context and fall back to raster pipeline on failure (null Context => implicit
opt-in for raster pipeline). Shaders can still choose not to draw by returning both a
null Context and failing appendStages().
BUG=skia:7772
Change-Id: I2e76f51af7064853a6cb851b4c30c82eba3ee828
Reviewed-on: https://skia-review.googlesource.com/118383
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
Diffstat (limited to 'src/shaders')
-rw-r--r-- | src/shaders/SkColorFilterShader.h | 1 | ||||
-rw-r--r-- | src/shaders/SkComposeShader.h | 2 | ||||
-rw-r--r-- | src/shaders/SkImageShader.cpp | 50 | ||||
-rw-r--r-- | src/shaders/SkImageShader.h | 6 | ||||
-rw-r--r-- | src/shaders/SkLocalMatrixShader.h | 5 | ||||
-rw-r--r-- | src/shaders/SkPictureShader.cpp | 5 | ||||
-rw-r--r-- | src/shaders/SkPictureShader.h | 1 | ||||
-rw-r--r-- | src/shaders/SkShader.cpp | 17 | ||||
-rw-r--r-- | src/shaders/SkShaderBase.h | 8 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShader.cpp | 7 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShaderPriv.h | 1 | ||||
-rw-r--r-- | src/shaders/gradients/SkLinearGradient.cpp | 4 | ||||
-rw-r--r-- | src/shaders/gradients/SkRadialGradient.h | 2 | ||||
-rw-r--r-- | src/shaders/gradients/SkSweepGradient.h | 2 | ||||
-rw-r--r-- | src/shaders/gradients/SkTwoPointConicalGradient.h | 2 |
15 files changed, 33 insertions, 80 deletions
diff --git a/src/shaders/SkColorFilterShader.h b/src/shaders/SkColorFilterShader.h index e771f38123..c0083fd2a4 100644 --- a/src/shaders/SkColorFilterShader.h +++ b/src/shaders/SkColorFilterShader.h @@ -28,7 +28,6 @@ protected: void flatten(SkWriteBuffer&) const override; sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override; bool onAppendStages(const StageRec&) const override; - bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; } private: sk_sp<SkShader> fShader; diff --git a/src/shaders/SkComposeShader.h b/src/shaders/SkComposeShader.h index 7efa06cd99..ebcc86c1b0 100644 --- a/src/shaders/SkComposeShader.h +++ b/src/shaders/SkComposeShader.h @@ -44,8 +44,6 @@ protected: sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override; bool onAppendStages(const StageRec&) const override; - bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; } - private: sk_sp<SkShader> fDst; sk_sp<SkShader> fSrc; diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp index c3e6931baf..cdd9413ace 100644 --- a/src/shaders/SkImageShader.cpp +++ b/src/shaders/SkImageShader.cpp @@ -69,14 +69,8 @@ bool SkImageShader::isOpaque() const { return fImage->isOpaque() && fTileModeX != kDecal_TileMode && fTileModeY != kDecal_TileMode; } -static bool legacy_shader_can_handle(const SkMatrix& a, const SkMatrix& b) { - SkMatrix m = SkMatrix::Concat(a, b); - if (!m.isScaleTranslate()) { - return false; - } - - SkMatrix inv; - if (!m.invert(&inv)) { +static bool legacy_shader_can_handle(const SkMatrix& inv) { + if (!inv.isScaleTranslate()) { return false; } @@ -97,37 +91,31 @@ static bool legacy_shader_can_handle(const SkMatrix& a, const SkMatrix& b) { return true; } -bool SkImageShader::IsRasterPipelineOnly(const SkMatrix& ctm, SkColorType ct, SkAlphaType at, - SkShader::TileMode tx, SkShader::TileMode ty, - const SkMatrix& localM) { - if (ct != kN32_SkColorType) { - return true; +SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec, + SkArenaAlloc* alloc) const { + const auto info = as_IB(fImage)->onImageInfo(); + + if (info.colorType() != kN32_SkColorType) { + return nullptr; } - if (at == kUnpremul_SkAlphaType) { - return true; + if (info.alphaType() == kUnpremul_SkAlphaType) { + return nullptr; } #ifndef SK_SUPPORT_LEGACY_TILED_BITMAPS - if (tx != ty) { - return true; + if (fTileModeX != fTileModeY) { + return nullptr; } #endif - if (tx == kDecal_TileMode || ty == kDecal_TileMode) { - return true; - } - if (!legacy_shader_can_handle(ctm, localM)) { - return true; + if (fTileModeX == kDecal_TileMode || fTileModeY == kDecal_TileMode) { + return nullptr; } - return false; -} -bool SkImageShader::onIsRasterPipelineOnly(const SkMatrix& ctm) const { - SkBitmapProvider provider(fImage.get(), nullptr); - return IsRasterPipelineOnly(ctm, provider.info().colorType(), provider.info().alphaType(), - fTileModeX, fTileModeY, this->getLocalMatrix()); -} + SkMatrix inv; + if (!this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &inv) || + !legacy_shader_can_handle(inv)) { + return nullptr; + } -SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec, - SkArenaAlloc* alloc) const { return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY, SkBitmapProvider(fImage.get(), rec.fDstColorSpace), rec, alloc); diff --git a/src/shaders/SkImageShader.h b/src/shaders/SkImageShader.h index a024dc7185..78627d5c28 100644 --- a/src/shaders/SkImageShader.h +++ b/src/shaders/SkImageShader.h @@ -30,10 +30,6 @@ public: std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override; #endif - static bool IsRasterPipelineOnly(const SkMatrix& ctm, SkColorType, SkAlphaType, - SkShader::TileMode tx, SkShader::TileMode ty, - const SkMatrix& localM); - private: SkImageShader(sk_sp<SkImage>, SkShader::TileMode tx, @@ -48,8 +44,6 @@ private: #endif SkImage* onIsAImage(SkMatrix*, SkShader::TileMode*) const override; - bool onIsRasterPipelineOnly(const SkMatrix& ctm) const override; - bool onAppendStages(const StageRec&) const override; sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override { diff --git a/src/shaders/SkLocalMatrixShader.h b/src/shaders/SkLocalMatrixShader.h index 2d7e313ddd..890482eff8 100644 --- a/src/shaders/SkLocalMatrixShader.h +++ b/src/shaders/SkLocalMatrixShader.h @@ -61,11 +61,6 @@ protected: } #endif - bool onIsRasterPipelineOnly(const SkMatrix& ctm) const override { - return as_SB(fProxyShader)->isRasterPipelineOnly(SkMatrix::Concat(ctm, - this->getLocalMatrix())); - } - private: sk_sp<SkShader> fProxyShader; diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp index 097a60515e..21c9e5fab1 100644 --- a/src/shaders/SkPictureShader.cpp +++ b/src/shaders/SkPictureShader.cpp @@ -280,11 +280,6 @@ sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, return tileShader; } -bool SkPictureShader::onIsRasterPipelineOnly(const SkMatrix& ctm) const { - return SkImageShader::IsRasterPipelineOnly(ctm, kN32_SkColorType, kPremul_SkAlphaType, - fTmx, fTmy, this->getLocalMatrix()); -} - bool SkPictureShader::onAppendStages(const StageRec& rec) const { // Keep bitmapShader alive by using alloc instead of stack memory auto& bitmapShader = *rec.fAlloc->make<sk_sp<SkShader>>(); diff --git a/src/shaders/SkPictureShader.h b/src/shaders/SkPictureShader.h index 3b7cab0f2d..6ad7165899 100644 --- a/src/shaders/SkPictureShader.h +++ b/src/shaders/SkPictureShader.h @@ -41,7 +41,6 @@ protected: bool onAppendStages(const StageRec&) const override; Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override; sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override; - bool onIsRasterPipelineOnly(const SkMatrix&) const override; private: SkPictureShader(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*, const SkRect*, diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp index 2dcba94983..195ac29d15 100644 --- a/src/shaders/SkShader.cpp +++ b/src/shaders/SkShader.cpp @@ -91,9 +91,15 @@ bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const { } SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { - return this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr) - ? this->onMakeContext(rec, alloc) - : nullptr; + // We always fall back to raster pipeline when perspective is present. + if (rec.fMatrix->hasPerspective() || + fLocalMatrix.hasPerspective() || + (rec.fLocalMatrix && rec.fLocalMatrix->hasPerspective()) || + !this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr)) { + return nullptr; + } + + return this->onMakeContext(rec, alloc); } SkShaderBase::Context* SkShaderBase::makeBurstPipelineContext(const ContextRec& rec, @@ -114,11 +120,10 @@ SkShaderBase::Context* SkShaderBase::makeBurstPipelineContext(const ContextRec& SkShaderBase::Context::Context(const SkShaderBase& shader, const ContextRec& rec) : fShader(shader), fCTM(*rec.fMatrix) { - // We should never use a context for RP-only shaders. - SkASSERT(!shader.isRasterPipelineOnly(*rec.fMatrix)); - // ... or for perspective. + // We should never use a context with perspective. SkASSERT(!rec.fMatrix->hasPerspective()); SkASSERT(!rec.fLocalMatrix || !rec.fLocalMatrix->hasPerspective()); + SkASSERT(!shader.getLocalMatrix().hasPerspective()); // Because the context parameters must be valid at this point, we know that the matrix is // invertible. diff --git a/src/shaders/SkShaderBase.h b/src/shaders/SkShaderBase.h index f72863e498..a4b0607a61 100644 --- a/src/shaders/SkShaderBase.h +++ b/src/shaders/SkShaderBase.h @@ -173,12 +173,6 @@ public: return this->onMakeColorSpace(xformer); } - bool isRasterPipelineOnly(const SkMatrix& ctm) const { - // We always use RP when perspective is present. - return ctm.hasPerspective() || fLocalMatrix.hasPerspective() - || this->onIsRasterPipelineOnly(ctm); - } - struct StageRec { SkRasterPipeline* fPipeline; SkArenaAlloc* fAlloc; @@ -241,8 +235,6 @@ protected: // Default impl creates shadercontext and calls that (not very efficient) virtual bool onAppendStages(const StageRec&) const; - virtual bool onIsRasterPipelineOnly(const SkMatrix& ctm) const { return false; } - private: // This is essentially const, but not officially so it can be modified in constructors. SkMatrix fLocalMatrix; diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 114b7c58a1..82ae1294ca 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -419,13 +419,6 @@ bool SkGradientShaderBase::isOpaque() const { return fColorsAreOpaque && (this->getTileMode() != SkShader::kDecal_TileMode); } -bool SkGradientShaderBase::onIsRasterPipelineOnly(const SkMatrix& ctm) const { - if (this->getTileMode() == SkShader::kDecal_TileMode) { - return true; - } - return this->INHERITED::onIsRasterPipelineOnly(ctm); -} - static unsigned rounded_divide(unsigned numer, unsigned denom) { return (numer + (denom >> 1)) / denom; } diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h index 7fef12758a..29c8c6eb20 100644 --- a/src/shaders/gradients/SkGradientShaderPriv.h +++ b/src/shaders/gradients/SkGradientShaderPriv.h @@ -94,7 +94,6 @@ protected: void initLinearBitmap(SkBitmap* bitmap, GradientBitmapType) const; bool onAppendStages(const StageRec&) const override; - bool onIsRasterPipelineOnly(const SkMatrix& ctm) const override; virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, SkRasterPipeline* postPipeline) const = 0; diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp index 739822157c..21338b8143 100644 --- a/src/shaders/gradients/SkLinearGradient.cpp +++ b/src/shaders/gradients/SkLinearGradient.cpp @@ -55,7 +55,9 @@ void SkLinearGradient::flatten(SkWriteBuffer& buffer) const { SkShaderBase::Context* SkLinearGradient::onMakeContext( const ContextRec& rec, SkArenaAlloc* alloc) const { - return CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec); + return fTileMode != kDecal_TileMode + ? CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec) + : nullptr; } SkShaderBase::Context* SkLinearGradient::onMakeBurstPipelineContext( diff --git a/src/shaders/gradients/SkRadialGradient.h b/src/shaders/gradients/SkRadialGradient.h index 06ba27ffb3..2fac4c635a 100644 --- a/src/shaders/gradients/SkRadialGradient.h +++ b/src/shaders/gradients/SkRadialGradient.h @@ -30,8 +30,6 @@ protected: void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, SkRasterPipeline* postPipeline) const override; - bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; } - private: const SkPoint fCenter; const SkScalar fRadius; diff --git a/src/shaders/gradients/SkSweepGradient.h b/src/shaders/gradients/SkSweepGradient.h index c4b5c67830..49b789c4c4 100644 --- a/src/shaders/gradients/SkSweepGradient.h +++ b/src/shaders/gradients/SkSweepGradient.h @@ -30,8 +30,6 @@ protected: void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, SkRasterPipeline* postPipeline) const override; - bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; } - private: const SkPoint fCenter; const SkScalar fTBias, diff --git a/src/shaders/gradients/SkTwoPointConicalGradient.h b/src/shaders/gradients/SkTwoPointConicalGradient.h index 413a199b3d..59728ef984 100644 --- a/src/shaders/gradients/SkTwoPointConicalGradient.h +++ b/src/shaders/gradients/SkTwoPointConicalGradient.h @@ -74,8 +74,6 @@ protected: void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, SkRasterPipeline* postPipeline) const override; - bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; } - private: SkTwoPointConicalGradient(const SkPoint& c0, SkScalar r0, const SkPoint& c1, SkScalar r1, |