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:

Review URL: https://codereview.chromium.org/608253002
This commit is contained in:
egdaniel 2014-10-02 09:57:48 -07:00 committed by Commit bot
parent 8f8c25eabb
commit 3b8af07828
47 changed files with 440 additions and 331 deletions

View File

@ -37,14 +37,49 @@ 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 == GrColorUnpackA(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 +193,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;

View File

@ -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<XferEffect>::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;

View File

@ -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

View File

@ -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<GrArithmeticEffect>::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;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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 {

View File

@ -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);

View File

@ -349,51 +349,6 @@ public:
return GrTBackendFragmentProcessorFactory<ColorMatrixEffect>::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<uint8_t>(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<uint8_t>(SkScalarPin(outputA, 0, 255)) << GrColor_SHIFT_A;
inout->fIsSingleComponent = false;
}
SkColorMatrix fMatrix;
typedef GrFragmentProcessor INHERITED;

View File

@ -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<GrDisplacementMapEffect>::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;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -73,13 +73,6 @@ public:
return GrTBackendFragmentProcessorFactory<LumaColorFilterEffect>::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 {

View File

@ -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

View File

@ -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;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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,

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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<EllipseEdgeEffect>::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<DIEllipseEdgeEffect>::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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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 {

View File

@ -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];

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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<DitherEffect>::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;
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -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];

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -28,13 +28,6 @@ public:
return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::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;

View File

@ -99,12 +99,14 @@ static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrCont
const GetConstantComponentTestCase& test = filterTests[i];
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
SkAutoTUnref<GrFragmentProcessor> effect(cf->asFragmentProcessor(grContext));
GrColor color = test.inputColor;
uint32_t components = test.inputComponents;
effect->getConstantColorComponents(&color, &components);
GrProcessor::InvariantOutput inout;
inout.fColor = test.inputColor;
inout.fValidFlags = test.inputComponents;
inout.fIsSingleComponent = false;
effect->computeInvariantOutput(&inout);
REPORTER_ASSERT(reporter, filterColor(color, components) == test.outputColor);
REPORTER_ASSERT(reporter, test.outputComponents == components);
REPORTER_ASSERT(reporter, filterColor(inout.fColor, inout.fValidFlags) == test.outputColor);
REPORTER_ASSERT(reporter, test.outputComponents == inout.fValidFlags);
}
}