aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-04-04 13:46:35 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-04 18:13:48 +0000
commitaf2769d00b70ca456452e4e88bdf5abecd320f68 (patch)
tree83fef5b2e2a4d66ec9de911cfc33fdc2d5ffe6dd /src/shaders
parentbf74a460814a7912ed3d2e1af000afd2c45cd318 (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.h1
-rw-r--r--src/shaders/SkComposeShader.h2
-rw-r--r--src/shaders/SkImageShader.cpp50
-rw-r--r--src/shaders/SkImageShader.h6
-rw-r--r--src/shaders/SkLocalMatrixShader.h5
-rw-r--r--src/shaders/SkPictureShader.cpp5
-rw-r--r--src/shaders/SkPictureShader.h1
-rw-r--r--src/shaders/SkShader.cpp17
-rw-r--r--src/shaders/SkShaderBase.h8
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp7
-rw-r--r--src/shaders/gradients/SkGradientShaderPriv.h1
-rw-r--r--src/shaders/gradients/SkLinearGradient.cpp4
-rw-r--r--src/shaders/gradients/SkRadialGradient.h2
-rw-r--r--src/shaders/gradients/SkSweepGradient.h2
-rw-r--r--src/shaders/gradients/SkTwoPointConicalGradient.h2
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,