diff options
Diffstat (limited to 'src')
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)); } |