зеркало из https://github.com/mozilla/moz-skia.git
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:
Родитель
8f8c25eabb
Коммит
3b8af07828
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче