aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-01-27 10:59:27 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-27 16:43:38 +0000
commit587e08f361ee3e775a6bbc6dca761dbba82e422c (patch)
tree9f64e10d50fab820419d29dea30a6c978c86c8c9 /src
parent4d3adb6b0dea1c9f74fc00b007dfb1af425fc727 (diff)
Revert "Revert "Start of rewrite of GrFragmentProcessor optimizations.""
This reverts commit 052fd5158f7f85e478a9f87c45fecaacf7d0f5f3. Disables the test (of unused code) until platform-specific issues are addressed. Change-Id: I7aa23a07954fccf382aa07d28afcbffb0bebcd6d Reviewed-on: https://skia-review.googlesource.com/7656 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkColorMatrixFilterRowMajor255.cpp5
-rw-r--r--src/core/SkLightingShader.cpp6
-rw-r--r--src/core/SkNormalBevelSource.cpp11
-rw-r--r--src/core/SkNormalFlatSource.cpp15
-rw-r--r--src/core/SkNormalMapSource.cpp4
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.cpp29
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.h2
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.cpp9
-rw-r--r--src/effects/SkArithmeticImageFilter.cpp8
-rw-r--r--src/effects/SkBlurMaskFilter.cpp20
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp38
-rw-r--r--src/effects/SkGaussianEdgeShader.cpp6
-rw-r--r--src/effects/SkLightingImageFilter.cpp15
-rw-r--r--src/effects/SkLumaColorFilter.cpp10
-rw-r--r--src/effects/SkMagnifierImageFilter.cpp18
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp14
-rw-r--r--src/effects/SkOverdrawColorFilter.cpp6
-rw-r--r--src/effects/SkPerlinNoiseShader.cpp18
-rw-r--r--src/effects/SkRRectsGaussianEdgeMaskFilter.cpp4
-rw-r--r--src/effects/SkTableColorFilter.cpp9
-rw-r--r--src/effects/gradients/SkGradientShader.cpp8
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h6
-rw-r--r--src/effects/gradients/SkLinearGradient.cpp3
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp3
-rw-r--r--src/effects/gradients/SkSweepGradient.cpp3
-rw-r--r--src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp22
-rwxr-xr-xsrc/effects/shadows/SkAmbientShadowMaskFilter.cpp6
-rw-r--r--src/gpu/GrFragmentProcessor.cpp79
-rw-r--r--src/gpu/SkGrPriv.h18
-rw-r--r--src/gpu/effects/Gr1DKernelEffect.h12
-rw-r--r--src/gpu/effects/GrBicubicEffect.cpp18
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp8
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.h1
-rw-r--r--src/gpu/effects/GrConstColorProcessor.cpp13
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.cpp5
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp4
-rw-r--r--src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp3
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.cpp14
-rw-r--r--src/gpu/effects/GrOvalEffect.cpp14
-rw-r--r--src/gpu/effects/GrRRectEffect.cpp14
-rw-r--r--src/gpu/effects/GrSRGBEffect.cpp24
-rw-r--r--src/gpu/effects/GrSRGBEffect.h1
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.h54
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.cpp66
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.h36
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp18
-rw-r--r--src/gpu/effects/GrTextureDomain.h2
-rw-r--r--src/gpu/effects/GrXfermodeFragmentProcessor.cpp56
-rw-r--r--src/gpu/effects/GrYUVEffect.cpp30
49 files changed, 532 insertions, 256 deletions
diff --git a/src/core/SkColorMatrixFilterRowMajor255.cpp b/src/core/SkColorMatrixFilterRowMajor255.cpp
index 2bcc79e4cc..167fd21b38 100644
--- a/src/core/SkColorMatrixFilterRowMajor255.cpp
+++ b/src/core/SkColorMatrixFilterRowMajor255.cpp
@@ -345,9 +345,10 @@ public:
typedef GrGLSLFragmentProcessor INHERITED;
};
-
private:
- ColorMatrixEffect(const SkScalar matrix[20]) {
+ // We could implement the constant input->constant output optimization but haven't. Other
+ // optimizations would be matrix-dependent.
+ ColorMatrixEffect(const SkScalar matrix[20]) : INHERITED(kNone_OptimizationFlags) {
memcpy(fMatrix, matrix, sizeof(SkScalar) * 20);
this->initClassID<ColorMatrixEffect>();
}
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp
index bb2828a13e..4ed0057682 100644
--- a/src/core/SkLightingShader.cpp
+++ b/src/core/SkLightingShader.cpp
@@ -117,8 +117,8 @@ private:
// premul'd.
class LightingFP : public GrFragmentProcessor {
public:
- LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights) {
-
+ LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights)
+ : INHERITED(kPreservesOpaqueInput_OptimizationFlag) {
// fuse all ambient lights into a single one
fAmbientColor = lights->ambientLightColor();
for (int i = 0; i < lights->numLights(); ++i) {
@@ -263,6 +263,8 @@ private:
SkTArray<SkLights::Light> fDirectionalLights;
SkColor3f fAmbientColor;
+
+ typedef GrFragmentProcessor INHERITED;
};
////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp
index bcdb999c15..5d49253b01 100644
--- a/src/core/SkNormalBevelSource.cpp
+++ b/src/core/SkNormalBevelSource.cpp
@@ -30,12 +30,13 @@
class NormalBevelFP : public GrFragmentProcessor {
public:
NormalBevelFP(SkNormalSource::BevelType bevelType, SkScalar bevelWidth, SkScalar bevelHeight)
- : fBevelType(bevelType)
- , fBevelWidth(bevelWidth)
- , fBevelHeight(bevelHeight) {
+ : INHERITED(kNone_OptimizationFlags)
+ , fBevelType(bevelType)
+ , fBevelWidth(bevelWidth)
+ , fBevelHeight(bevelHeight) {
this->initClassID<NormalBevelFP>();
- fUsesDistanceVectorField = true;
+ this->setWillUseDistanceVectorField();
}
class GLSLNormalBevelFP : public GLSLNormalFP {
@@ -239,6 +240,8 @@ private:
SkNormalSource::BevelType fBevelType;
SkScalar fBevelWidth;
SkScalar fBevelHeight;
+
+ typedef GrFragmentProcessor INHERITED;
};
sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor(
diff --git a/src/core/SkNormalFlatSource.cpp b/src/core/SkNormalFlatSource.cpp
index 4fca57c1f3..b4ed977285 100644
--- a/src/core/SkNormalFlatSource.cpp
+++ b/src/core/SkNormalFlatSource.cpp
@@ -20,7 +20,7 @@
class NormalFlatFP : public GrFragmentProcessor {
public:
- NormalFlatFP() {
+ NormalFlatFP() : INHERITED(kConstantOutputForConstantInput_OptimizationFlag) {
this->initClassID<NormalFlatFP>();
}
@@ -43,20 +43,23 @@ public:
const GrProcessor& proc) override {}
};
+ const char* name() const override { return "NormalFlatFP"; }
+
+private:
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
GLSLNormalFlatFP::GenKey(*this, caps, b);
}
-
- const char* name() const override { return "NormalFlatFP"; }
-
void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
inout->setToUnknown();
}
-
-private:
+ GrColor4f constantOutputForConstantInput(GrColor4f) const override {
+ return GrColor4f(0, 0, 1, 0);
+ }
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLNormalFlatFP; }
bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
+
+ typedef GrFragmentProcessor INHERITED;
};
sk_sp<GrFragmentProcessor> SkNormalFlatSourceImpl::asFragmentProcessor(
diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp
index 71e5565ac8..3a9f9cf76f 100644
--- a/src/core/SkNormalMapSource.cpp
+++ b/src/core/SkNormalMapSource.cpp
@@ -26,7 +26,7 @@
class NormalMapFP : public GrFragmentProcessor {
public:
NormalMapFP(sk_sp<GrFragmentProcessor> mapFP, const SkMatrix& invCTM)
- : fInvCTM(invCTM) {
+ : INHERITED(kNone_OptimizationFlags), fInvCTM(invCTM) {
this->registerChildProcessor(mapFP);
this->initClassID<NormalMapFP>();
@@ -117,6 +117,8 @@ private:
}
SkMatrix fInvCTM;
+
+ typedef GrFragmentProcessor INHERITED;
};
sk_sp<GrFragmentProcessor> SkNormalMapSourceImpl::asFragmentProcessor(
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
index a259607444..8f9e45dc2b 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
@@ -32,6 +32,14 @@ sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::Make(
bounds));
}
+inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::OptFlags(float outerThreshold) {
+ if (outerThreshold >= 1.f) {
+ return kPreservesOpaqueInput_OptimizationFlag | kModulatesInput_OptimizationFlag;
+ } else {
+ return kModulatesInput_OptimizationFlag;
+ }
+}
+
GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
@@ -39,16 +47,17 @@ GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
float innerThreshold,
float outerThreshold,
const SkIRect& bounds)
- : fInnerThreshold(innerThreshold)
- , fOuterThreshold(outerThreshold)
- , fImageCoordTransform(SkMatrix::I(), texture, GrSamplerParams::kNone_FilterMode)
- , fImageTextureSampler(texture)
- , fColorSpaceXform(std::move(colorSpaceXform))
- , fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()),
- SkIntToScalar(-bounds.y())),
- maskTexture,
- GrSamplerParams::kNone_FilterMode)
- , fMaskTextureSampler(maskTexture) {
+ : INHERITED(OptFlags(outerThreshold))
+ , fInnerThreshold(innerThreshold)
+ , fOuterThreshold(outerThreshold)
+ , fImageCoordTransform(SkMatrix::I(), texture, GrSamplerParams::kNone_FilterMode)
+ , fImageTextureSampler(texture)
+ , fColorSpaceXform(std::move(colorSpaceXform))
+ , fMaskCoordTransform(
+ SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
+ maskTexture,
+ GrSamplerParams::kNone_FilterMode)
+ , fMaskTextureSampler(maskTexture) {
this->initClassID<GrAlphaThresholdFragmentProcessor>();
this->addCoordTransform(&fImageCoordTransform);
this->addTextureSampler(&fImageTextureSampler);
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.h b/src/effects/GrAlphaThresholdFragmentProcessor.h
index f7a2491aee..f2c14c64bc 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.h
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.h
@@ -35,6 +35,8 @@ public:
GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); }
private:
+ static OptimizationFlags OptFlags(float outerThreshold);
+
GrAlphaThresholdFragmentProcessor(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
GrTexture* maskTexture,
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index d3eb325b34..91d17d6e6c 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -88,10 +88,11 @@ GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circl
float textureRadius,
float solidRadius,
GrTexture* blurProfile)
- : fCircle(circle)
- , fSolidRadius(solidRadius)
- , fTextureRadius(textureRadius)
- , fBlurProfileSampler(blurProfile, GrSamplerParams::kBilerp_FilterMode) {
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fCircle(circle)
+ , fSolidRadius(solidRadius)
+ , fTextureRadius(textureRadius)
+ , fBlurProfileSampler(blurProfile, GrSamplerParams::kBilerp_FilterMode) {
this->initClassID<GrCircleBlurFragmentProcessor>();
this->addTextureSampler(&fBlurProfileSampler);
}
diff --git a/src/effects/SkArithmeticImageFilter.cpp b/src/effects/SkArithmeticImageFilter.cpp
index 8d80984bdf..a9a232554f 100644
--- a/src/effects/SkArithmeticImageFilter.cpp
+++ b/src/effects/SkArithmeticImageFilter.cpp
@@ -290,9 +290,15 @@ private:
inout->setToUnknown();
}
+ // This could implement the const input -> const output optimization but it's unlikely to help.
ArithmeticFP(float k1, float k2, float k3, float k4, bool enforcePMColor,
sk_sp<GrFragmentProcessor> dst)
- : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) {
+ : INHERITED(kNone_OptimizationFlags)
+ , fK1(k1)
+ , fK2(k2)
+ , fK3(k3)
+ , fK4(k4)
+ , fEnforcePMColor(enforcePMColor) {
this->initClassID<ArithmeticFP>();
SkASSERT(dst);
SkDEBUGCODE(int dstIndex =) this->registerChildProcessor(std::move(dst));
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index b53fc41dea..bf544077df 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -974,12 +974,13 @@ GrTexture* GrRectBlurEffect::CreateBlurProfileTexture(GrTextureProvider* texture
return blurProfile;
}
-GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile,
+GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture* blurProfile,
GrSLPrecision precision)
- : fRect(rect)
- , fSigma(sigma)
- , fBlurProfileSampler(blurProfile)
- , fPrecision(precision) {
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fRect(rect)
+ , fSigma(sigma)
+ , fBlurProfileSampler(blurProfile)
+ , fPrecision(precision) {
this->initClassID<GrRectBlurEffect>();
this->addTextureSampler(&fBlurProfileSampler);
}
@@ -1206,10 +1207,11 @@ void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
inout->mulByUnknownSingleComponent();
}
-GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)
- : fRRect(rrect),
- fSigma(sigma),
- fNinePatchSampler(ninePatchTexture) {
+GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture* ninePatchTexture)
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fRRect(rrect)
+ , fSigma(sigma)
+ , fNinePatchSampler(ninePatchTexture) {
this->initClassID<GrRRectBlurEffect>();
this->addTextureSampler(&fNinePatchSampler);
}
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index d838e1e347..cee47f4f3f 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -487,24 +487,26 @@ void GrDisplacementMapEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
}
GrDisplacementMapEffect::GrDisplacementMapEffect(
- SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
- SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
- const SkVector& scale,
- GrTexture* displacement,
- const SkMatrix& offsetMatrix,
- GrTexture* color,
- sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkISize& colorDimensions)
- : fDisplacementTransform(offsetMatrix, displacement, GrSamplerParams::kNone_FilterMode)
- , fDisplacementSampler(displacement)
- , fColorTransform(color, GrSamplerParams::kNone_FilterMode)
- , fDomain(color, GrTextureDomain::MakeTexelDomain(SkIRect::MakeSize(colorDimensions)),
- GrTextureDomain::kDecal_Mode)
- , fColorSampler(color)
- , fColorSpaceXform(std::move(colorSpaceXform))
- , fXChannelSelector(xChannelSelector)
- , fYChannelSelector(yChannelSelector)
- , fScale(scale) {
+ SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
+ SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
+ const SkVector& scale,
+ GrTexture* displacement,
+ const SkMatrix& offsetMatrix,
+ GrTexture* color,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkISize& colorDimensions)
+ : INHERITED(GrPixelConfigIsOpaque(color->config()) ? kPreservesOpaqueInput_OptimizationFlag
+ : kNone_OptimizationFlags)
+ , fDisplacementTransform(offsetMatrix, displacement, GrSamplerParams::kNone_FilterMode)
+ , fDisplacementSampler(displacement)
+ , fColorTransform(color, GrSamplerParams::kNone_FilterMode)
+ , fDomain(color, GrTextureDomain::MakeTexelDomain(SkIRect::MakeSize(colorDimensions)),
+ GrTextureDomain::kDecal_Mode)
+ , fColorSampler(color)
+ , fColorSpaceXform(std::move(colorSpaceXform))
+ , fXChannelSelector(xChannelSelector)
+ , fYChannelSelector(yChannelSelector)
+ , fScale(scale) {
this->initClassID<GrDisplacementMapEffect>();
this->addCoordTransform(&fDisplacementTransform);
this->addTextureSampler(&fDisplacementSampler);
diff --git a/src/effects/SkGaussianEdgeShader.cpp b/src/effects/SkGaussianEdgeShader.cpp
index 7405fd14d9..5bd7dca124 100644
--- a/src/effects/SkGaussianEdgeShader.cpp
+++ b/src/effects/SkGaussianEdgeShader.cpp
@@ -63,11 +63,11 @@ private:
class GaussianEdgeFP : public GrFragmentProcessor {
public:
- GaussianEdgeFP() {
+ GaussianEdgeFP() : INHERITED(kNone_OptimizationFlags) {
this->initClassID<GaussianEdgeFP>();
// enable output of distance information for shape
- fUsesDistanceVectorField = true;
+ this->setWillUseDistanceVectorField();
}
class GLSLGaussianEdgeFP : public GrGLSLFragmentProcessor {
@@ -123,6 +123,8 @@ private:
}
bool onIsEqual(const GrFragmentProcessor& proc) const override { return true; }
+
+ typedef GrFragmentProcessor INHERITED;
};
////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index da4dcb8bdf..3a03a1701c 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1625,7 +1625,7 @@ SkString emitNormalFunc(BoundaryMode mode,
}
-class GrGLLightingEffect : public GrGLSLFragmentProcessor {
+class GrGLLightingEffect : public GrGLSLFragmentProcessor {
public:
GrGLLightingEffect() : fLight(nullptr) { }
virtual ~GrGLLightingEffect() { delete fLight; }
@@ -1702,12 +1702,13 @@ GrLightingEffect::GrLightingEffect(GrTexture* texture,
const SkMatrix& matrix,
BoundaryMode boundaryMode,
const SkIRect* srcBounds)
- : INHERITED(texture, nullptr, SkMatrix::I())
- , fLight(light)
- , fSurfaceScale(surfaceScale)
- , fFilterMatrix(matrix)
- , fBoundaryMode(boundaryMode)
- , fDomain(create_domain(texture, srcBounds, GrTextureDomain::kDecal_Mode)) {
+ // Perhaps this could advertise the opaque or modulating optimizations?
+ : INHERITED(texture, nullptr, SkMatrix::I(), kNone_OptimizationFlags)
+ , fLight(light)
+ , fSurfaceScale(surfaceScale)
+ , fFilterMatrix(matrix)
+ , fBoundaryMode(boundaryMode)
+ , fDomain(create_domain(texture, srcBounds, GrTextureDomain::kDecal_Mode)) {
fLight->ref();
}
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index a9516af63d..1792437e34 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -98,7 +98,7 @@ public:
};
private:
- LumaColorFilterEffect() {
+ LumaColorFilterEffect() : INHERITED(kConstantOutputForConstantInput_OptimizationFlag) {
this->initClassID<LumaColorFilterEffect>();
}
@@ -117,6 +117,14 @@ private:
// The output is always black. The alpha value for the color passed in is arbitrary.
inout->setToOther(kRGB_GrColorComponentFlags, GrColorPackRGBA(0, 0, 0, 0));
}
+ GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
+ float luma = SK_ITU_BT709_LUM_COEFF_R * input.fRGBA[0] +
+ SK_ITU_BT709_LUM_COEFF_G * input.fRGBA[1] +
+ SK_ITU_BT709_LUM_COEFF_B * input.fRGBA[2];
+ return GrColor4f(0, 0, 0, luma);
+ }
+
+ typedef GrFragmentProcessor INHERITED;
};
sk_sp<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const {
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index c8b32aee70..49f4fdddc3 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -27,7 +27,6 @@
#include "../private/GrGLSL.h"
class GrMagnifierEffect : public GrSingleTextureEffect {
-
public:
static sk_sp<GrFragmentProcessor> Make(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
@@ -71,14 +70,15 @@ private:
float yInvZoom,
float xInvInset,
float yInvInset)
- : INHERITED(texture, std::move(colorSpaceXform), SkMatrix::I())
- , fBounds(bounds)
- , fXOffset(xOffset)
- , fYOffset(yOffset)
- , fXInvZoom(xInvZoom)
- , fYInvZoom(yInvZoom)
- , fXInvInset(xInvInset)
- , fYInvInset(yInvInset) {
+ : INHERITED(texture, std::move(colorSpaceXform), SkMatrix::I(),
+ ModulationFlags(texture->config()))
+ , fBounds(bounds)
+ , fXOffset(xOffset)
+ , fYOffset(yOffset)
+ , fXInvZoom(xInvZoom)
+ , fYInvZoom(yInvZoom)
+ , fXInvInset(xInvInset)
+ , fYInvInset(yInvInset) {
this->initClassID<GrMagnifierEffect>();
}
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 6e2a80507f..febde203d5 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -140,9 +140,7 @@ void SkDilateImageFilter::toString(SkString* str) const {
* color.
*/
class GrMorphologyEffect : public Gr1DKernelEffect {
-
public:
-
enum MorphologyType {
kErode_MorphologyType,
kDilate_MorphologyType,
@@ -327,9 +325,9 @@ GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
Direction direction,
int radius,
MorphologyType type)
- : INHERITED(texture, direction, radius)
- , fType(type)
- , fUseRange(false) {
+ : INHERITED(texture, direction, radius, ModulationFlags(texture->config()))
+ , fType(type)
+ , fUseRange(false) {
this->initClassID<GrMorphologyEffect>();
}
@@ -338,9 +336,9 @@ GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
int radius,
MorphologyType type,
const float range[2])
- : INHERITED(texture, direction, radius)
- , fType(type)
- , fUseRange(true) {
+ : INHERITED(texture, direction, radius, ModulationFlags(texture->config()))
+ , fType(type)
+ , fUseRange(true) {
this->initClassID<GrMorphologyEffect>();
fRange[0] = range[0];
fRange[1] = range[1];
diff --git a/src/effects/SkOverdrawColorFilter.cpp b/src/effects/SkOverdrawColorFilter.cpp
index dea4f8b6de..243ef77cd0 100644
--- a/src/effects/SkOverdrawColorFilter.cpp
+++ b/src/effects/SkOverdrawColorFilter.cpp
@@ -59,7 +59,6 @@ public:
static sk_sp<GrFragmentProcessor> Make(const SkPMColor* colors);
const char* name() const override { return "Overdraw"; }
-
private:
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
@@ -105,7 +104,10 @@ sk_sp<GrFragmentProcessor> OverdrawFragmentProcessor::Make(const SkPMColor* colo
return sk_sp<OverdrawFragmentProcessor>(new OverdrawFragmentProcessor(grColors));
}
-OverdrawFragmentProcessor::OverdrawFragmentProcessor(const GrColor4f* colors) {
+// This could implement the constant input -> constant output optimization, but we don't really
+// care given how this is used.
+OverdrawFragmentProcessor::OverdrawFragmentProcessor(const GrColor4f* colors)
+ : INHERITED(kNone_OptimizationFlags) {
this->initClassID<OverdrawFragmentProcessor>();
memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f));
}
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index 3798a407ac..450fcaa4ef 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -538,18 +538,18 @@ private:
inout->setToUnknown();
}
- GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type,
- int numOctaves, bool stitchTiles,
+ GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, int numOctaves, bool stitchTiles,
SkPerlinNoiseShader::PaintingData* paintingData,
GrTexture* permutationsTexture, GrTexture* noiseTexture,
const SkMatrix& matrix)
- : fType(type)
- , fCoordTransform(matrix)
- , fNumOctaves(numOctaves)
- , fStitchTiles(stitchTiles)
- , fPermutationsSampler(permutationsTexture)
- , fNoiseSampler(noiseTexture)
- , fPaintingData(paintingData) {
+ : INHERITED(kNone_OptimizationFlags)
+ , fType(type)
+ , fCoordTransform(matrix)
+ , fNumOctaves(numOctaves)
+ , fStitchTiles(stitchTiles)
+ , fPermutationsSampler(permutationsTexture)
+ , fNoiseSampler(noiseTexture)
+ , fPaintingData(paintingData) {
this->initClassID<GrPerlinNoiseEffect>();
this->addTextureSampler(&fPermutationsSampler);
this->addTextureSampler(&fNoiseSampler);
diff --git a/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp b/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp
index 5da3ed1eb1..223887bab9 100644
--- a/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp
+++ b/src/effects/SkRRectsGaussianEdgeMaskFilter.cpp
@@ -207,9 +207,7 @@ public:
};
RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, SkScalar radius)
- : fFirst(first)
- , fSecond(second)
- , fRadius(radius) {
+ : INHERITED(kNone_OptimizationFlags), fFirst(first), fSecond(second), fRadius(radius) {
this->initClassID<RRectsGaussianEdgeFP>();
fFirstMode = ComputeMode(fFirst);
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 1fd4c90eed..9198460c66 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -512,10 +512,11 @@ sk_sp<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context, SkBitmap b
ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row,
unsigned flags)
- : fTextureSampler(texture)
- , fFlags(flags)
- , fAtlas(atlas)
- , fRow(row) {
+ : INHERITED(kNone_OptimizationFlags) // Not bothering with table-specific optimizations.
+ , fTextureSampler(texture)
+ , fFlags(flags)
+ , fAtlas(atlas)
+ , fRow(row) {
this->initClassID<ColorTableEffect>();
this->addTextureSampler(&fTextureSampler);
}
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index b1d3e13a46..9a3438efe0 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -1572,7 +1572,13 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
/////////////////////////////////////////////////////////////////////
-GrGradientEffect::GrGradientEffect(const CreateArgs& args) {
+inline GrFragmentProcessor::OptimizationFlags GrGradientEffect::OptFlags(bool isOpaque) {
+ return isOpaque ? kPreservesOpaqueInput_OptimizationFlag | kModulatesInput_OptimizationFlag
+ : kModulatesInput_OptimizationFlag;
+}
+
+GrGradientEffect::GrGradientEffect(const CreateArgs& args, bool isOpaque)
+ : INHERITED(OptFlags(isOpaque)) {
const SkGradientShaderBase& shader(*args.fShader);
fIsOpaque = shader.isOpaque();
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 48ccbd50d0..6f46698eba 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -352,8 +352,6 @@ public:
class GLSLProcessor;
- GrGradientEffect(const CreateArgs&);
-
virtual ~GrGradientEffect();
bool useAtlas() const { return SkToBool(-1 != fRow); }
@@ -402,6 +400,8 @@ public:
}
protected:
+ GrGradientEffect(const CreateArgs&, bool isOpaque);
+
/** Helper struct that stores (and populates) parameters to construct a random gradient.
If fUseColors4f is true, then the SkColor4f factory should be called, with fColors4f and
fColorSpace. Otherwise, the SkColor factory should be called, with fColors. fColorCount
@@ -430,6 +430,8 @@ protected:
const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
private:
+ static OptimizationFlags OptFlags(bool isOpaque);
+
// If we're in legacy mode, then fColors will be populated. If we're gamma-correct, then
// fColors4f and fColorSpaceXform will be populated.
SkTDArray<SkColor> fColors;
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index aab1ac787a..07418e8010 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -426,8 +426,7 @@ public:
const char* name() const override { return "Linear Gradient"; }
private:
- GrLinearGradient(const CreateArgs& args)
- : INHERITED(args) {
+ GrLinearGradient(const CreateArgs& args) : INHERITED(args, args.fShader->colorsAreOpaque()) {
this->initClassID<GrLinearGradient>();
}
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 887410aa96..4eb3e6d93a 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -256,8 +256,7 @@ public:
const char* name() const override { return "Radial Gradient"; }
private:
- GrRadialGradient(const CreateArgs& args)
- : INHERITED(args) {
+ GrRadialGradient(const CreateArgs& args) : INHERITED(args, args.fShader->colorsAreOpaque()) {
this->initClassID<GrRadialGradient>();
}
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 64778c3a54..7e93a21de4 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -138,8 +138,7 @@ public:
const char* name() const override { return "Sweep Gradient"; }
private:
- GrSweepGradient(const CreateArgs& args)
- : INHERITED(args) {
+ GrSweepGradient(const CreateArgs& args) : INHERITED(args, args.fShader->colorsAreOpaque()) {
this->initClassID<GrSweepGradient>();
}
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
index 5f26dcdb13..75b1cf7090 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -92,7 +92,7 @@ private:
}
Edge2PtConicalEffect(const CreateArgs& args)
- : INHERITED(args) {
+ : INHERITED(args, false /* opaque: draws transparent black outside of the cone. */) {
const SkTwoPointConicalGradient& shader =
*static_cast<const SkTwoPointConicalGradient*>(args.fShader);
fCenterX1 = shader.getCenterX1();
@@ -398,10 +398,15 @@ private:
this->fIsFlipped == s.fIsFlipped);
}
+ static bool IsFlipped(const CreateArgs& args) {
+ // eww.
+ return static_cast<const SkTwoPointConicalGradient*>(args.fShader)->isFlippedGrad();
+ }
+
FocalOutside2PtConicalEffect(const CreateArgs& args, SkScalar focalX)
- : INHERITED(args)
- , fFocalX(focalX)
- , fIsFlipped(static_cast<const SkTwoPointConicalGradient*>(args.fShader)->isFlippedGrad()) {
+ : INHERITED(args, false /* opaque: draws transparent black outside of the cone. */)
+ , fFocalX(focalX)
+ , fIsFlipped(IsFlipped(args)) {
this->initClassID<FocalOutside2PtConicalEffect>();
}
@@ -413,7 +418,7 @@ private:
typedef GrGradientEffect INHERITED;
};
-class FocalOutside2PtConicalEffect::GLSLFocalOutside2PtConicalProcessor
+class FocalOutside2PtConicalEffect::GLSLFocalOutside2PtConicalProcessor
: public GrGradientEffect::GLSLProcessor {
public:
GLSLFocalOutside2PtConicalProcessor(const GrProcessor&);
@@ -606,7 +611,7 @@ private:
}
FocalInside2PtConicalEffect(const CreateArgs& args, SkScalar focalX)
- : INHERITED(args), fFocalX(focalX) {
+ : INHERITED(args, args.fShader->colorsAreOpaque()), fFocalX(focalX) {
this->initClassID<FocalInside2PtConicalEffect>();
}
@@ -847,7 +852,7 @@ private:
}
CircleInside2PtConicalEffect(const CreateArgs& args, const CircleConicalInfo& info)
- : INHERITED(args), fInfo(info) {
+ : INHERITED(args, args.fShader->colorsAreOpaque()), fInfo(info) {
this->initClassID<CircleInside2PtConicalEffect>();
}
@@ -1064,7 +1069,8 @@ private:
}
CircleOutside2PtConicalEffect(const CreateArgs& args, const CircleConicalInfo& info)
- : INHERITED(args), fInfo(info) {
+ : INHERITED(args, false /* opaque: draws transparent black outside of the cone. */)
+ , fInfo(info) {
this->initClassID<CircleOutside2PtConicalEffect>();
const SkTwoPointConicalGradient& shader =
*static_cast<const SkTwoPointConicalGradient*>(args.fShader);
diff --git a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
index d92a7b548c..e7d8d31302 100755
--- a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
+++ b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
@@ -140,9 +140,7 @@ void SkAmbientShadowMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
//
class ShadowEdgeFP : public GrFragmentProcessor {
public:
- ShadowEdgeFP() {
- this->initClassID<ShadowEdgeFP>();
- }
+ ShadowEdgeFP() : INHERITED(kNone_OptimizationFlags) { this->initClassID<ShadowEdgeFP>(); }
class GLSLShadowEdgeFP : public GrGLSLFragmentProcessor {
public:
@@ -179,6 +177,8 @@ private:
}
bool onIsEqual(const GrFragmentProcessor& proc) const override { return true; }
+
+ typedef GrFragmentProcessor INHERITED;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 0ad144a3be..f294ac646d 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -58,7 +58,7 @@ GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
fCoordTransforms.push_back(transform);
- fUsesLocalCoords = true;
+ fFlags |= kUsesLocalCoords_Flag;
SkDEBUGCODE(transform->setInProcessor();)
}
@@ -66,10 +66,10 @@ int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child
this->combineRequiredFeatures(*child);
if (child->usesLocalCoords()) {
- fUsesLocalCoords = true;
+ fFlags |= kUsesLocalCoords_Flag;
}
if (child->usesDistanceVectorField()) {
- fUsesDistanceVectorField = true;
+ fFlags |= kUsesDistanceVectorField_Flag;
}
int index = fChildProcessors.count();
@@ -111,12 +111,13 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProc
class PremulInputFragmentProcessor : public GrFragmentProcessor {
public:
- PremulInputFragmentProcessor() {
+ PremulInputFragmentProcessor()
+ : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
+ kConstantOutputForConstantInput_OptimizationFlag) {
this->initClassID<PremulInputFragmentProcessor>();
}
const char* name() const override { return "PremultiplyInput"; }
-
private:
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
class GLFP : public GrGLSLFragmentProcessor {
@@ -139,6 +140,11 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProc
void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
inout->premulFourChannelColor();
}
+ GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
+ return input.premul();
+ }
+
+ typedef GrFragmentProcessor INHERITED;
};
if (!fp) {
return nullptr;
@@ -152,7 +158,8 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputUnpremulColor(
class PremulFragmentProcessor : public GrFragmentProcessor {
public:
- PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
+ PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor)
+ : INHERITED(OptFlags(processor.get())) {
this->initClassID<PremulFragmentProcessor>();
this->registerChildProcessor(processor);
}
@@ -178,6 +185,16 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputUnpremulColor(
bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
+ static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
+ OptimizationFlags flags = kNone_OptimizationFlags;
+ if (inner->preservesOpaqueInput()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+ if (inner->hasConstantOutputForConstantInput()) {
+ flags |= kConstantOutputForConstantInput_OptimizationFlag;
+ }
+ return flags;
+ }
void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
// TODO: Add a helper to GrInvariantOutput that handles multiplying by color with flags?
if (!(inout->validFlags() & kA_GrColorComponentFlag)) {
@@ -210,6 +227,16 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputUnpremulColor(
}
inout->setToOther(commonFlags, color);
}
+ GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
+ GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
+ GrColor4f::OpaqueWhite());
+ return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0],
+ input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1],
+ input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2],
+ input.fRGBA[3] * childColor.fRGBA[3]);
+ }
+
+ typedef GrFragmentProcessor INHERITED;
};
if (!fp) {
return nullptr;
@@ -224,7 +251,7 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentPr
class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
public:
ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor4f color)
- : fColor(color) {
+ : INHERITED(OptFlags(child.get(), color)), fColor(color) {
this->initClassID<ReplaceInputFragmentProcessor>();
this->registerChildProcessor(std::move(child));
}
@@ -264,6 +291,18 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentPr
}
private:
+ static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) {
+ OptimizationFlags childFlags = child->optimizationFlags();
+ OptimizationFlags flags = kNone_OptimizationFlags;
+ if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
+ flags |= kConstantOutputForConstantInput_OptimizationFlag;
+ }
+ if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+ return flags;
+ }
+
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
{}
@@ -276,7 +315,13 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentPr
this->childProcessor(0).computeInvariantOutput(inout);
}
+ GrColor4f constantOutputForConstantInput(GrColor4f) const override {
+ return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
+ }
+
GrColor4f fColor;
+
+ typedef GrFragmentProcessor INHERITED;
};
GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags);
@@ -288,7 +333,8 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
int cnt) {
class SeriesFragmentProcessor : public GrFragmentProcessor {
public:
- SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt){
+ SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt)
+ : INHERITED(OptFlags(children, cnt)) {
SkASSERT(cnt > 1);
this->initClassID<SeriesFragmentProcessor>();
for (int i = 0; i < cnt; ++i) {
@@ -317,8 +363,14 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
};
return new GLFP;
}
-
private:
+ static OptimizationFlags OptFlags(sk_sp<GrFragmentProcessor>* children, int cnt) {
+ OptimizationFlags flags = kAll_OptimizationFlags;
+ for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
+ flags &= children[i]->optimizationFlags();
+ }
+ return flags;
+ }
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
@@ -328,6 +380,15 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
this->childProcessor(i).computeInvariantOutput(inout);
}
}
+ GrColor4f constantOutputForConstantInput(GrColor4f color) const override {
+ int childCnt = this->numChildProcessors();
+ for (int i = 0; i < childCnt; ++i) {
+ color = ConstantOutputForConstantInput(this->childProcessor(i), color);
+ }
+ return color;
+ }
+
+ typedef GrFragmentProcessor INHERITED;
};
if (!cnt) {
diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h
index a4e3976126..9e2aad0ccd 100644
--- a/src/gpu/SkGrPriv.h
+++ b/src/gpu/SkGrPriv.h
@@ -8,10 +8,11 @@
#ifndef SkGrPriv_DEFINED
#define SkGrPriv_DEFINED
-#include "GrTypes.h"
#include "GrBlend.h"
+#include "GrTypes.h"
#include "SkImageInfo.h"
#include "SkMatrix.h"
+#include "SkPM4f.h"
#include "SkXfermodePriv.h"
class GrCaps;
@@ -102,6 +103,21 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
//////////////////////////////////////////////////////////////////////////////
+static inline SkPM4f GrColor4fToSkPM4f(const GrColor4f& c) {
+ SkPM4f pm4f;
+ pm4f.fVec[SkPM4f::R] = c.fRGBA[0];
+ pm4f.fVec[SkPM4f::G] = c.fRGBA[1];
+ pm4f.fVec[SkPM4f::B] = c.fRGBA[2];
+ pm4f.fVec[SkPM4f::A] = c.fRGBA[3];
+ return pm4f;
+}
+
+static inline GrColor4f SkPM4fToGrColor4f(const SkPM4f& c) {
+ return GrColor4f{c.r(), c.g(), c.b(), c.a()};
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&, const GrCaps&);
bool GrPixelConfigToColorType(GrPixelConfig, SkColorType*);
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index 29e0e5dec2..67cc771c61 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -28,12 +28,11 @@ public:
kY_Direction,
};
- Gr1DKernelEffect(GrTexture* texture,
- Direction direction,
- int radius)
- : INHERITED(texture, nullptr, SkMatrix::I())
- , fDirection(direction)
- , fRadius(radius) {}
+ Gr1DKernelEffect(GrTexture* texture, Direction direction, int radius,
+ OptimizationFlags optFlags)
+ : INHERITED(texture, nullptr, SkMatrix::I(), optFlags)
+ , fDirection(direction)
+ , fRadius(radius) {}
virtual ~Gr1DKernelEffect() {}
@@ -51,7 +50,6 @@ public:
}
private:
-
Direction fDirection;
int fRadius;
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index 07d1c53011..cf3d2b5e79 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -132,21 +132,23 @@ void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman,
GrBicubicEffect::GrBicubicEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix &matrix,
+ const SkMatrix& matrix,
const SkShader::TileMode tileModes[2])
- : INHERITED(texture, std::move(colorSpaceXform), matrix,
- GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode))
- , fDomain(GrTextureDomain::IgnoredDomain()) {
+ : INHERITED(texture, std::move(colorSpaceXform), matrix,
+ GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode),
+ ModulationFlags(texture->config()))
+ , fDomain(GrTextureDomain::IgnoredDomain()) {
this->initClassID<GrBicubicEffect>();
}
GrBicubicEffect::GrBicubicEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix &matrix,
+ const SkMatrix& matrix,
const SkRect& domain)
- : INHERITED(texture, std::move(colorSpaceXform), matrix,
- GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode))
- , fDomain(texture, domain, GrTextureDomain::kClamp_Mode) {
+ : INHERITED(texture, std::move(colorSpaceXform), matrix,
+ GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode),
+ ModulationFlags(texture->config()))
+ , fDomain(texture, domain, GrTextureDomain::kClamp_Mode) {
this->initClassID<GrBicubicEffect>();
}
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 2380ad3435..74cf2ca44f 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -98,9 +98,9 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
const GrSwizzle& swizzle,
PMConversion pmConversion,
const SkMatrix& matrix)
- : INHERITED(texture, nullptr, matrix)
- , fSwizzle(swizzle)
- , fPMConversion(pmConversion) {
+ : INHERITED(texture, nullptr, matrix, ModulationFlags(texture->config()))
+ , fSwizzle(swizzle)
+ , fPMConversion(pmConversion) {
this->initClassID<GrConfigConversionEffect>();
// We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul
// conversion.
@@ -116,7 +116,7 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrContext* context,
const GrSwizzle& swizzle,
PMConversion pmConversion,
const SkMatrix& matrix)
- : INHERITED(context, proxy, nullptr, matrix)
+ : INHERITED(context, ModulationFlags(proxy->config()), proxy, nullptr, matrix)
, fSwizzle(swizzle)
, fPMConversion(pmConversion) {
this->initClassID<GrConfigConversionEffect>();
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 46180bb2f2..151365b9b0 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -52,7 +52,6 @@ public:
static void TestForPreservingPMConversions(GrContext* context,
PMConversion* PMToUPMRule,
PMConversion* UPMToPMRule);
-
private:
GrConfigConversionEffect(GrTexture*, const GrSwizzle&, PMConversion, const SkMatrix& matrix);
diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp
index e6568793df..3875ffcaa0 100644
--- a/src/gpu/effects/GrConstColorProcessor.cpp
+++ b/src/gpu/effects/GrConstColorProcessor.cpp
@@ -85,6 +85,19 @@ void GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) c
}
}
+GrColor4f GrConstColorProcessor::constantOutputForConstantInput(GrColor4f input) const {
+ switch (fMode) {
+ case kIgnore_InputMode:
+ return fColor;
+ case kModulateA_InputMode:
+ return fColor.mulByScalar(input.fRGBA[3]);
+ case kModulateRGBA_InputMode:
+ return fColor.modulate(input);
+ }
+ SkFAIL("Unexpected mode");
+ return GrColor4f::TransparentBlack();
+}
+
void GrConstColorProcessor::onGetGLSLProcessorKey(const GrShaderCaps&,
GrProcessorKeyBuilder* b) const {
b->add32(fMode);
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index 65ed87b687..4100a0fce2 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -32,7 +32,7 @@ public:
private:
AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect)
- : fRect(rect), fEdgeType(edgeType) {
+ : INHERITED(kModulatesInput_OptimizationFlag), fRect(rect), fEdgeType(edgeType) {
this->initClassID<AARectEffect>();
}
@@ -339,8 +339,7 @@ GrGLSLFragmentProcessor* GrConvexPolyEffect::onCreateGLSLInstance() const {
}
GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[])
- : fEdgeType(edgeType)
- , fEdgeCount(n) {
+ : INHERITED(kModulatesInput_OptimizationFlag), fEdgeType(edgeType), fEdgeCount(n) {
this->initClassID<GrConvexPolyEffect>();
// Factory function should have already ensured this.
SkASSERT(n <= kMaxEdges);
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index 2ba47d2e09..24e3ba6d50 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -26,9 +26,7 @@ public:
const char* name() const override { return "Dither"; }
private:
- DitherEffect() {
- this->initClassID<DitherEffect>();
- }
+ DitherEffect() : INHERITED(kNone_OptimizationFlags) { this->initClassID<DitherEffect>(); }
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index 91301ff9ac..be6d4d8302 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -150,7 +150,8 @@ GrGaussianConvolutionFragmentProcessor::GrGaussianConvolutionFragmentProcessor(G
float gaussianSigma,
bool useBounds,
float bounds[2])
- : INHERITED(texture, direction, radius), fUseBounds(useBounds) {
+ : INHERITED(texture, direction, radius, ModulationFlags(texture->config()))
+ , fUseBounds(useBounds) {
this->initClassID<GrGaussianConvolutionFragmentProcessor>();
SkASSERT(radius <= kMaxKernelRadius);
int width = this->width();
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 01fc6cec9c..9b670e120f 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -156,12 +156,14 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
const SkIPoint& kernelOffset,
GrTextureDomain::Mode tileMode,
bool convolveAlpha)
- : INHERITED(texture, nullptr, SkMatrix::I()),
- fKernelSize(kernelSize),
- fGain(SkScalarToFloat(gain)),
- fBias(SkScalarToFloat(bias) / 255.0f),
- fConvolveAlpha(convolveAlpha),
- fDomain(texture, GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) {
+ // To advertise either the modulation or opaqueness optimizations we'd have to examine the
+ // parameters.
+ : INHERITED(texture, nullptr, SkMatrix::I(), kNone_OptimizationFlags)
+ , fKernelSize(kernelSize)
+ , fGain(SkScalarToFloat(gain))
+ , fBias(SkScalarToFloat(bias) / 255.0f)
+ , fConvolveAlpha(convolveAlpha)
+ , fDomain(texture, GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) {
this->initClassID<GrMatrixConvolutionEffect>();
for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
fKernel[i] = SkScalarToFloat(kernel[i]);
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index 21a4ba00e5..3b0a8871c4 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -64,9 +64,7 @@ void CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
}
CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
- : fCenter(c)
- , fRadius(r)
- , fEdgeType(edgeType) {
+ : INHERITED(kModulatesInput_OptimizationFlag), fCenter(c), fRadius(r), fEdgeType(edgeType) {
this->initClassID<CircleEffect>();
}
@@ -230,10 +228,12 @@ void EllipseEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownSingleComponent();
}
-EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)
- : fCenter(c)
- , fRadii(SkVector::Make(rx, ry))
- , fEdgeType(edgeType) {
+EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx,
+ SkScalar ry)
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fCenter(c)
+ , fRadii(SkVector::Make(rx, ry))
+ , fEdgeType(edgeType) {
this->initClassID<EllipseEffect>();
}
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index adebc245a6..4397fcf930 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -95,9 +95,10 @@ void CircularRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) con
CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
const SkRRect& rrect)
- : fRRect(rrect)
- , fEdgeType(edgeType)
- , fCircularCornerFlags(circularCornerFlags) {
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fRRect(rrect)
+ , fEdgeType(edgeType)
+ , fCircularCornerFlags(circularCornerFlags) {
this->initClassID<CircularRRectEffect>();
}
@@ -410,8 +411,8 @@ private:
void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
- SkRRect fRRect;
- GrPrimitiveEdgeType fEdgeType;
+ SkRRect fRRect;
+ GrPrimitiveEdgeType fEdgeType;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
@@ -431,8 +432,7 @@ void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) c
}
EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
- : fRRect(rrect)
- , fEdgeType(edgeType) {
+ : INHERITED(kModulatesInput_OptimizationFlag), fRRect(rrect), fEdgeType(edgeType) {
this->initClassID<EllipticalRRectEffect>();
}
diff --git a/src/gpu/effects/GrSRGBEffect.cpp b/src/gpu/effects/GrSRGBEffect.cpp
index 67600ef320..9279586584 100644
--- a/src/gpu/effects/GrSRGBEffect.cpp
+++ b/src/gpu/effects/GrSRGBEffect.cpp
@@ -71,7 +71,9 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrSRGBEffect::GrSRGBEffect(Mode mode)
- : fMode(mode) {
+ : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
+ kConstantOutputForConstantInput_OptimizationFlag)
+ , fMode(mode) {
this->initClassID<GrSRGBEffect>();
}
@@ -84,6 +86,26 @@ void GrSRGBEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->setToUnknown();
}
+static inline float srgb_to_linear(float srgb) {
+ return (srgb <= 0.04045f) ? srgb / 12.92f : powf((srgb + 0.055f) / 1.055f, 2.4f);
+}
+static inline float linear_to_srgb(float linear) {
+ return (linear <= 0.0031308) ? linear * 12.92f : 1.055f * powf(linear, 1.f / 2.4f) - 0.055f;
+}
+
+GrColor4f GrSRGBEffect::constantOutputForConstantInput(GrColor4f input) const {
+ switch (fMode) {
+ case Mode::kLinearToSRGB:
+ return GrColor4f(linear_to_srgb(input.fRGBA[0]), linear_to_srgb(input.fRGBA[1]),
+ linear_to_srgb(input.fRGBA[2]), input.fRGBA[3]);
+ case Mode::kSRGBToLinear:
+ return GrColor4f(srgb_to_linear(input.fRGBA[0]), srgb_to_linear(input.fRGBA[1]),
+ srgb_to_linear(input.fRGBA[2]), input.fRGBA[3]);
+ }
+ SkFAIL("Unexpected mode");
+ return GrColor4f::TransparentBlack();
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSRGBEffect);
diff --git a/src/gpu/effects/GrSRGBEffect.h b/src/gpu/effects/GrSRGBEffect.h
index 2952689c4e..3d05dd646b 100644
--- a/src/gpu/effects/GrSRGBEffect.h
+++ b/src/gpu/effects/GrSRGBEffect.h
@@ -33,6 +33,7 @@ private:
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
+ GrColor4f constantOutputForConstantInput(GrColor4f input) const override;
Mode fMode;
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index bf013e9c83..c44ce44121 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -13,6 +13,29 @@
class GrInvariantOutput;
+// In a few places below we rely on braced initialization order being defined by the C++ spec (left
+// to right). We use operator-> on a sk_sp and then in a later argument std::move() the sk_sp. GCC
+// 4.9.0 and earlier has a bug where the left to right order evaluation isn't implemented correctly.
+#if defined(__GNUC__) && !defined(__clang__)
+# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+# if (GCC_VERSION > 40900)
+# define GCC_EVAL_ORDER_BUG 0
+# else
+# define GCC_EVAL_ORDER_BUG 1
+# endif
+# undef GCC_VERSION
+#else
+# define GCC_EVAL_ORDER_BUG 0
+#endif
+
+#if GCC_EVAL_ORDER_BUG
+# define PROXY_MOVE(X) (X)
+#else
+# define PROXY_MOVE(X) (std::move(X))
+#endif
+
+#undef GCC_EVAL_ORDER_BUG
+
/**
* The output color of this effect is a modulation of the input color and a sample from a texture.
* It allows explicit specification of the filtering and wrap modes (GrSamplerParams) and accepts
@@ -81,32 +104,41 @@ private:
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& matrix,
GrSamplerParams::FilterMode filterMode)
- : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode) {
+ : INHERITED(texture, std::move(colorSpaceXform), matrix, filterMode,
+ ModulationFlags(texture->config())) {
this->initClassID<GrSimpleTextureEffect>();
}
GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
- sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& matrix,
+ sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix,
GrSamplerParams::FilterMode filterMode)
- : GrSingleTextureEffect(ctx, std::move(proxy), std::move(colorSpaceXform),
- matrix, filterMode) {
+ : INHERITED{ctx,
+ ModulationFlags(proxy->config()),
+ PROXY_MOVE(proxy),
+ std::move(colorSpaceXform),
+ matrix,
+ filterMode} {
this->initClassID<GrSimpleTextureEffect>();
}
GrSimpleTextureEffect(GrTexture* texture,
- sk_sp<GrColorSpaceXform> colorSpaceXform,
+ sk_sp<GrColorSpaceXform>colorSpaceXform,
const SkMatrix& matrix,
const GrSamplerParams& params)
- : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, params) {
+ : INHERITED(texture, std::move(colorSpaceXform), matrix, params,
+ ModulationFlags(texture->config())) {
this->initClassID<GrSimpleTextureEffect>();
}
GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
- sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& matrix,
+ sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix,
const GrSamplerParams& params)
- : GrSingleTextureEffect(ctx, std::move(proxy), std::move(colorSpaceXform), matrix, params) {
+ : INHERITED{ctx,
+ ModulationFlags(proxy->config()),
+ PROXY_MOVE(proxy),
+ std::move(colorSpaceXform),
+ matrix,
+ params} {
this->initClassID<GrSimpleTextureEffect>();
}
@@ -123,4 +155,6 @@ private:
typedef GrSingleTextureEffect INHERITED;
};
+#undef PROXY_MOVE
+
#endif
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
index c493920d3d..acfc0d142d 100644
--- a/src/gpu/effects/GrSingleTextureEffect.cpp
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -12,10 +12,11 @@
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& m)
- : fCoordTransform(m, texture, GrSamplerParams::kNone_FilterMode)
- , fTextureSampler(texture)
- , fColorSpaceXform(std::move(colorSpaceXform)) {
+ const SkMatrix& m, OptimizationFlags optFlags)
+ : INHERITED(optFlags)
+ , fCoordTransform(m, texture, GrSamplerParams::kNone_FilterMode)
+ , fTextureSampler(texture)
+ , fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
this->addTextureSampler(&fTextureSampler);
}
@@ -23,56 +24,61 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& m,
- GrSamplerParams::FilterMode filterMode)
- : fCoordTransform(m, texture, filterMode)
- , fTextureSampler(texture, filterMode)
- , fColorSpaceXform(std::move(colorSpaceXform)) {
+ GrSamplerParams::FilterMode filterMode,
+ OptimizationFlags optFlags)
+ : INHERITED(optFlags)
+ , fCoordTransform(m, texture, filterMode)
+ , fTextureSampler(texture, filterMode)
+ , fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
this->addTextureSampler(&fTextureSampler);
}
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& m,
- const GrSamplerParams& params)
- : fCoordTransform(m, texture, params.filterMode())
- , fTextureSampler(texture, params)
- , fColorSpaceXform(std::move(colorSpaceXform)) {
+ const SkMatrix& m, const GrSamplerParams& params,
+ OptimizationFlags optFlags)
+ : INHERITED(optFlags)
+ , fCoordTransform(m, texture, params.filterMode())
+ , fTextureSampler(texture, params)
+ , fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
this->addTextureSampler(&fTextureSampler);
}
-GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, OptimizationFlags optFlags,
+ sk_sp<GrTextureProxy> proxy,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& m)
- : fCoordTransform(ctx, m, proxy.get(), GrSamplerParams::kNone_FilterMode)
- , fTextureSampler(ctx->textureProvider(), std::move(proxy))
- , fColorSpaceXform(std::move(colorSpaceXform)) {
+ : INHERITED(optFlags)
+ , fCoordTransform(ctx, m, proxy.get(), GrSamplerParams::kNone_FilterMode)
+ , fTextureSampler(ctx->textureProvider(), std::move(proxy))
+ , fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
this->addTextureSampler(&fTextureSampler);
}
-GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, OptimizationFlags optFlags,
+ sk_sp<GrTextureProxy> proxy,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& m,
GrSamplerParams::FilterMode filterMode)
- : fCoordTransform(ctx, m, proxy.get(), filterMode)
- , fTextureSampler(ctx->textureProvider(), std::move(proxy), filterMode)
- , fColorSpaceXform(std::move(colorSpaceXform)) {
+ : INHERITED(optFlags)
+ , fCoordTransform(ctx, m, proxy.get(), filterMode)
+ , fTextureSampler(ctx->textureProvider(), std::move(proxy), filterMode)
+ , fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
this->addTextureSampler(&fTextureSampler);
}
-GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+GrSingleTextureEffect::GrSingleTextureEffect(GrContext* ctx, OptimizationFlags optFlags,
+ sk_sp<GrTextureProxy> proxy,
sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& m,
- const GrSamplerParams& params)
- : fCoordTransform(ctx, m, proxy.get(), params.filterMode())
- , fTextureSampler(ctx->textureProvider(), std::move(proxy), params)
- , fColorSpaceXform(std::move(colorSpaceXform)) {
+ const SkMatrix& m, const GrSamplerParams& params)
+ : INHERITED(optFlags)
+ , fCoordTransform(ctx, m, proxy.get(), params.filterMode())
+ , fTextureSampler(ctx->textureProvider(), std::move(proxy), params)
+ , fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
this->addTextureSampler(&fTextureSampler);
}
-
-GrSingleTextureEffect::~GrSingleTextureEffect() {
-}
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
index 1d0f27a4ff..29105b5cda 100644
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -23,8 +23,6 @@ class GrTextureProxy;
*/
class GrSingleTextureEffect : public GrFragmentProcessor {
public:
- ~GrSingleTextureEffect() override;
-
SkString dumpInfo() const override {
SkString str;
str.appendf("Texture: %d", fTextureSampler.texture()->uniqueID().asUInt());
@@ -35,25 +33,26 @@ public:
protected:
/** unfiltered, clamp mode */
- GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&);
+ GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&,
+ OptimizationFlags optFlags);
/** clamp mode */
GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&,
- GrSamplerParams::FilterMode filterMode);
+ GrSamplerParams::FilterMode filterMode, OptimizationFlags optFlags);
GrSingleTextureEffect(GrTexture*,
sk_sp<GrColorSpaceXform>,
const SkMatrix&,
- const GrSamplerParams&);
+ const GrSamplerParams&,
+ OptimizationFlags optFlags);
/** unfiltered, clamp mode */
- GrSingleTextureEffect(GrContext*,
- sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>, const SkMatrix&);
+ GrSingleTextureEffect(GrContext*, OptimizationFlags, sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>, const SkMatrix&);
/** clamp mode */
- GrSingleTextureEffect(GrContext*,
- sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>, const SkMatrix&,
+ GrSingleTextureEffect(GrContext*, OptimizationFlags, sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>, const SkMatrix&,
GrSamplerParams::FilterMode filterMode);
- GrSingleTextureEffect(GrContext*,
- sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>, const SkMatrix&,
- const GrSamplerParams&);
+ GrSingleTextureEffect(GrContext*, OptimizationFlags, sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>, const SkMatrix&, const GrSamplerParams&);
/**
* Can be used as a helper to implement subclass onComputeInvariantOutput(). It assumes that
@@ -71,6 +70,19 @@ protected:
}
}
+ /**
+ * Can be used as a helper to implement subclass onOptimizationFlags(). It assumes that
+ * the subclass output color will be a modulation of the input color with a value read from the
+ * texture.
+ */
+ static OptimizationFlags ModulationFlags(GrPixelConfig config) {
+ if (GrPixelConfigIsOpaque(config)) {
+ return kModulatesInput_OptimizationFlag | kPreservesOpaqueInput_OptimizationFlag;
+ } else {
+ return kModulatesInput_OptimizationFlag;
+ }
+ }
+
private:
GrCoordTransform fCoordTransform;
TextureSampler fTextureSampler;
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 095f100593..7ab598fd1f 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -208,14 +208,25 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture,
}
}
+inline GrFragmentProcessor::OptimizationFlags GrTextureDomainEffect::OptFlags(
+ GrTexture* texture, GrTextureDomain::Mode mode) {
+ if (mode == GrTextureDomain::kDecal_Mode || !GrPixelConfigIsOpaque(texture->config())) {
+ return GrFragmentProcessor::kModulatesInput_OptimizationFlag;
+ } else {
+ return GrFragmentProcessor::kModulatesInput_OptimizationFlag |
+ GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag;
+ }
+}
+
GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& matrix,
const SkRect& domain,
GrTextureDomain::Mode mode,
GrSamplerParams::FilterMode filterMode)
- : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode)
- , fTextureDomain(texture, domain, mode) {
+ : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode,
+ OptFlags(texture, mode))
+ , fTextureDomain(texture, domain, mode) {
SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
filterMode == GrSamplerParams::kNone_FilterMode);
this->initClassID<GrTextureDomainEffect>();
@@ -323,7 +334,8 @@ sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(GrTe
GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
GrTexture* texture, const SkIRect& subset, const SkIPoint& deviceSpaceOffset)
- : fTextureSampler(texture, GrSamplerParams::ClampNoFilter())
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fTextureSampler(texture, GrSamplerParams::ClampNoFilter())
, fTextureDomain(texture, GrTextureDomain::MakeTexelDomain(subset),
GrTextureDomain::kDecal_Mode) {
this->addTextureSampler(&fTextureSampler);
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 66bd2201e3..6758d9045e 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -178,6 +178,8 @@ private:
GrTextureDomain::Mode,
GrSamplerParams::FilterMode);
+ static OptimizationFlags OptFlags(GrTexture* texture, GrTextureDomain::Mode mode);
+
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
index d98478747a..af32adec8b 100644
--- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
+++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
@@ -19,7 +19,7 @@ class ComposeTwoFragmentProcessor : public GrFragmentProcessor {
public:
ComposeTwoFragmentProcessor(sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> dst,
SkBlendMode mode)
- : fMode(mode) {
+ : INHERITED(OptFlags(src.get(), dst.get(), mode)), fMode(mode) {
this->initClassID<ComposeTwoFragmentProcessor>();
SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(std::move(src));
SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(std::move(dst));
@@ -35,7 +35,18 @@ public:
SkBlendMode getMode() const { return fMode; }
-protected:
+private:
+ static OptimizationFlags OptFlags(const GrFragmentProcessor* src,
+ const GrFragmentProcessor* dst, SkBlendMode mode) {
+ // We only attempt the constant output optimization.
+ // The CPU and GPU implementations differ significantly for the advanced modes.
+ if (mode <= SkBlendMode::kLastSeparableMode && src->hasConstantOutputForConstantInput() &&
+ dst->hasConstantOutputForConstantInput()) {
+ return kConstantOutputForConstantInput_OptimizationFlag;
+ }
+ return kNone_OptimizationFlags;
+ }
+
bool onIsEqual(const GrFragmentProcessor& other) const override {
const ComposeTwoFragmentProcessor& cs = other.cast<ComposeTwoFragmentProcessor>();
return fMode == cs.fMode;
@@ -45,7 +56,17 @@ protected:
inout->setToUnknown();
}
-private:
+ GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
+ float alpha = input.fRGBA[3];
+ input = input.opaque();
+ GrColor4f srcColor = ConstantOutputForConstantInput(this->childProcessor(0), input);
+ GrColor4f dstColor = ConstantOutputForConstantInput(this->childProcessor(1), input);
+ SkPM4f src = GrColor4fToSkPM4f(srcColor);
+ SkPM4f dst = GrColor4fToSkPM4f(dstColor);
+ auto proc = SkXfermode::GetProc4f(fMode);
+ return SkPM4fToGrColor4f(proc(src, dst)).mulByScalar(alpha);
+ }
+
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
SkBlendMode fMode;
@@ -145,8 +166,7 @@ public:
};
ComposeOneFragmentProcessor(sk_sp<GrFragmentProcessor> dst, SkBlendMode mode, Child child)
- : fMode(mode)
- , fChild(child) {
+ : INHERITED(OptFlags(dst.get(), mode)), fMode(mode), fChild(child) {
this->initClassID<ComposeOneFragmentProcessor>();
SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(std::move(dst));
SkASSERT(0 == dstIndex);
@@ -172,7 +192,16 @@ public:
Child child() const { return fChild; }
-protected:
+private:
+ OptimizationFlags OptFlags(const GrFragmentProcessor* child, SkBlendMode mode) {
+ // We only attempt the constant output optimization.
+ // The CPU and GPU implementations differ significantly for the advanced modes.
+ if (mode <= SkBlendMode::kLastSeparableMode && child->hasConstantOutputForConstantInput()) {
+ return kConstantOutputForConstantInput_OptimizationFlag;
+ }
+ return kNone_OptimizationFlags;
+ }
+
bool onIsEqual(const GrFragmentProcessor& that) const override {
return fMode == that.cast<ComposeOneFragmentProcessor>().fMode;
}
@@ -203,6 +232,21 @@ protected:
}
}
+ GrColor4f constantOutputForConstantInput(GrColor4f inputColor) const override {
+ GrColor4f childColor =
+ ConstantOutputForConstantInput(this->childProcessor(0), GrColor4f::OpaqueWhite());
+ SkPM4f src, dst;
+ if (kSrc_Child == fChild) {
+ src = GrColor4fToSkPM4f(childColor);
+ dst = GrColor4fToSkPM4f(inputColor);
+ } else {
+ src = GrColor4fToSkPM4f(inputColor);
+ dst = GrColor4fToSkPM4f(childColor);
+ }
+ auto proc = SkXfermode::GetProc4f(fMode);
+ return SkPM4fToGrColor4f(proc(src, dst));
+ }
+
private:
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp
index 254cdffd2b..6d917f36d5 100644
--- a/src/gpu/effects/GrYUVEffect.cpp
+++ b/src/gpu/effects/GrYUVEffect.cpp
@@ -155,19 +155,17 @@ public:
};
private:
- YUVtoRGBEffect(GrContext* ctx,
- sk_sp<GrTextureProxy> yProxy,
- sk_sp<GrTextureProxy> uProxy,
- sk_sp<GrTextureProxy> vProxy,
- const SkMatrix yuvMatrix[3], GrSamplerParams::FilterMode uvFilterMode,
- SkYUVColorSpace colorSpace, bool nv12)
- : fYTransform(ctx, yuvMatrix[0], yProxy.get(), GrSamplerParams::kNone_FilterMode)
- , fYSampler(ctx->textureProvider(), std::move(yProxy))
- , fUTransform(ctx, yuvMatrix[1], uProxy.get(), uvFilterMode)
- , fUSampler(ctx->textureProvider(), std::move(uProxy), uvFilterMode)
- , fVSampler(ctx->textureProvider(), vProxy, uvFilterMode)
- , fColorSpace(colorSpace)
- , fNV12(nv12) {
+ YUVtoRGBEffect(GrContext* ctx, sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy,
+ sk_sp<GrTextureProxy> vProxy, const SkMatrix yuvMatrix[3],
+ GrSamplerParams::FilterMode uvFilterMode, SkYUVColorSpace colorSpace, bool nv12)
+ : INHERITED(kPreservesOpaqueInput_OptimizationFlag)
+ , fYTransform(ctx, yuvMatrix[0], yProxy.get(), GrSamplerParams::kNone_FilterMode)
+ , fYSampler(ctx->textureProvider(), std::move(yProxy))
+ , fUTransform(ctx, yuvMatrix[1], uProxy.get(), uvFilterMode)
+ , fUSampler(ctx->textureProvider(), std::move(uProxy), uvFilterMode)
+ , fVSampler(ctx->textureProvider(), vProxy, uvFilterMode)
+ , fColorSpace(colorSpace)
+ , fNV12(nv12) {
this->initClassID<YUVtoRGBEffect>();
this->addCoordTransform(&fYTransform);
this->addTextureSampler(&fYSampler);
@@ -228,8 +226,10 @@ public:
RGBToYUVEffect(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace,
OutputChannels output)
- : fColorSpace(colorSpace)
- , fOutputChannels(output) {
+ // This could advertise kConstantOutputForConstantInput, but doesn't seem useful.
+ : INHERITED(kPreservesOpaqueInput_OptimizationFlag)
+ , fColorSpace(colorSpace)
+ , fOutputChannels(output) {
this->initClassID<RGBToYUVEffect>();
this->registerChildProcessor(std::move(rgbFP));
}