use rasterpipeline for images if matrix is >= scale+translate
Bug: skia:
Change-Id: I36112fe54c6f2d0965d0b88f0291d7ffe0902715
Reviewed-on: https://skia-review.googlesource.com/30480
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 6bd48be..a1a1db6 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -913,7 +913,7 @@
return true;
}
// ... or unless the shader is raster pipeline-only.
- if (paint.getShader() && as_SB(paint.getShader())->isRasterPipelineOnly()) {
+ if (paint.getShader() && as_SB(paint.getShader())->isRasterPipelineOnly(matrix)) {
return true;
}
diff --git a/src/shaders/SkColorFilterShader.h b/src/shaders/SkColorFilterShader.h
index 001f3cc..3a1878f 100644
--- a/src/shaders/SkColorFilterShader.h
+++ b/src/shaders/SkColorFilterShader.h
@@ -29,7 +29,7 @@
sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
const SkMatrix&, const SkPaint&, const SkMatrix* localM) const override;
- bool onIsRasterPipelineOnly() const override { return true; }
+ 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 432915d..1389742 100644
--- a/src/shaders/SkComposeShader.h
+++ b/src/shaders/SkComposeShader.h
@@ -45,7 +45,7 @@
bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
const SkMatrix&, const SkPaint&, const SkMatrix* localM) const override;
- bool onIsRasterPipelineOnly() const override { return true; }
+ bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; }
private:
sk_sp<SkShader> fDst;
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index 6657743..609ad4b 100644
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -61,7 +61,7 @@
return fImage->isOpaque();
}
-bool SkImageShader::IsRasterPipelineOnly(SkColorType ct, SkAlphaType at,
+bool SkImageShader::IsRasterPipelineOnly(const SkMatrix& ctm, SkColorType ct, SkAlphaType at,
SkShader::TileMode tx, SkShader::TileMode ty) {
if (ct != kN32_SkColorType) {
return true;
@@ -72,12 +72,17 @@
if (tx != ty) {
return true;
}
+#ifndef SK_SUPPORT_LEGACY_ROTATED_SHADERS
+ if (!ctm.isScaleTranslate()) {
+ return true;
+ }
+#endif
return false;
}
-bool SkImageShader::onIsRasterPipelineOnly() const {
+bool SkImageShader::onIsRasterPipelineOnly(const SkMatrix& ctm) const {
SkBitmapProvider provider(fImage.get(), nullptr);
- return IsRasterPipelineOnly(provider.info().colorType(), provider.info().alphaType(),
+ return IsRasterPipelineOnly(ctm, provider.info().colorType(), provider.info().alphaType(),
fTileModeX, fTileModeY);
}
diff --git a/src/shaders/SkImageShader.h b/src/shaders/SkImageShader.h
index b74c315..b499b92 100644
--- a/src/shaders/SkImageShader.h
+++ b/src/shaders/SkImageShader.h
@@ -29,7 +29,7 @@
SkImageShader(sk_sp<SkImage>, TileMode tx, TileMode ty, const SkMatrix* localMatrix);
- static bool IsRasterPipelineOnly(SkColorType, SkAlphaType,
+ static bool IsRasterPipelineOnly(const SkMatrix& ctm, SkColorType, SkAlphaType,
SkShader::TileMode tx, SkShader::TileMode ty);
protected:
@@ -40,7 +40,7 @@
#endif
SkImage* onIsAImage(SkMatrix*, TileMode*) const override;
- bool onIsRasterPipelineOnly() const override;
+ bool onIsRasterPipelineOnly(const SkMatrix& ctm) const override;
bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
const SkMatrix& ctm, const SkPaint&, const SkMatrix*) const override;
diff --git a/src/shaders/SkLocalMatrixShader.h b/src/shaders/SkLocalMatrixShader.h
index 5ae8e03..3ae44cf 100644
--- a/src/shaders/SkLocalMatrixShader.h
+++ b/src/shaders/SkLocalMatrixShader.h
@@ -62,8 +62,8 @@
}
#endif
- bool onIsRasterPipelineOnly() const override {
- return as_SB(fProxyShader)->isRasterPipelineOnly();
+ bool onIsRasterPipelineOnly(const SkMatrix& ctm) const override {
+ return as_SB(fProxyShader)->isRasterPipelineOnly(ctm);
}
private:
diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp
index 95a128e..4c746ee 100644
--- a/src/shaders/SkPictureShader.cpp
+++ b/src/shaders/SkPictureShader.cpp
@@ -291,8 +291,9 @@
return tileShader;
}
-bool SkPictureShader::onIsRasterPipelineOnly() const {
- return SkImageShader::IsRasterPipelineOnly(kN32_SkColorType, kPremul_SkAlphaType, fTmx, fTmy);
+bool SkPictureShader::onIsRasterPipelineOnly(const SkMatrix& ctm) const {
+ return SkImageShader::IsRasterPipelineOnly(ctm, kN32_SkColorType, kPremul_SkAlphaType,
+ fTmx, fTmy);
}
bool SkPictureShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
diff --git a/src/shaders/SkPictureShader.h b/src/shaders/SkPictureShader.h
index ee89f88..3d58d6d 100644
--- a/src/shaders/SkPictureShader.h
+++ b/src/shaders/SkPictureShader.h
@@ -42,7 +42,7 @@
const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
- bool onIsRasterPipelineOnly() 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 cc0d6b1..5540b2d 100644
--- a/src/shaders/SkShader.cpp
+++ b/src/shaders/SkShader.cpp
@@ -91,8 +91,6 @@
}
SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
- SkASSERT(!this->isRasterPipelineOnly());
-
return this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr)
? this->onMakeContext(rec, alloc)
: nullptr;
@@ -117,7 +115,7 @@
: fShader(shader), fCTM(*rec.fMatrix)
{
// We should never use a context for RP-only shaders.
- SkASSERT(!shader.isRasterPipelineOnly());
+ SkASSERT(!shader.isRasterPipelineOnly(*rec.fMatrix));
// ... or for perspective.
SkASSERT(!rec.fMatrix->hasPerspective());
SkASSERT(!rec.fLocalMatrix || !rec.fLocalMatrix->hasPerspective());
diff --git a/src/shaders/SkShaderBase.h b/src/shaders/SkShaderBase.h
index 783fff4..99cace2 100644
--- a/src/shaders/SkShaderBase.h
+++ b/src/shaders/SkShaderBase.h
@@ -187,9 +187,10 @@
return this->onMakeColorSpace(xformer);
}
- bool isRasterPipelineOnly() const {
+ bool isRasterPipelineOnly(const SkMatrix& ctm) const {
// We always use RP when perspective is present.
- return fLocalMatrix.hasPerspective() || this->onIsRasterPipelineOnly();
+ return ctm.hasPerspective() || fLocalMatrix.hasPerspective()
+ || this->onIsRasterPipelineOnly(ctm);
}
// If this returns false, then we draw nothing (do not fall back to shader context)
@@ -247,7 +248,7 @@
virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
const SkMatrix&, const SkPaint&, const SkMatrix* localM) const;
- virtual bool onIsRasterPipelineOnly() const { return false; }
+ virtual bool onIsRasterPipelineOnly(const SkMatrix& ctm) const { return false; }
private:
// This is essentially const, but not officially so it can be modified in constructors.
diff --git a/src/shaders/gradients/SkRadialGradient.h b/src/shaders/gradients/SkRadialGradient.h
index 5becf0a..8cd7df2 100644
--- a/src/shaders/gradients/SkRadialGradient.h
+++ b/src/shaders/gradients/SkRadialGradient.h
@@ -30,7 +30,7 @@
void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
SkRasterPipeline* postPipeline) const override;
- bool onIsRasterPipelineOnly() const override { return true; }
+ bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; }
private:
const SkPoint fCenter;
diff --git a/src/shaders/gradients/SkSweepGradient.h b/src/shaders/gradients/SkSweepGradient.h
index 92d3411..b42f270 100644
--- a/src/shaders/gradients/SkSweepGradient.h
+++ b/src/shaders/gradients/SkSweepGradient.h
@@ -30,7 +30,7 @@
void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
SkRasterPipeline* postPipeline) const override;
- bool onIsRasterPipelineOnly() const override { return true; }
+ bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; }
private:
const SkPoint fCenter;
diff --git a/src/shaders/gradients/SkTwoPointConicalGradient.h b/src/shaders/gradients/SkTwoPointConicalGradient.h
index 81b3b20..408f31d 100644
--- a/src/shaders/gradients/SkTwoPointConicalGradient.h
+++ b/src/shaders/gradients/SkTwoPointConicalGradient.h
@@ -41,7 +41,7 @@
void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
SkRasterPipeline* postPipeline) const override;
- bool onIsRasterPipelineOnly() const override { return true; }
+ bool onIsRasterPipelineOnly(const SkMatrix&) const override { return true; }
private:
enum class Type {