From 1a8ecdfb73a15de600d5779b75d7c4b61863c50b Mon Sep 17 00:00:00 2001 From: egdaniel Date: Fri, 3 Oct 2014 06:24:12 -0700 Subject: [PATCH] Add isSingleComponent bool to getConstantColorComponent Initial step to allowing effects to use/output 1 or 4 color/coverage components. This cl doesn't change any current logic and all effects still assume they are working with 4 components. BUG=skia: Committed: https://skia.googlesource.com/skia/+/3b8af078281a5a20f951b9fd84f38d92b8f6217b Review URL: https://codereview.chromium.org/608253002 --- include/gpu/GrProcessor.h | 48 ++++++++-- src/core/SkXfermode.cpp | 10 +-- src/effects/SkAlphaThresholdFilter.cpp | 14 +-- src/effects/SkArithmeticMode.cpp | 9 +- src/effects/SkBlurMaskFilter.cpp | 19 ++-- src/effects/SkColorFilters.cpp | 15 ++-- src/effects/SkColorMatrixFilter.cpp | 90 +++++++++---------- src/effects/SkDisplacementMapEffect.cpp | 10 +-- src/effects/SkLightingImageFilter.cpp | 12 +-- src/effects/SkLumaColorFilter.cpp | 14 +-- src/effects/SkMagnifierImageFilter.cpp | 9 +- src/effects/SkMorphologyImageFilter.cpp | 8 +- src/effects/SkPerlinNoiseShader.cpp | 9 +- src/effects/SkTableColorFilter.cpp | 17 ++-- src/effects/gradients/SkGradientShader.cpp | 9 +- src/effects/gradients/SkGradientShaderPriv.h | 4 +- src/gpu/GrAAConvexPathRenderer.cpp | 10 +-- src/gpu/GrAARectRenderer.cpp | 20 ++--- src/gpu/GrDrawState.cpp | 55 ++++++------ src/gpu/GrOptDrawState.cpp | 23 ++--- src/gpu/GrOvalRenderer.cpp | 30 +++---- src/gpu/GrPaint.cpp | 24 ++--- src/gpu/GrProcessor.cpp | 42 +++++++++ src/gpu/effects/GrBezierEffect.h | 30 +++---- src/gpu/effects/GrBicubicEffect.cpp | 5 +- src/gpu/effects/GrBicubicEffect.h | 3 +- src/gpu/effects/GrConfigConversionEffect.cpp | 6 +- src/gpu/effects/GrConfigConversionEffect.h | 4 +- src/gpu/effects/GrConvexPolyEffect.cpp | 27 +++--- src/gpu/effects/GrConvexPolyEffect.h | 4 +- src/gpu/effects/GrConvolutionEffect.h | 13 +-- .../effects/GrCustomCoordsTextureEffect.cpp | 11 ++- src/gpu/effects/GrCustomCoordsTextureEffect.h | 4 +- src/gpu/effects/GrDashingEffect.cpp | 18 ++-- .../effects/GrDistanceFieldTextureEffect.cpp | 24 ++--- .../effects/GrDistanceFieldTextureEffect.h | 7 +- src/gpu/effects/GrDitherEffect.cpp | 9 +- src/gpu/effects/GrMatrixConvolutionEffect.h | 12 +-- src/gpu/effects/GrOvalEffect.cpp | 18 ++-- src/gpu/effects/GrRRectEffect.cpp | 18 ++-- src/gpu/effects/GrSimpleTextureEffect.cpp | 5 +- src/gpu/effects/GrSimpleTextureEffect.h | 4 +- src/gpu/effects/GrSingleTextureEffect.h | 11 ++- src/gpu/effects/GrTextureDomain.cpp | 7 +- src/gpu/effects/GrTextureDomain.h | 3 +- src/gpu/effects/GrYUVtoRGBEffect.cpp | 14 +-- tests/GpuColorFilterTest.cpp | 14 +-- 47 files changed, 440 insertions(+), 332 deletions(-) diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h index 7053872bbe..2dbead1c22 100644 --- a/include/gpu/GrProcessor.h +++ b/include/gpu/GrProcessor.h @@ -37,14 +37,48 @@ public: virtual ~GrProcessor(); + struct InvariantOutput{ + GrColor fColor; + uint32_t fValidFlags; + bool fIsSingleComponent; + + bool isOpaque() const { + return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor)); + } + + bool isSolidWhite() const { + return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor); + } + + /** + * If isSingleComponent is true, then the flag values for r, g, b, and a must all be the + * same. If the flags are all set then all color components must be equal. + */ + SkDEBUGCODE(void validate() const;) + + private: + SkDEBUGCODE(bool colorComponentsAllEqual() const;) + + /** + * If alpha is valid, check that any valid R,G,B values are <= A + */ + SkDEBUGCODE(bool validPreMulColor() const;) + }; + /** - * This function is used to perform optimizations. When called the color and validFlags params + * This function is used to perform optimizations. When called the invarientOuput param * indicate whether the input components to this effect in the FS will have known values. - * validFlags is a bitfield of GrColorComponentFlags. The function updates both params to - * indicate known values of its output. A component of the color param only has meaning if the - * corresponding bit in validFlags is set. + * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent + * member indicates whether the input will be 1 or 4 bytes. The function updates the members of + * inout to indicate known values of its output. A component of the color member only has + * meaning if the corresponding bit in validFlags is set. */ - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const = 0; + void computeInvariantOutput(InvariantOutput* inout) const { + this->onComputeInvariantOutput(inout); +#ifdef SK_DEBUG + inout->validate(); +#endif + } /** This object, besides creating back-end-specific helper objects, is used for run-time-type- identification. The factory should be an instance of templated class, @@ -158,6 +192,10 @@ private: getFactory()).*/ virtual bool onIsEqual(const GrProcessor& other) const = 0; + /** + * Subclass implements this to support getConstantColorComponents(...). + */ + virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0; friend class GrGeometryProcessor; // to set fRequiresVertexShader and build fVertexAttribTypes. SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 8a3218fcbd..1d151e4dba 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -799,11 +799,6 @@ public: } } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE { return GrTBackendFragmentProcessorFactory::getInstance(); } @@ -1216,6 +1211,11 @@ private: return fMode == s.fMode && fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture(); } + + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } SkXfermode::Mode fMode; GrCoordTransform fBackgroundTransform; diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp index 09cc61851c..462cfec55e 100644 --- a/src/effects/SkAlphaThresholdFilter.cpp +++ b/src/effects/SkAlphaThresholdFilter.cpp @@ -76,8 +76,6 @@ public: static const char* Name() { return "Alpha Threshold"; } virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - float innerThreshold() const { return fInnerThreshold; } float outerThreshold() const { return fOuterThreshold; } @@ -104,6 +102,8 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; float fInnerThreshold; @@ -228,13 +228,13 @@ bool AlphaThresholdEffect::onIsEqual(const GrProcessor& sBase) const { this->fOuterThreshold == s.fOuterThreshold); } -void AlphaThresholdEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && - GrPixelConfigIsOpaque(this->texture(0)->config())) { - *validFlags = kA_GrColorComponentFlag; +void AlphaThresholdEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { + inout->fValidFlags = kA_GrColorComponentFlag; } else { - *validFlags = 0; + inout->fValidFlags = 0; } + inout->fIsSingleComponent = false; } #endif diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp index 85af19cf55..b62b33db9a 100644 --- a/src/effects/SkArithmeticMode.cpp +++ b/src/effects/SkArithmeticMode.cpp @@ -289,8 +289,6 @@ public: static const char* Name() { return "Arithmetic"; } GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture(); } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - float k1() const { return fK1; } float k2() const { return fK2; } float k3() const { return fK3; } @@ -300,6 +298,8 @@ public: private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrArithmeticEffect(float k1, float k2, float k3, float k4, bool enforcePMColor, GrTexture* background); float fK1, fK2, fK3, fK4; @@ -344,9 +344,10 @@ const GrBackendFragmentProcessorFactory& GrArithmeticEffect::getFactory() const return GrTBackendFragmentProcessorFactory::getInstance(); } -void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { +void GrArithmeticEffect::onComputeInvariantOutput(InvariantOutput* inout) const { // TODO: optimize this - *validFlags = 0; + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index 123b9d28e5..251398ca5b 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -563,8 +563,6 @@ public: typedef GrGLRectBlurEffect GLProcessor; virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - /** * Create a simple filter effect with custom bicubic coefficients. */ @@ -594,6 +592,8 @@ private: GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile); virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + static bool CreateBlurProfileTexture(GrContext *context, float sigma, GrTexture **blurProfileTexture); @@ -765,9 +765,9 @@ bool GrRectBlurEffect::onIsEqual(const GrProcessor& sBase) const { return this->getSigma() == s.getSigma() && this->getRect() == s.getRect(); } -void GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; - return; +void GrRectBlurEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect); @@ -837,8 +837,6 @@ public: typedef GrGLRRectBlurEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -846,6 +844,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + SkRRect fRRect; float fSigma; GrTextureAccess fNinePatchAccess; @@ -929,8 +929,9 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma, return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture)); } -void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void GrRRectBlurEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& GrRRectBlurEffect::getFactory() const { diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp index bd0d2aa6c8..ba62817f56 100644 --- a/src/effects/SkColorFilters.cpp +++ b/src/effects/SkColorFilters.cpp @@ -195,8 +195,6 @@ public: return SkNEW_ARGS(ModeColorFilterEffect, (c, mode)); } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - bool willUseFilterColor() const { SkXfermode::Coeff dstCoeff; SkXfermode::Coeff srcCoeff; @@ -293,6 +291,8 @@ private: return fMode == s.fMode && fColor == s.fColor; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + SkXfermode::Mode fMode; GrColor fColor; @@ -382,18 +382,19 @@ private: } -void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { +void ModeColorFilterEffect::onComputeInvariantOutput(InvariantOutput* inout) const { float inputColor[4]; - GrColorToRGBAFloat(*color, inputColor); + GrColorToRGBAFloat(inout->fColor, inputColor); float filterColor[4]; GrColorToRGBAFloat(fColor, filterColor); MaskedColorExpr result = color_filter_expression(fMode, MaskedColorExpr(filterColor, kRGBA_GrColorComponentFlags), - MaskedColorExpr(inputColor, *validFlags)); + MaskedColorExpr(inputColor, inout->fValidFlags)); - *color = result.getColor(); - *validFlags = result.getValidComponents(); + inout->fColor = result.getColor(); + inout->fValidFlags = result.getValidComponents(); + inout->fIsSingleComponent = false; } GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ModeColorFilterEffect); diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp index 5ac455253e..8549fd72e1 100644 --- a/src/effects/SkColorMatrixFilter.cpp +++ b/src/effects/SkColorMatrixFilter.cpp @@ -349,51 +349,6 @@ public: return GrTBackendFragmentProcessorFactory::getInstance(); } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - // We only bother to check whether the alpha channel will be constant. If SkColorMatrix had - // type flags it might be worth checking the other components. - - // The matrix is defined such the 4th row determines the output alpha. The first four - // columns of that row multiply the input r, g, b, and a, respectively, and the last column - // is the "translation". - static const uint32_t kRGBAFlags[] = { - kR_GrColorComponentFlag, - kG_GrColorComponentFlag, - kB_GrColorComponentFlag, - kA_GrColorComponentFlag - }; - static const int kShifts[] = { - GrColor_SHIFT_R, GrColor_SHIFT_G, GrColor_SHIFT_B, GrColor_SHIFT_A, - }; - enum { - kAlphaRowStartIdx = 15, - kAlphaRowTranslateIdx = 19, - }; - - SkScalar outputA = 0; - for (int i = 0; i < 4; ++i) { - // If any relevant component of the color to be passed through the matrix is non-const - // then we can't know the final result. - if (0 != fMatrix.fMat[kAlphaRowStartIdx + i]) { - if (!(*validFlags & kRGBAFlags[i])) { - *validFlags = 0; - return; - } else { - uint32_t component = (*color >> kShifts[i]) & 0xFF; - outputA += fMatrix.fMat[kAlphaRowStartIdx + i] * component; - } - } - } - outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; - *validFlags = kA_GrColorComponentFlag; - // We pin the color to [0,1]. This would happen to the *final* color output from the frag - // shader but currently the effect does not pin its own output. So in the case of over/ - // underflow this may deviate from the actual result. Maybe the effect should pin its - // result if the matrix could over/underflow for any component? - *color = static_cast(SkScalarPin(outputA, 0, 255)) << GrColor_SHIFT_A; - } - GR_DECLARE_FRAGMENT_PROCESSOR_TEST; class GLProcessor : public GrGLFragmentProcessor { @@ -471,6 +426,51 @@ private: return cme.fMatrix == fMatrix; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + // We only bother to check whether the alpha channel will be constant. If SkColorMatrix had + // type flags it might be worth checking the other components. + + // The matrix is defined such the 4th row determines the output alpha. The first four + // columns of that row multiply the input r, g, b, and a, respectively, and the last column + // is the "translation". + static const uint32_t kRGBAFlags[] = { + kR_GrColorComponentFlag, + kG_GrColorComponentFlag, + kB_GrColorComponentFlag, + kA_GrColorComponentFlag + }; + static const int kShifts[] = { + GrColor_SHIFT_R, GrColor_SHIFT_G, GrColor_SHIFT_B, GrColor_SHIFT_A, + }; + enum { + kAlphaRowStartIdx = 15, + kAlphaRowTranslateIdx = 19, + }; + + SkScalar outputA = 0; + for (int i = 0; i < 4; ++i) { + // If any relevant component of the color to be passed through the matrix is non-const + // then we can't know the final result. + if (0 != fMatrix.fMat[kAlphaRowStartIdx + i]) { + if (!(inout->fValidFlags & kRGBAFlags[i])) { + inout->fValidFlags = 0; + return; + } else { + uint32_t component = (inout->fColor >> kShifts[i]) & 0xFF; + outputA += fMatrix.fMat[kAlphaRowStartIdx + i] * component; + } + } + } + outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; + inout->fValidFlags = kA_GrColorComponentFlag; + // We pin the color to [0,1]. This would happen to the *final* color output from the frag + // shader but currently the effect does not pin its own output. So in the case of over/ + // underflow this may deviate from the actual result. Maybe the effect should pin its + // result if the matrix could over/underflow for any component? + inout->fColor = static_cast(SkScalarPin(outputA, 0, 255)) << GrColor_SHIFT_A; + inout->fIsSingleComponent = false; + } + SkColorMatrix fMatrix; typedef GrFragmentProcessor INHERITED; diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 474d9a7dc8..ace9e02866 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -351,11 +351,11 @@ public: typedef GrGLDisplacementMapEffect GLProcessor; static const char* Name() { return "DisplacementMap"; } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, const SkVector& scale, @@ -491,14 +491,14 @@ const GrBackendFragmentProcessorFactory& GrDisplacementMapEffect::getFactory() c return GrTBackendFragmentProcessorFactory::getInstance(); } -void GrDisplacementMapEffect::getConstantColorComponents(GrColor*, - uint32_t* validFlags) const { +void GrDisplacementMapEffect::onComputeInvariantOutput(InvariantOutput* inout) const { // Any displacement offset bringing a pixel out of bounds will output a color of (0,0,0,0), // so the only way we'd get a constant alpha is if the input color image has a constant alpha // and no displacement offset push any texture coordinates out of bounds OR if the constant // alpha is 0. Since this isn't trivial to compute at this point, let's assume the output is // not of constant color when a displacement effect is applied. - *validFlags = 0; + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index f766562128..ce787c6ab8 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -350,15 +350,15 @@ public: SkScalar surfaceScale() const { return fSurfaceScale; } const SkMatrix& filterMatrix() const { return fFilterMatrix; } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - // lighting shaders are complicated. We just throw up our hands. - *validFlags = 0; - } - protected: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + // lighting shaders are complicated. We just throw up our hands. + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + private: typedef GrSingleTextureEffect INHERITED; const SkLight* fLight; diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp index ee2bfa654c..616bcde891 100644 --- a/src/effects/SkLumaColorFilter.cpp +++ b/src/effects/SkLumaColorFilter.cpp @@ -73,13 +73,6 @@ public: return GrTBackendFragmentProcessorFactory::getInstance(); } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - // The output is always black. - *color = GrColorPackRGBA(0, 0, 0, GrColorUnpackA(*color)); - *validFlags = kRGB_GrColorComponentFlags; - } - class GLProcessor : public GrGLFragmentProcessor { public: GLProcessor(const GrBackendProcessorFactory& factory, @@ -119,6 +112,13 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; } + + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + // The output is always black. + inout->fColor = GrColorPackRGBA(0, 0, 0, GrColorUnpackA(inout->fColor)); + inout->fValidFlags = kRGB_GrColorComponentFlags; + inout->fIsSingleComponent = false; + } }; GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const { diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index 9d7b918365..d6a8e783b9 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -47,8 +47,6 @@ public: static const char* Name() { return "Magnifier"; } virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - float x_offset() const { return fXOffset; } float y_offset() const { return fYOffset; } float x_inv_zoom() const { return fXInvZoom; } @@ -76,6 +74,8 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; float fXOffset; @@ -227,8 +227,9 @@ bool GrMagnifierEffect::onIsEqual(const GrProcessor& sBase) const { this->fYInvInset == s.fYInvInset); } -void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - this->updateConstantColorComponentsForModulation(color, validFlags); +void GrMagnifierEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + this->updateInvariantOutputForModulation(inout); + inout->fIsSingleComponent = false; } #endif diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 397e43193e..4c7f62482c 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -309,7 +309,6 @@ public: typedef GrGLMorphologyEffect GLProcessor; virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; protected: @@ -318,6 +317,8 @@ protected: private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); GR_DECLARE_FRAGMENT_PROCESSOR_TEST; @@ -455,10 +456,11 @@ bool GrMorphologyEffect::onIsEqual(const GrProcessor& sBase) const { this->type() == s.type()); } -void GrMorphologyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { +void GrMorphologyEffect::onComputeInvariantOutput(InvariantOutput* inout) const { // This is valid because the color components of the result of the kernel all come // exactly from existing values in the source texture. - this->updateConstantColorComponentsForModulation(color, validFlags); + this->updateInvariantOutputForModulation(inout); + inout->fIsSingleComponent = false; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp index 88e6caddb9..43197dedf2 100644 --- a/src/effects/SkPerlinNoiseShader.cpp +++ b/src/effects/SkPerlinNoiseShader.cpp @@ -586,6 +586,11 @@ private: fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit; } + void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; // This is noise. Nothing is constant. + inout->fIsSingleComponent = false; + } + GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, int numOctaves, bool stitchTiles, SkPerlinNoiseShader::PaintingData* paintingData, @@ -616,10 +621,6 @@ private: GrTextureAccess fNoiseAccess; SkPerlinNoiseShader::PaintingData *fPaintingData; - void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; // This is noise. Nothing is constant. - } - private: typedef GrFragmentProcessor INHERITED; }; diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 4853f73e5c..f6726ca078 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -294,20 +294,20 @@ public: static const char* Name() { return "ColorTable"; } virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - typedef GLColorTableEffect GLProcessor; private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + explicit ColorTableEffect(GrTexture* texture, unsigned flags); GR_DECLARE_FRAGMENT_PROCESSOR_TEST; GrTextureAccess fTextureAccess; unsigned fFlags; // currently not used in shader code, just to assist - // getConstantColorComponents(). + // onComputeInvariantOutput(). typedef GrFragmentProcessor INHERITED; }; @@ -401,21 +401,22 @@ bool ColorTableEffect::onIsEqual(const GrProcessor& sBase) const { return this->texture(0) == sBase.texture(0); } -void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { +void ColorTableEffect::onComputeInvariantOutput(InvariantOutput* inout) const { // If we kept the table in the effect then we could actually run known inputs through the // table. if (fFlags & SkTable_ColorFilter::kR_Flag) { - *validFlags &= ~kR_GrColorComponentFlag; + inout->fValidFlags &= ~kR_GrColorComponentFlag; } if (fFlags & SkTable_ColorFilter::kG_Flag) { - *validFlags &= ~kG_GrColorComponentFlag; + inout->fValidFlags &= ~kG_GrColorComponentFlag; } if (fFlags & SkTable_ColorFilter::kB_Flag) { - *validFlags &= ~kB_GrColorComponentFlag; + inout->fValidFlags &= ~kB_GrColorComponentFlag; } if (fFlags & SkTable_ColorFilter::kA_Flag) { - *validFlags &= ~kA_GrColorComponentFlag; + inout->fValidFlags &= ~kA_GrColorComponentFlag; } + inout->fIsSingleComponent = false; } diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index d25873b438..89b323a701 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -1217,12 +1217,13 @@ bool GrGradientEffect::onIsEqual(const GrProcessor& processor) const { return false; } -void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) { - *validFlags = kA_GrColorComponentFlag; +void GrGradientEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + if (fIsOpaque && inout->isOpaque()) { + inout->fValidFlags = kA_GrColorComponentFlag; } else { - *validFlags = 0; + inout->fValidFlags = 0; } + inout->fIsSingleComponent = false; } int GrGradientEffect::RandomGradientParams(SkRandom* random, diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index b81b5626ba..33d8adde05 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -342,8 +342,6 @@ public: bool useAtlas() const { return SkToBool(-1 != fRow); } SkScalar getYCoord() const { return fYCoord; }; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; } enum PremulType { @@ -376,6 +374,8 @@ protected: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + const GrCoordTransform& getCoordTransform() const { return fCoordTransform; } private: diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index dc74459e3e..1aa90c3f2b 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -517,11 +517,6 @@ public: static const char* Name() { return "QuadEdge"; } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - const GrShaderVar& inQuadEdge() const { return fInQuadEdge; } virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { @@ -593,6 +588,11 @@ private: return true; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + const GrShaderVar& fInQuadEdge; GR_DECLARE_GEOMETRY_PROCESSOR_TEST; diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 572098249e..0b895d1d33 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -30,11 +30,6 @@ public: static const char* Name() { return "AlignedRectEdge"; } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - const GrShaderVar& inRect() const { return fInRect; } virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { @@ -112,6 +107,11 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + GR_DECLARE_GEOMETRY_PROCESSOR_TEST; typedef GrGeometryProcessor INHERITED; @@ -155,11 +155,6 @@ public: static const char* Name() { return "RectEdge"; } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - const GrShaderVar& inRectEdge() const { return fInRectEdge; } const GrShaderVar& inWidthHeight() const { return fInWidthHeight; } @@ -257,6 +252,11 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + const GrShaderVar& fInRectEdge; const GrShaderVar& fInWidthHeight; diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 872d20a1ab..b4cf9c8b41 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -421,26 +421,26 @@ bool GrDrawState::hasSolidCoverage() const { return true; } - GrColor coverage; - uint32_t validComponentFlags; + GrProcessor::InvariantOutput inout; + inout.fIsSingleComponent = false; // Initialize to an unknown starting coverage if per-vertex coverage is specified. if (this->hasCoverageVertexAttribute()) { - validComponentFlags = 0; + inout.fValidFlags = 0; } else { - coverage = fCoverage; - validComponentFlags = kRGBA_GrColorComponentFlags; + inout.fColor = fCoverage; + inout.fValidFlags = kRGBA_GrColorComponentFlags; } // Run through the coverage stages and see if the coverage will be all ones at the end. if (this->hasGeometryProcessor()) { const GrGeometryProcessor* gp = fGeometryProcessor->getGeometryProcessor(); - gp->getConstantColorComponents(&coverage, &validComponentFlags); + gp->computeInvariantOutput(&inout); } for (int s = 0; s < this->numCoverageStages(); ++s) { const GrProcessor* processor = this->getCoverageStage(s).getProcessor(); - processor->getConstantColorComponents(&coverage, &validComponentFlags); + processor->computeInvariantOutput(&inout); } - return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage); + return inout.isSolidWhite(); } ////////////////////////////////////////////////////////////////////////////// @@ -755,55 +755,54 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, bool GrDrawState::srcAlphaWillBeOne() const { - uint32_t validComponentFlags; - GrColor color; + GrProcessor::InvariantOutput inoutColor; + inoutColor.fIsSingleComponent = false; // Check if per-vertex or constant color may have partial alpha if (this->hasColorVertexAttribute()) { if (fHints & kVertexColorsAreOpaque_Hint) { - validComponentFlags = kA_GrColorComponentFlag; - color = 0xFF << GrColor_SHIFT_A; + inoutColor.fValidFlags = kA_GrColorComponentFlag; + inoutColor.fColor = 0xFF << GrColor_SHIFT_A; } else { - validComponentFlags = 0; - color = 0; // not strictly necessary but we get false alarms from tools about uninit. + inoutColor.fValidFlags = 0; + // not strictly necessary but we get false alarms from tools about uninit. + inoutColor.fColor = 0; } } else { - validComponentFlags = kRGBA_GrColorComponentFlags; - color = this->getColor(); + inoutColor.fValidFlags = kRGBA_GrColorComponentFlags; + inoutColor.fColor = this->getColor(); } // Run through the color stages for (int s = 0; s < this->numColorStages(); ++s) { const GrProcessor* processor = this->getColorStage(s).getProcessor(); - processor->getConstantColorComponents(&color, &validComponentFlags); + processor->computeInvariantOutput(&inoutColor); } // Check whether coverage is treated as color. If so we run through the coverage computation. if (this->isCoverageDrawing()) { // The shader generated for coverage drawing runs the full coverage computation and then // makes the shader output be the multiplication of color and coverage. We mirror that here. - GrColor coverage; - uint32_t coverageComponentFlags; + GrProcessor::InvariantOutput inoutCoverage; + inoutCoverage.fIsSingleComponent = false; if (this->hasCoverageVertexAttribute()) { - coverageComponentFlags = 0; - coverage = 0; // suppresses any warnings. + inoutCoverage.fValidFlags = 0; + inoutCoverage.fColor = 0; // suppresses any warnings. } else { - coverageComponentFlags = kRGBA_GrColorComponentFlags; - coverage = this->getCoverageColor(); + inoutCoverage.fValidFlags = kRGBA_GrColorComponentFlags; + inoutCoverage.fColor = this->getCoverageColor(); } // Run through the coverage stages for (int s = 0; s < this->numCoverageStages(); ++s) { const GrProcessor* processor = this->getCoverageStage(s).getProcessor(); - processor->getConstantColorComponents(&coverage, &coverageComponentFlags); + processor->computeInvariantOutput(&inoutCoverage); } // Since the shader will multiply coverage and color, the only way the final A==1 is if // coverage and color both have A==1. - return (kA_GrColorComponentFlag & validComponentFlags & coverageComponentFlags) && - 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage); - + return (inoutColor.isOpaque() && inoutCoverage.isOpaque()); } - return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color); + return inoutColor.isOpaque(); } diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp index 98a5689d53..6a79203d1a 100644 --- a/src/gpu/GrOptDrawState.cpp +++ b/src/gpu/GrOptDrawState.cpp @@ -170,18 +170,19 @@ void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) { int firstColorStage = 0; // Set up color and flags for ConstantColorComponent checks - GrColor color; - uint32_t validComponentFlags; + GrProcessor::InvariantOutput inout; + inout.fIsSingleComponent = false; if (!this->hasColorVertexAttribute()) { - color = ds.getColor(); - validComponentFlags = kRGBA_GrColorComponentFlags; + inout.fColor = ds.getColor(); + inout.fValidFlags = kRGBA_GrColorComponentFlags; } else { if (ds.vertexColorsAreOpaque()) { - color = 0xFF << GrColor_SHIFT_A; - validComponentFlags = kA_GrColorComponentFlag; + inout.fColor = 0xFF << GrColor_SHIFT_A; + inout.fValidFlags = kA_GrColorComponentFlag; } else { - validComponentFlags = 0; - color = 0; // not strictly necessary but we get false alarms from tools about uninit. + inout.fValidFlags = 0; + // not strictly necessary but we get false alarms from tools about uninit. + inout.fColor = 0; } } @@ -191,10 +192,10 @@ void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) { firstColorStage = i; fInputColorIsUsed = false; } - fp->getConstantColorComponents(&color, &validComponentFlags); - if (kRGBA_GrColorComponentFlags == validComponentFlags) { + fp->computeInvariantOutput(&inout); + if (kRGBA_GrColorComponentFlags == inout.fValidFlags) { firstColorStage = i + 1; - fColor = color; + fColor = inout.fColor; fInputColorIsUsed = true; this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding); } diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 4ae0ebc7ef..7a84f80805 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -75,11 +75,6 @@ public: } } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - const GrShaderVar& inCircleEdge() const { return fInCircleEdge; } virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { @@ -150,6 +145,11 @@ private: return cee.fStroke == fStroke; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + const GrShaderVar& fInCircleEdge; bool fStroke; @@ -192,11 +192,6 @@ public: } } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { return GrTBackendGeometryProcessorFactory::getInstance(); } @@ -291,6 +286,11 @@ private: return eee.fStroke == fStroke; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + const GrShaderVar& fInEllipseOffset; const GrShaderVar& fInEllipseRadii; bool fStroke; @@ -341,11 +341,6 @@ public: } } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { return GrTBackendGeometryProcessorFactory::getInstance(); } @@ -460,6 +455,11 @@ private: return eee.fMode == fMode; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + const GrShaderVar& fInEllipseOffsets0; const GrShaderVar& fInEllipseOffsets1; Mode fMode; diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp index 84fdf420e2..ffde5f99e4 100644 --- a/src/gpu/GrPaint.cpp +++ b/src/gpu/GrPaint.cpp @@ -52,28 +52,32 @@ bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor, // TODO: Share this implementation with GrDrawState - GrColor coverage = GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage); - uint32_t coverageComps = kRGBA_GrColorComponentFlags; + GrProcessor::InvariantOutput inout; + inout.fColor = GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage); + inout.fValidFlags = kRGBA_GrColorComponentFlags; + inout.fIsSingleComponent = false; int count = fCoverageStages.count(); for (int i = 0; i < count; ++i) { - fCoverageStages[i].getProcessor()->getConstantColorComponents(&coverage, &coverageComps); + fCoverageStages[i].getProcessor()->computeInvariantOutput(&inout); } - if (kRGBA_GrColorComponentFlags != coverageComps || 0xffffffff != coverage) { + if (!inout.isSolidWhite()) { return false; } - GrColor color = fColor; - uint32_t colorComps = kRGBA_GrColorComponentFlags; + inout.fColor = fColor; + inout.fValidFlags = kRGBA_GrColorComponentFlags; + inout.fIsSingleComponent = false; count = fColorStages.count(); for (int i = 0; i < count; ++i) { - fColorStages[i].getProcessor()->getConstantColorComponents(&color, &colorComps); + fColorStages[i].getProcessor()->computeInvariantOutput(&inout); } SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents)); GrBlendCoeff srcCoeff = fSrcBlendCoeff; GrBlendCoeff dstCoeff = fDstBlendCoeff; - GrSimplifyBlend(&srcCoeff, &dstCoeff, color, colorComps, 0, 0, 0); + GrSimplifyBlend(&srcCoeff, &dstCoeff, inout.fColor, inout.fValidFlags, + 0, 0, 0); bool opaque = kZero_GrBlendCoeff == dstCoeff && !GrBlendCoeffRefsDst(srcCoeff); if (solidColor) { @@ -85,8 +89,8 @@ bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor, break; case kOne_GrBlendCoeff: - *solidColor = color; - *solidColorKnownComponents = colorComps; + *solidColor = inout.fColor; + *solidColorKnownComponents = inout.fValidFlags; break; // The src coeff should never refer to the src and if it refers to dst then opaque diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 45298b522d..26e00530be 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -88,4 +88,46 @@ void GrProcessor::assertEquality(const GrProcessor& other) const { SkASSERT(this->textureAccess(i) == other.textureAccess(i)); } } + +void GrProcessor::InvariantOutput::validate() const { + if (fIsSingleComponent) { + SkASSERT(0 == fValidFlags || kRGBA_GrColorComponentFlags == fValidFlags); + if (kRGBA_GrColorComponentFlags == fValidFlags) { + SkASSERT(this->colorComponentsAllEqual()); + } + } + + SkASSERT(this->validPreMulColor()); +} + +bool GrProcessor::InvariantOutput::colorComponentsAllEqual() const { + unsigned colorA = GrColorUnpackA(fColor); + return(GrColorUnpackR(fColor) == colorA && + GrColorUnpackG(fColor) == colorA && + GrColorUnpackB(fColor) == colorA); +} + +bool GrProcessor::InvariantOutput::validPreMulColor() const { + if (kA_GrColorComponentFlag & fValidFlags) { + float c[4]; + GrColorToRGBAFloat(fColor, c); + if (kR_GrColorComponentFlag & fValidFlags) { + if (c[0] > c[3]) { + return false; + } + } + if (kG_GrColorComponentFlag & fValidFlags) { + if (c[1] > c[3]) { + return false; + } + } + if (kB_GrColorComponentFlag & fValidFlags) { + if (c[2] > c[3]) { + return false; + } + } + } + return true; +} #endif + diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h index cb79ac39c5..4631a2ca8e 100644 --- a/src/gpu/effects/GrBezierEffect.h +++ b/src/gpu/effects/GrBezierEffect.h @@ -97,11 +97,6 @@ public: typedef GrGLConicEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -109,6 +104,11 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + GrPrimitiveEdgeType fEdgeType; const GrShaderVar& fInConicCoeffs; @@ -170,11 +170,6 @@ public: typedef GrGLQuadEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -182,6 +177,11 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + GrPrimitiveEdgeType fEdgeType; const GrShaderVar& fInHairQuadEdge; @@ -245,11 +245,6 @@ public: typedef GrGLCubicEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - *validFlags = 0; - } - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -257,6 +252,11 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + GrPrimitiveEdgeType fEdgeType; const GrShaderVar& fInCubicCoeffs; diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp index d73e604b04..f5cc9d1218 100644 --- a/src/gpu/effects/GrBicubicEffect.cpp +++ b/src/gpu/effects/GrBicubicEffect.cpp @@ -169,9 +169,10 @@ bool GrBicubicEffect::onIsEqual(const GrProcessor& sBase) const { fDomain == s.fDomain; } -void GrBicubicEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { +void GrBicubicEffect::onComputeInvariantOutput(InvariantOutput* inout) const { // FIXME: Perhaps we can do better. - *validFlags = 0; + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; return; } diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h index 03476da38f..e36aa8d1d5 100644 --- a/src/gpu/effects/GrBicubicEffect.h +++ b/src/gpu/effects/GrBicubicEffect.h @@ -29,7 +29,6 @@ public: typedef GrGLBicubicEffect GLProcessor; virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; const GrTextureDomain& domain() const { return fDomain; } @@ -93,6 +92,8 @@ private: const SkMatrix &matrix, const SkRect& domain); virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + float fCoefficients[16]; GrTextureDomain fDomain; diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 3042d86f03..f60be2a970 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -126,9 +126,9 @@ bool GrConfigConversionEffect::onIsEqual(const GrProcessor& s) const { other.fPMConversion == fPMConversion; } -void GrConfigConversionEffect::getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const { - this->updateConstantColorComponentsForModulation(color, validFlags); +void GrConfigConversionEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + this->updateInvariantOutputForModulation(inout); + inout->fIsSingleComponent = false; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h index 765e49b45b..aa2c87482e 100644 --- a/src/gpu/effects/GrConfigConversionEffect.h +++ b/src/gpu/effects/GrConfigConversionEffect.h @@ -43,8 +43,6 @@ public: virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - bool swapsRedAndBlue() const { return fSwapRedAndBlue; } PMConversion pmConversion() const { return fPMConversion; } @@ -65,6 +63,8 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + bool fSwapRedAndBlue; PMConversion fPMConversion; diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index 4857a9e96d..836596a761 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -29,17 +29,6 @@ public: return SkNEW_ARGS(AARectEffect, (edgeType, rect)); } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - if (fRect.isEmpty()) { - // An empty rect will have no coverage anywhere. - *color = 0x00000000; - *validFlags = kRGBA_GrColorComponentFlags; - } else { - *validFlags = 0; - } - } - GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; @@ -54,6 +43,17 @@ private: return fRect == aare.fRect; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + if (fRect.isEmpty()) { + // An empty rect will have no coverage anywhere. + inout->fColor = 0x00000000; + inout->fValidFlags = kRGBA_GrColorComponentFlags; + } else { + inout->fValidFlags = 0; + } + inout->fIsSingleComponent = false; + } + SkRect fRect; GrPrimitiveEdgeType fEdgeType; @@ -328,8 +328,9 @@ GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, co GrConvexPolyEffect::~GrConvexPolyEffect() {} -void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void GrConvexPolyEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& GrConvexPolyEffect::getFactory() const { diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h index e4749390a4..7f76f797dc 100644 --- a/src/gpu/effects/GrConvexPolyEffect.h +++ b/src/gpu/effects/GrConvexPolyEffect.h @@ -70,8 +70,6 @@ public: typedef GrGLConvexPolyEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -79,6 +77,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrPrimitiveEdgeType fEdgeType; int fEdgeCount; SkScalar fEdges[3 * kMaxEdges]; diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h index f2a2d5a779..f61f378ec2 100644 --- a/src/gpu/effects/GrConvolutionEffect.h +++ b/src/gpu/effects/GrConvolutionEffect.h @@ -64,12 +64,6 @@ public: virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor*, uint32_t* validFlags) const { - // If the texture was opaque we could know that the output color if we knew the sum of the - // kernel values. - *validFlags = 0; - } - enum { // This was decided based on the min allowed value for the max texture // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0 @@ -103,6 +97,13 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const { + // If the texture was opaque we could know that the output color if we knew the sum of the + // kernel values. + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; typedef Gr1DKernelEffect INHERITED; diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp index b9794c149d..7362ba98a6 100644 --- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp +++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp @@ -72,14 +72,13 @@ bool GrCustomCoordsTextureEffect::onIsEqual(const GrProcessor& other) const { return fTextureAccess == cte.fTextureAccess; } -void GrCustomCoordsTextureEffect::getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const { - if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && - GrPixelConfigIsOpaque(this->texture(0)->config())) { - *validFlags = kA_GrColorComponentFlag; +void GrCustomCoordsTextureEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { + inout->fValidFlags = kA_GrColorComponentFlag; } else { - *validFlags = 0; + inout->fValidFlags = 0; } + inout->fIsSingleComponent = false; } const GrBackendGeometryProcessorFactory& GrCustomCoordsTextureEffect::getFactory() const { diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.h b/src/gpu/effects/GrCustomCoordsTextureEffect.h index f48a144c56..0a6af7d4b4 100644 --- a/src/gpu/effects/GrCustomCoordsTextureEffect.h +++ b/src/gpu/effects/GrCustomCoordsTextureEffect.h @@ -28,8 +28,6 @@ public: static const char* Name() { return "Texture"; } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - const GrShaderVar& inTextureCoords() const { return fInTextureCoords; } typedef GrGLCustomCoordsTextureEffect GLProcessor; @@ -41,6 +39,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrTextureAccess fTextureAccess; const GrShaderVar& fInTextureCoords; diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 704a6ac3e6..4df1f02558 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -456,8 +456,6 @@ public: typedef GLDashingCircleEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -465,6 +463,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrPrimitiveEdgeType fEdgeType; const GrShaderVar& fInCoord; SkScalar fIntervalLength; @@ -584,8 +584,9 @@ GrGeometryProcessor* DashingCircleEffect::Create(GrPrimitiveEdgeType edgeType, c DashingCircleEffect::~DashingCircleEffect() {} -void DashingCircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void DashingCircleEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const { @@ -668,8 +669,6 @@ public: typedef GLDashingLineEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -677,6 +676,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrPrimitiveEdgeType fEdgeType; const GrShaderVar& fInCoord; SkRect fRect; @@ -807,8 +808,9 @@ GrGeometryProcessor* DashingLineEffect::Create(GrPrimitiveEdgeType edgeType, DashingLineEffect::~DashingLineEffect() {} -void DashingLineEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void DashingLineEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const { diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp index d5d334805c..245a035592 100755 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp @@ -206,14 +206,14 @@ bool GrDistanceFieldTextureEffect::onIsEqual(const GrProcessor& other) const { fFlags == cte.fFlags; } -void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const { - if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && - GrPixelConfigIsOpaque(this->texture(0)->config())) { - *validFlags = kA_GrColorComponentFlag; +void GrDistanceFieldTextureEffect::onComputeInvariantOutput( + InvariantOutput* inout) const { + if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { + inout->fValidFlags = kA_GrColorComponentFlag; } else { - *validFlags = 0; + inout->fValidFlags = 0; } + inout->fIsSingleComponent = false; } const GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactory() const { @@ -476,14 +476,14 @@ bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrProcessor& other) const fFlags == cte.fFlags); } -void GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const { - if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && - GrPixelConfigIsOpaque(this->texture(0)->config())) { - *validFlags = kA_GrColorComponentFlag; +void GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput( + InvariantOutput* inout) const { + if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { + inout->fValidFlags = kA_GrColorComponentFlag; } else { - *validFlags = 0; + inout->fValidFlags = 0; } + inout->fIsSingleComponent = false; } const GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFactory() const { diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h index b8d774d610..efd622ea72 100644 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.h +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h @@ -58,8 +58,6 @@ public: static const char* Name() { return "DistanceFieldTexture"; } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - const GrShaderVar& inTextureCoords() const { return fInTextureCoords; } #ifdef SK_GAMMA_APPLY_TO_A8 float getLuminance() const { return fLuminance; } @@ -79,6 +77,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrTextureAccess fTextureAccess; #ifdef SK_GAMMA_APPLY_TO_A8 GrTextureAccess fGammaTextureAccess; @@ -112,7 +112,6 @@ public: static const char* Name() { return "DistanceFieldLCDTexture"; } const GrShaderVar& inTextureCoords() const { return fInTextureCoords; } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; GrColor getTextColor() const { return fTextColor; } uint32_t getFlags() const { return fFlags; } @@ -128,6 +127,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GrTextureAccess fTextureAccess; GrTextureAccess fGammaTextureAccess; GrColor fTextColor; diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp index fe7447d179..e7f90acd87 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -30,8 +30,6 @@ public: typedef GLDitherEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE { return GrTBackendFragmentProcessorFactory::getInstance(); } @@ -44,13 +42,16 @@ private: // All dither effects are equal virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; typedef GrFragmentProcessor INHERITED; }; -void DitherEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void DitherEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } ////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h index 4cc4296eee..4d76f4c9ac 100644 --- a/src/gpu/effects/GrMatrixConvolutionEffect.h +++ b/src/gpu/effects/GrMatrixConvolutionEffect.h @@ -52,12 +52,6 @@ public: virtual ~GrMatrixConvolutionEffect(); - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - // TODO: Try to do better? - *validFlags = 0; - } - static const char* Name() { return "MatrixConvolution"; } const SkIRect& bounds() const { return fBounds; } const SkISize& kernelSize() const { return fKernelSize; } @@ -85,6 +79,12 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + // TODO: Try to do better? + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; + } + SkIRect fBounds; SkISize fKernelSize; float fKernel[MAX_KERNEL_SIZE]; diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp index 10fd8a6bf4..2a04e16611 100644 --- a/src/gpu/effects/GrOvalEffect.cpp +++ b/src/gpu/effects/GrOvalEffect.cpp @@ -32,8 +32,6 @@ public: typedef GLCircleEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -41,6 +39,8 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + SkPoint fCenter; SkScalar fRadius; GrPrimitiveEdgeType fEdgeType; @@ -56,8 +56,9 @@ GrFragmentProcessor* CircleEffect::Create(GrPrimitiveEdgeType edgeType, const Sk return SkNEW_ARGS(CircleEffect, (edgeType, center, radius)); } -void CircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void CircleEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& CircleEffect::getFactory() const { @@ -204,8 +205,6 @@ public: typedef GLEllipseEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -213,6 +212,8 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + SkPoint fCenter; SkVector fRadii; GrPrimitiveEdgeType fEdgeType; @@ -230,8 +231,9 @@ GrFragmentProcessor* EllipseEffect::Create(GrPrimitiveEdgeType edgeType, return SkNEW_ARGS(EllipseEffect, (edgeType, center, rx, ry)); } -void EllipseEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void EllipseEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& EllipseEffect::getFactory() const { diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp index f5131feba4..0af564c844 100644 --- a/src/gpu/effects/GrRRectEffect.cpp +++ b/src/gpu/effects/GrRRectEffect.cpp @@ -59,8 +59,6 @@ public: typedef GLCircularRRectEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -68,6 +66,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + SkRRect fRRect; GrPrimitiveEdgeType fEdgeType; uint32_t fCircularCornerFlags; @@ -86,8 +86,9 @@ GrFragmentProcessor* CircularRRectEffect::Create(GrPrimitiveEdgeType edgeType, return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect)); } -void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void CircularRRectEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& CircularRRectEffect::getFactory() const { @@ -399,8 +400,6 @@ public: typedef GLEllipticalRRectEffect GLProcessor; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; private: @@ -408,6 +407,8 @@ private: virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + SkRRect fRRect; GrPrimitiveEdgeType fEdgeType; @@ -424,8 +425,9 @@ EllipticalRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect)); } -void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; +void EllipticalRRectEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + inout->fValidFlags = 0; + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& EllipticalRRectEffect::getFactory() const { diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp index 6743ddbbe1..a7707da8af 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -41,8 +41,9 @@ private: /////////////////////////////////////////////////////////////////////////////// -void GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - this->updateConstantColorComponentsForModulation(color, validFlags); +void GrSimpleTextureEffect::onComputeInvariantOutput(InvariantOutput* inout) const { + this->updateInvariantOutputForModulation(inout); + inout->fIsSingleComponent = false; } const GrBackendFragmentProcessorFactory& GrSimpleTextureEffect::getFactory() const { diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h index dc9cf85e0f..88c5ca21a1 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.h +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -49,8 +49,6 @@ public: static const char* Name() { return "Texture"; } - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - typedef GrGLSimpleTextureEffect GLProcessor; virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; @@ -75,6 +73,8 @@ private: return this->hasSameTextureParamsMatrixAndSourceCoords(ste); } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; typedef GrSingleTextureEffect INHERITED; diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index 6349ee7896..cba322eab4 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -44,16 +44,15 @@ protected: } /** - * Can be used as a helper to implement subclass getConstantColorComponents(). It assumes that + * Can be used as a helper to implement subclass onComputeInvariantOutput(). It assumes that * the subclass output color will be a modulation of the input color with a value read from the * texture. */ - void updateConstantColorComponentsForModulation(GrColor* color, uint32_t* validFlags) const { - if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && - GrPixelConfigIsOpaque(this->texture(0)->config())) { - *validFlags = kA_GrColorComponentFlag; + void updateInvariantOutputForModulation(InvariantOutput* inout) const { + if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) { + inout->fValidFlags = kA_GrColorComponentFlag; } else { - *validFlags = 0; + inout->fValidFlags = 0; } } diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 1d3b37dddd..90e3b412e6 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -269,12 +269,13 @@ bool GrTextureDomainEffect::onIsEqual(const GrProcessor& sBase) const { this->fTextureDomain == s.fTextureDomain; } -void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { +void GrTextureDomainEffect::onComputeInvariantOutput(InvariantOutput* inout) const { if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper - *validFlags = 0; + inout->fValidFlags = 0; } else { - this->updateConstantColorComponentsForModulation(color, validFlags); + this->updateInvariantOutputForModulation(inout); } + inout->fIsSingleComponent = false; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index 5751bad0f7..ec86847925 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -159,7 +159,6 @@ public: typedef GrGLTextureDomainEffect GLProcessor; virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; const GrTextureDomain& textureDomain() const { return fTextureDomain; } @@ -176,6 +175,8 @@ private: virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; typedef GrSingleTextureEffect INHERITED; diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp index 436106c991..cdbe654ede 100644 --- a/src/gpu/effects/GrYUVtoRGBEffect.cpp +++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp @@ -28,13 +28,6 @@ public: return GrTBackendFragmentProcessorFactory::getInstance(); } - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - // YUV is opaque - *color = 0xFF; - *validFlags = kA_GrColorComponentFlag; - } - SkYUVColorSpace getColorSpace() const { return fColorSpace; } @@ -117,6 +110,13 @@ private: fColorSpace == s.getColorSpace(); } + virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { + // YUV is opaque + inout->fColor = 0xFF; + inout->fValidFlags = kA_GrColorComponentFlag; + inout->fIsSingleComponent = false; + } + GrCoordTransform fCoordTransform; GrTextureAccess fYAccess; GrTextureAccess fUAccess; diff --git a/tests/GpuColorFilterTest.cpp b/tests/GpuColorFilterTest.cpp index 202756b0e6..a61fe0b545 100644 --- a/tests/GpuColorFilterTest.cpp +++ b/tests/GpuColorFilterTest.cpp @@ -99,12 +99,14 @@ static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrCont const GetConstantComponentTestCase& test = filterTests[i]; SkAutoTUnref cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode)); SkAutoTUnref effect(cf->asFragmentProcessor(grContext)); - GrColor color = test.inputColor; - uint32_t components = test.inputComponents; - effect->getConstantColorComponents(&color, &components); - - REPORTER_ASSERT(reporter, filterColor(color, components) == test.outputColor); - REPORTER_ASSERT(reporter, test.outputComponents == components); + GrProcessor::InvariantOutput inout; + inout.fColor = test.inputColor; + inout.fValidFlags = test.inputComponents; + inout.fIsSingleComponent = false; + effect->computeInvariantOutput(&inout); + + REPORTER_ASSERT(reporter, filterColor(inout.fColor, inout.fValidFlags) == test.outputColor); + REPORTER_ASSERT(reporter, test.outputComponents == inout.fValidFlags); } } -- 2.34.1