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:
parent
8f8c25eabb
commit
3b8af07828
@ -37,14 +37,49 @@ public:
|
|||||||
|
|
||||||
virtual ~GrProcessor();
|
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.
|
* 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
|
* In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent
|
||||||
* indicate known values of its output. A component of the color param only has meaning if the
|
* member indicates whether the input will be 1 or 4 bytes. The function updates the members of
|
||||||
* corresponding bit in validFlags is set.
|
* 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-
|
/** 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,
|
identification. The factory should be an instance of templated class,
|
||||||
@ -158,6 +193,10 @@ private:
|
|||||||
getFactory()).*/
|
getFactory()).*/
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const = 0;
|
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.
|
friend class GrGeometryProcessor; // to set fRequiresVertexShader and build fVertexAttribTypes.
|
||||||
|
|
||||||
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
|
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 {
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
return GrTBackendFragmentProcessorFactory<XferEffect>::getInstance();
|
return GrTBackendFragmentProcessorFactory<XferEffect>::getInstance();
|
||||||
}
|
}
|
||||||
@ -1216,6 +1211,11 @@ private:
|
|||||||
return fMode == s.fMode &&
|
return fMode == s.fMode &&
|
||||||
fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture();
|
fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
|
}
|
||||||
|
|
||||||
SkXfermode::Mode fMode;
|
SkXfermode::Mode fMode;
|
||||||
GrCoordTransform fBackgroundTransform;
|
GrCoordTransform fBackgroundTransform;
|
||||||
|
@ -76,8 +76,6 @@ public:
|
|||||||
static const char* Name() { return "Alpha Threshold"; }
|
static const char* Name() { return "Alpha Threshold"; }
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
float innerThreshold() const { return fInnerThreshold; }
|
float innerThreshold() const { return fInnerThreshold; }
|
||||||
float outerThreshold() const { return fOuterThreshold; }
|
float outerThreshold() const { return fOuterThreshold; }
|
||||||
|
|
||||||
@ -104,6 +102,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
float fInnerThreshold;
|
float fInnerThreshold;
|
||||||
@ -228,13 +228,13 @@ bool AlphaThresholdEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
this->fOuterThreshold == s.fOuterThreshold);
|
this->fOuterThreshold == s.fOuterThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlphaThresholdEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void AlphaThresholdEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
|
if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
||||||
GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
inout->fValidFlags = kA_GrColorComponentFlag;
|
||||||
*validFlags = kA_GrColorComponentFlag;
|
|
||||||
} else {
|
} else {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
}
|
}
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -289,8 +289,6 @@ public:
|
|||||||
static const char* Name() { return "Arithmetic"; }
|
static const char* Name() { return "Arithmetic"; }
|
||||||
GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture(); }
|
GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture(); }
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
float k1() const { return fK1; }
|
float k1() const { return fK1; }
|
||||||
float k2() const { return fK2; }
|
float k2() const { return fK2; }
|
||||||
float k3() const { return fK3; }
|
float k3() const { return fK3; }
|
||||||
@ -300,6 +298,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
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,
|
GrArithmeticEffect(float k1, float k2, float k3, float k4, bool enforcePMColor,
|
||||||
GrTexture* background);
|
GrTexture* background);
|
||||||
float fK1, fK2, fK3, fK4;
|
float fK1, fK2, fK3, fK4;
|
||||||
@ -344,9 +344,10 @@ const GrBackendFragmentProcessorFactory& GrArithmeticEffect::getFactory() const
|
|||||||
return GrTBackendFragmentProcessorFactory<GrArithmeticEffect>::getInstance();
|
return GrTBackendFragmentProcessorFactory<GrArithmeticEffect>::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrArithmeticEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
// TODO: optimize this
|
// TODO: optimize this
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -563,8 +563,6 @@ public:
|
|||||||
typedef GrGLRectBlurEffect GLProcessor;
|
typedef GrGLRectBlurEffect GLProcessor;
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
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.
|
* Create a simple filter effect with custom bicubic coefficients.
|
||||||
*/
|
*/
|
||||||
@ -594,6 +592,8 @@ private:
|
|||||||
GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile);
|
GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile);
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
static bool CreateBlurProfileTexture(GrContext *context, float sigma,
|
static bool CreateBlurProfileTexture(GrContext *context, float sigma,
|
||||||
GrTexture **blurProfileTexture);
|
GrTexture **blurProfileTexture);
|
||||||
|
|
||||||
@ -765,9 +765,9 @@ bool GrRectBlurEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
return this->getSigma() == s.getSigma() && this->getRect() == s.getRect();
|
return this->getSigma() == s.getSigma() && this->getRect() == s.getRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrRectBlurEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
return;
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
|
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
|
||||||
@ -837,8 +837,6 @@ public:
|
|||||||
|
|
||||||
typedef GrGLRRectBlurEffect GLProcessor;
|
typedef GrGLRRectBlurEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -846,6 +844,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
SkRRect fRRect;
|
SkRRect fRRect;
|
||||||
float fSigma;
|
float fSigma;
|
||||||
GrTextureAccess fNinePatchAccess;
|
GrTextureAccess fNinePatchAccess;
|
||||||
@ -929,8 +929,9 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
|
|||||||
return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture));
|
return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrRRectBlurEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& GrRRectBlurEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& GrRRectBlurEffect::getFactory() const {
|
||||||
|
@ -195,8 +195,6 @@ public:
|
|||||||
return SkNEW_ARGS(ModeColorFilterEffect, (c, mode));
|
return SkNEW_ARGS(ModeColorFilterEffect, (c, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
bool willUseFilterColor() const {
|
bool willUseFilterColor() const {
|
||||||
SkXfermode::Coeff dstCoeff;
|
SkXfermode::Coeff dstCoeff;
|
||||||
SkXfermode::Coeff srcCoeff;
|
SkXfermode::Coeff srcCoeff;
|
||||||
@ -293,6 +291,8 @@ private:
|
|||||||
return fMode == s.fMode && fColor == s.fColor;
|
return fMode == s.fMode && fColor == s.fColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
SkXfermode::Mode fMode;
|
SkXfermode::Mode fMode;
|
||||||
GrColor fColor;
|
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];
|
float inputColor[4];
|
||||||
GrColorToRGBAFloat(*color, inputColor);
|
GrColorToRGBAFloat(inout->fColor, inputColor);
|
||||||
float filterColor[4];
|
float filterColor[4];
|
||||||
GrColorToRGBAFloat(fColor, filterColor);
|
GrColorToRGBAFloat(fColor, filterColor);
|
||||||
MaskedColorExpr result =
|
MaskedColorExpr result =
|
||||||
color_filter_expression(fMode,
|
color_filter_expression(fMode,
|
||||||
MaskedColorExpr(filterColor, kRGBA_GrColorComponentFlags),
|
MaskedColorExpr(filterColor, kRGBA_GrColorComponentFlags),
|
||||||
MaskedColorExpr(inputColor, *validFlags));
|
MaskedColorExpr(inputColor, inout->fValidFlags));
|
||||||
|
|
||||||
*color = result.getColor();
|
inout->fColor = result.getColor();
|
||||||
*validFlags = result.getValidComponents();
|
inout->fValidFlags = result.getValidComponents();
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ModeColorFilterEffect);
|
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ModeColorFilterEffect);
|
||||||
|
@ -349,51 +349,6 @@ public:
|
|||||||
return GrTBackendFragmentProcessorFactory<ColorMatrixEffect>::getInstance();
|
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;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
class GLProcessor : public GrGLFragmentProcessor {
|
class GLProcessor : public GrGLFragmentProcessor {
|
||||||
@ -471,6 +426,51 @@ private:
|
|||||||
return cme.fMatrix == fMatrix;
|
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;
|
SkColorMatrix fMatrix;
|
||||||
|
|
||||||
typedef GrFragmentProcessor INHERITED;
|
typedef GrFragmentProcessor INHERITED;
|
||||||
|
@ -351,11 +351,11 @@ public:
|
|||||||
typedef GrGLDisplacementMapEffect GLProcessor;
|
typedef GrGLDisplacementMapEffect GLProcessor;
|
||||||
static const char* Name() { return "DisplacementMap"; }
|
static const char* Name() { return "DisplacementMap"; }
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
|
GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
|
||||||
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
|
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
|
||||||
const SkVector& scale,
|
const SkVector& scale,
|
||||||
@ -491,14 +491,14 @@ const GrBackendFragmentProcessorFactory& GrDisplacementMapEffect::getFactory() c
|
|||||||
return GrTBackendFragmentProcessorFactory<GrDisplacementMapEffect>::getInstance();
|
return GrTBackendFragmentProcessorFactory<GrDisplacementMapEffect>::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrDisplacementMapEffect::getConstantColorComponents(GrColor*,
|
void GrDisplacementMapEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
uint32_t* validFlags) const {
|
|
||||||
// Any displacement offset bringing a pixel out of bounds will output a color of (0,0,0,0),
|
// 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
|
// 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
|
// 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
|
// 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.
|
// 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; }
|
SkScalar surfaceScale() const { return fSurfaceScale; }
|
||||||
const SkMatrix& filterMatrix() const { return fFilterMatrix; }
|
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:
|
protected:
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
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:
|
private:
|
||||||
typedef GrSingleTextureEffect INHERITED;
|
typedef GrSingleTextureEffect INHERITED;
|
||||||
const SkLight* fLight;
|
const SkLight* fLight;
|
||||||
|
@ -73,13 +73,6 @@ public:
|
|||||||
return GrTBackendFragmentProcessorFactory<LumaColorFilterEffect>::getInstance();
|
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 {
|
class GLProcessor : public GrGLFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
GLProcessor(const GrBackendProcessorFactory& factory,
|
GLProcessor(const GrBackendProcessorFactory& factory,
|
||||||
@ -119,6 +112,13 @@ private:
|
|||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE {
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE {
|
||||||
return true;
|
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 {
|
GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
|
||||||
|
@ -47,8 +47,6 @@ public:
|
|||||||
static const char* Name() { return "Magnifier"; }
|
static const char* Name() { return "Magnifier"; }
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
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 x_offset() const { return fXOffset; }
|
||||||
float y_offset() const { return fYOffset; }
|
float y_offset() const { return fYOffset; }
|
||||||
float x_inv_zoom() const { return fXInvZoom; }
|
float x_inv_zoom() const { return fXInvZoom; }
|
||||||
@ -76,6 +74,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
float fXOffset;
|
float fXOffset;
|
||||||
@ -227,8 +227,9 @@ bool GrMagnifierEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
this->fYInvInset == s.fYInvInset);
|
this->fYInvInset == s.fYInvInset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrMagnifierEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
this->updateConstantColorComponentsForModulation(color, validFlags);
|
this->updateInvariantOutputForModulation(inout);
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -309,7 +309,6 @@ public:
|
|||||||
typedef GrGLMorphologyEffect GLProcessor;
|
typedef GrGLMorphologyEffect GLProcessor;
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -318,6 +317,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
|
GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
@ -455,10 +456,11 @@ bool GrMorphologyEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
this->type() == s.type());
|
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
|
// This is valid because the color components of the result of the kernel all come
|
||||||
// exactly from existing values in the source texture.
|
// 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;
|
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,
|
GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type,
|
||||||
int numOctaves, bool stitchTiles,
|
int numOctaves, bool stitchTiles,
|
||||||
SkPerlinNoiseShader::PaintingData* paintingData,
|
SkPerlinNoiseShader::PaintingData* paintingData,
|
||||||
@ -616,10 +621,6 @@ private:
|
|||||||
GrTextureAccess fNoiseAccess;
|
GrTextureAccess fNoiseAccess;
|
||||||
SkPerlinNoiseShader::PaintingData *fPaintingData;
|
SkPerlinNoiseShader::PaintingData *fPaintingData;
|
||||||
|
|
||||||
void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE {
|
|
||||||
*validFlags = 0; // This is noise. Nothing is constant.
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef GrFragmentProcessor INHERITED;
|
typedef GrFragmentProcessor INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -294,20 +294,20 @@ public:
|
|||||||
static const char* Name() { return "ColorTable"; }
|
static const char* Name() { return "ColorTable"; }
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
typedef GLColorTableEffect GLProcessor;
|
typedef GLColorTableEffect GLProcessor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
explicit ColorTableEffect(GrTexture* texture, unsigned flags);
|
explicit ColorTableEffect(GrTexture* texture, unsigned flags);
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
GrTextureAccess fTextureAccess;
|
GrTextureAccess fTextureAccess;
|
||||||
unsigned fFlags; // currently not used in shader code, just to assist
|
unsigned fFlags; // currently not used in shader code, just to assist
|
||||||
// getConstantColorComponents().
|
// onComputeInvariantOutput().
|
||||||
|
|
||||||
typedef GrFragmentProcessor INHERITED;
|
typedef GrFragmentProcessor INHERITED;
|
||||||
};
|
};
|
||||||
@ -401,21 +401,22 @@ bool ColorTableEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
return this->texture(0) == sBase.texture(0);
|
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
|
// If we kept the table in the effect then we could actually run known inputs through the
|
||||||
// table.
|
// table.
|
||||||
if (fFlags & SkTable_ColorFilter::kR_Flag) {
|
if (fFlags & SkTable_ColorFilter::kR_Flag) {
|
||||||
*validFlags &= ~kR_GrColorComponentFlag;
|
inout->fValidFlags &= ~kR_GrColorComponentFlag;
|
||||||
}
|
}
|
||||||
if (fFlags & SkTable_ColorFilter::kG_Flag) {
|
if (fFlags & SkTable_ColorFilter::kG_Flag) {
|
||||||
*validFlags &= ~kG_GrColorComponentFlag;
|
inout->fValidFlags &= ~kG_GrColorComponentFlag;
|
||||||
}
|
}
|
||||||
if (fFlags & SkTable_ColorFilter::kB_Flag) {
|
if (fFlags & SkTable_ColorFilter::kB_Flag) {
|
||||||
*validFlags &= ~kB_GrColorComponentFlag;
|
inout->fValidFlags &= ~kB_GrColorComponentFlag;
|
||||||
}
|
}
|
||||||
if (fFlags & SkTable_ColorFilter::kA_Flag) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrGradientEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) {
|
if (fIsOpaque && inout->isOpaque()) {
|
||||||
*validFlags = kA_GrColorComponentFlag;
|
inout->fValidFlags = kA_GrColorComponentFlag;
|
||||||
} else {
|
} else {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
}
|
}
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GrGradientEffect::RandomGradientParams(SkRandom* random,
|
int GrGradientEffect::RandomGradientParams(SkRandom* random,
|
||||||
|
@ -342,8 +342,6 @@ public:
|
|||||||
bool useAtlas() const { return SkToBool(-1 != fRow); }
|
bool useAtlas() const { return SkToBool(-1 != fRow); }
|
||||||
SkScalar getYCoord() const { return fYCoord; };
|
SkScalar getYCoord() const { return fYCoord; };
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
|
SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
|
||||||
|
|
||||||
enum PremulType {
|
enum PremulType {
|
||||||
@ -376,6 +374,8 @@ protected:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
|
const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -517,11 +517,6 @@ public:
|
|||||||
|
|
||||||
static const char* Name() { return "QuadEdge"; }
|
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; }
|
const GrShaderVar& inQuadEdge() const { return fInQuadEdge; }
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
@ -593,6 +588,11 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
|
}
|
||||||
|
|
||||||
const GrShaderVar& fInQuadEdge;
|
const GrShaderVar& fInQuadEdge;
|
||||||
|
|
||||||
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
|
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
|
||||||
|
@ -30,11 +30,6 @@ public:
|
|||||||
|
|
||||||
static const char* Name() { return "AlignedRectEdge"; }
|
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; }
|
const GrShaderVar& inRect() const { return fInRect; }
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
@ -112,6 +107,11 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
|
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;
|
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
|
||||||
|
|
||||||
typedef GrGeometryProcessor INHERITED;
|
typedef GrGeometryProcessor INHERITED;
|
||||||
@ -155,11 +155,6 @@ public:
|
|||||||
|
|
||||||
static const char* Name() { return "RectEdge"; }
|
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& inRectEdge() const { return fInRectEdge; }
|
||||||
const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
|
const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
|
||||||
|
|
||||||
@ -257,6 +252,11 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
|
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& fInRectEdge;
|
||||||
const GrShaderVar& fInWidthHeight;
|
const GrShaderVar& fInWidthHeight;
|
||||||
|
|
||||||
|
@ -421,26 +421,26 @@ bool GrDrawState::hasSolidCoverage() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrColor coverage;
|
GrProcessor::InvariantOutput inout;
|
||||||
uint32_t validComponentFlags;
|
inout.fIsSingleComponent = false;
|
||||||
// Initialize to an unknown starting coverage if per-vertex coverage is specified.
|
// Initialize to an unknown starting coverage if per-vertex coverage is specified.
|
||||||
if (this->hasCoverageVertexAttribute()) {
|
if (this->hasCoverageVertexAttribute()) {
|
||||||
validComponentFlags = 0;
|
inout.fValidFlags = 0;
|
||||||
} else {
|
} else {
|
||||||
coverage = fCoverage;
|
inout.fColor = fCoverage;
|
||||||
validComponentFlags = kRGBA_GrColorComponentFlags;
|
inout.fValidFlags = kRGBA_GrColorComponentFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run through the coverage stages and see if the coverage will be all ones at the end.
|
// Run through the coverage stages and see if the coverage will be all ones at the end.
|
||||||
if (this->hasGeometryProcessor()) {
|
if (this->hasGeometryProcessor()) {
|
||||||
const GrGeometryProcessor* gp = fGeometryProcessor->getGeometryProcessor();
|
const GrGeometryProcessor* gp = fGeometryProcessor->getGeometryProcessor();
|
||||||
gp->getConstantColorComponents(&coverage, &validComponentFlags);
|
gp->computeInvariantOutput(&inout);
|
||||||
}
|
}
|
||||||
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
||||||
const GrProcessor* processor = this->getCoverageStage(s).getProcessor();
|
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 {
|
bool GrDrawState::srcAlphaWillBeOne() const {
|
||||||
uint32_t validComponentFlags;
|
GrProcessor::InvariantOutput inoutColor;
|
||||||
GrColor color;
|
inoutColor.fIsSingleComponent = false;
|
||||||
// Check if per-vertex or constant color may have partial alpha
|
// Check if per-vertex or constant color may have partial alpha
|
||||||
if (this->hasColorVertexAttribute()) {
|
if (this->hasColorVertexAttribute()) {
|
||||||
if (fHints & kVertexColorsAreOpaque_Hint) {
|
if (fHints & kVertexColorsAreOpaque_Hint) {
|
||||||
validComponentFlags = kA_GrColorComponentFlag;
|
inoutColor.fValidFlags = kA_GrColorComponentFlag;
|
||||||
color = 0xFF << GrColor_SHIFT_A;
|
inoutColor.fColor = 0xFF << GrColor_SHIFT_A;
|
||||||
} else {
|
} else {
|
||||||
validComponentFlags = 0;
|
inoutColor.fValidFlags = 0;
|
||||||
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
|
// not strictly necessary but we get false alarms from tools about uninit.
|
||||||
|
inoutColor.fColor = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
validComponentFlags = kRGBA_GrColorComponentFlags;
|
inoutColor.fValidFlags = kRGBA_GrColorComponentFlags;
|
||||||
color = this->getColor();
|
inoutColor.fColor = this->getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run through the color stages
|
// Run through the color stages
|
||||||
for (int s = 0; s < this->numColorStages(); ++s) {
|
for (int s = 0; s < this->numColorStages(); ++s) {
|
||||||
const GrProcessor* processor = this->getColorStage(s).getProcessor();
|
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.
|
// Check whether coverage is treated as color. If so we run through the coverage computation.
|
||||||
if (this->isCoverageDrawing()) {
|
if (this->isCoverageDrawing()) {
|
||||||
// The shader generated for coverage drawing runs the full coverage computation and then
|
// 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.
|
// makes the shader output be the multiplication of color and coverage. We mirror that here.
|
||||||
GrColor coverage;
|
GrProcessor::InvariantOutput inoutCoverage;
|
||||||
uint32_t coverageComponentFlags;
|
inoutCoverage.fIsSingleComponent = false;
|
||||||
if (this->hasCoverageVertexAttribute()) {
|
if (this->hasCoverageVertexAttribute()) {
|
||||||
coverageComponentFlags = 0;
|
inoutCoverage.fValidFlags = 0;
|
||||||
coverage = 0; // suppresses any warnings.
|
inoutCoverage.fColor = 0; // suppresses any warnings.
|
||||||
} else {
|
} else {
|
||||||
coverageComponentFlags = kRGBA_GrColorComponentFlags;
|
inoutCoverage.fValidFlags = kRGBA_GrColorComponentFlags;
|
||||||
coverage = this->getCoverageColor();
|
inoutCoverage.fColor = this->getCoverageColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run through the coverage stages
|
// Run through the coverage stages
|
||||||
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
||||||
const GrProcessor* processor = this->getCoverageStage(s).getProcessor();
|
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
|
// Since the shader will multiply coverage and color, the only way the final A==1 is if
|
||||||
// coverage and color both have A==1.
|
// coverage and color both have A==1.
|
||||||
return (kA_GrColorComponentFlag & validComponentFlags & coverageComponentFlags) &&
|
return (inoutColor.isOpaque() && inoutCoverage.isOpaque());
|
||||||
0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color);
|
return inoutColor.isOpaque();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,18 +170,19 @@ void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) {
|
|||||||
int firstColorStage = 0;
|
int firstColorStage = 0;
|
||||||
|
|
||||||
// Set up color and flags for ConstantColorComponent checks
|
// Set up color and flags for ConstantColorComponent checks
|
||||||
GrColor color;
|
GrProcessor::InvariantOutput inout;
|
||||||
uint32_t validComponentFlags;
|
inout.fIsSingleComponent = false;
|
||||||
if (!this->hasColorVertexAttribute()) {
|
if (!this->hasColorVertexAttribute()) {
|
||||||
color = ds.getColor();
|
inout.fColor = ds.getColor();
|
||||||
validComponentFlags = kRGBA_GrColorComponentFlags;
|
inout.fValidFlags = kRGBA_GrColorComponentFlags;
|
||||||
} else {
|
} else {
|
||||||
if (ds.vertexColorsAreOpaque()) {
|
if (ds.vertexColorsAreOpaque()) {
|
||||||
color = 0xFF << GrColor_SHIFT_A;
|
inout.fColor = 0xFF << GrColor_SHIFT_A;
|
||||||
validComponentFlags = kA_GrColorComponentFlag;
|
inout.fValidFlags = kA_GrColorComponentFlag;
|
||||||
} else {
|
} else {
|
||||||
validComponentFlags = 0;
|
inout.fValidFlags = 0;
|
||||||
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
|
// 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;
|
firstColorStage = i;
|
||||||
fInputColorIsUsed = false;
|
fInputColorIsUsed = false;
|
||||||
}
|
}
|
||||||
fp->getConstantColorComponents(&color, &validComponentFlags);
|
fp->computeInvariantOutput(&inout);
|
||||||
if (kRGBA_GrColorComponentFlags == validComponentFlags) {
|
if (kRGBA_GrColorComponentFlags == inout.fValidFlags) {
|
||||||
firstColorStage = i + 1;
|
firstColorStage = i + 1;
|
||||||
fColor = color;
|
fColor = inout.fColor;
|
||||||
fInputColorIsUsed = true;
|
fInputColorIsUsed = true;
|
||||||
this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
|
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; }
|
const GrShaderVar& inCircleEdge() const { return fInCircleEdge; }
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
@ -150,6 +145,11 @@ private:
|
|||||||
return cee.fStroke == fStroke;
|
return cee.fStroke == fStroke;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
|
}
|
||||||
|
|
||||||
const GrShaderVar& fInCircleEdge;
|
const GrShaderVar& fInCircleEdge;
|
||||||
bool fStroke;
|
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 {
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstance();
|
return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstance();
|
||||||
}
|
}
|
||||||
@ -291,6 +286,11 @@ private:
|
|||||||
return eee.fStroke == fStroke;
|
return eee.fStroke == fStroke;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
|
}
|
||||||
|
|
||||||
const GrShaderVar& fInEllipseOffset;
|
const GrShaderVar& fInEllipseOffset;
|
||||||
const GrShaderVar& fInEllipseRadii;
|
const GrShaderVar& fInEllipseRadii;
|
||||||
bool fStroke;
|
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 {
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInstance();
|
return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInstance();
|
||||||
}
|
}
|
||||||
@ -460,6 +455,11 @@ private:
|
|||||||
return eee.fMode == fMode;
|
return eee.fMode == fMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
|
}
|
||||||
|
|
||||||
const GrShaderVar& fInEllipseOffsets0;
|
const GrShaderVar& fInEllipseOffsets0;
|
||||||
const GrShaderVar& fInEllipseOffsets1;
|
const GrShaderVar& fInEllipseOffsets1;
|
||||||
Mode fMode;
|
Mode fMode;
|
||||||
|
@ -52,28 +52,32 @@ bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
|
|||||||
|
|
||||||
// TODO: Share this implementation with GrDrawState
|
// TODO: Share this implementation with GrDrawState
|
||||||
|
|
||||||
GrColor coverage = GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
|
GrProcessor::InvariantOutput inout;
|
||||||
uint32_t coverageComps = kRGBA_GrColorComponentFlags;
|
inout.fColor = GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
|
||||||
|
inout.fValidFlags = kRGBA_GrColorComponentFlags;
|
||||||
|
inout.fIsSingleComponent = false;
|
||||||
int count = fCoverageStages.count();
|
int count = fCoverageStages.count();
|
||||||
for (int i = 0; i < count; ++i) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrColor color = fColor;
|
inout.fColor = fColor;
|
||||||
uint32_t colorComps = kRGBA_GrColorComponentFlags;
|
inout.fValidFlags = kRGBA_GrColorComponentFlags;
|
||||||
|
inout.fIsSingleComponent = false;
|
||||||
count = fColorStages.count();
|
count = fColorStages.count();
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
fColorStages[i].getProcessor()->getConstantColorComponents(&color, &colorComps);
|
fColorStages[i].getProcessor()->computeInvariantOutput(&inout);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents));
|
SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents));
|
||||||
|
|
||||||
GrBlendCoeff srcCoeff = fSrcBlendCoeff;
|
GrBlendCoeff srcCoeff = fSrcBlendCoeff;
|
||||||
GrBlendCoeff dstCoeff = fDstBlendCoeff;
|
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);
|
bool opaque = kZero_GrBlendCoeff == dstCoeff && !GrBlendCoeffRefsDst(srcCoeff);
|
||||||
if (solidColor) {
|
if (solidColor) {
|
||||||
@ -85,8 +89,8 @@ bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kOne_GrBlendCoeff:
|
case kOne_GrBlendCoeff:
|
||||||
*solidColor = color;
|
*solidColor = inout.fColor;
|
||||||
*solidColorKnownComponents = colorComps;
|
*solidColorKnownComponents = inout.fValidFlags;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// The src coeff should never refer to the src and if it refers to dst then opaque
|
// 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));
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -97,11 +97,6 @@ public:
|
|||||||
|
|
||||||
typedef GrGLConicEffect GLProcessor;
|
typedef GrGLConicEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color,
|
|
||||||
uint32_t* validFlags) const SK_OVERRIDE {
|
|
||||||
*validFlags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -109,6 +104,11 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
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;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
const GrShaderVar& fInConicCoeffs;
|
const GrShaderVar& fInConicCoeffs;
|
||||||
|
|
||||||
@ -170,11 +170,6 @@ public:
|
|||||||
|
|
||||||
typedef GrGLQuadEffect GLProcessor;
|
typedef GrGLQuadEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color,
|
|
||||||
uint32_t* validFlags) const SK_OVERRIDE {
|
|
||||||
*validFlags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -182,6 +177,11 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
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;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
const GrShaderVar& fInHairQuadEdge;
|
const GrShaderVar& fInHairQuadEdge;
|
||||||
|
|
||||||
@ -245,11 +245,6 @@ public:
|
|||||||
|
|
||||||
typedef GrGLCubicEffect GLProcessor;
|
typedef GrGLCubicEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color,
|
|
||||||
uint32_t* validFlags) const SK_OVERRIDE {
|
|
||||||
*validFlags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -257,6 +252,11 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
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;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
const GrShaderVar& fInCubicCoeffs;
|
const GrShaderVar& fInCubicCoeffs;
|
||||||
|
|
||||||
|
@ -169,9 +169,10 @@ bool GrBicubicEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
fDomain == s.fDomain;
|
fDomain == s.fDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrBicubicEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrBicubicEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
// FIXME: Perhaps we can do better.
|
// FIXME: Perhaps we can do better.
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ public:
|
|||||||
typedef GrGLBicubicEffect GLProcessor;
|
typedef GrGLBicubicEffect GLProcessor;
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
const GrTextureDomain& domain() const { return fDomain; }
|
const GrTextureDomain& domain() const { return fDomain; }
|
||||||
|
|
||||||
@ -93,6 +92,8 @@ private:
|
|||||||
const SkMatrix &matrix, const SkRect& domain);
|
const SkMatrix &matrix, const SkRect& domain);
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
float fCoefficients[16];
|
float fCoefficients[16];
|
||||||
GrTextureDomain fDomain;
|
GrTextureDomain fDomain;
|
||||||
|
|
||||||
|
@ -126,9 +126,9 @@ bool GrConfigConversionEffect::onIsEqual(const GrProcessor& s) const {
|
|||||||
other.fPMConversion == fPMConversion;
|
other.fPMConversion == fPMConversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrConfigConversionEffect::getConstantColorComponents(GrColor* color,
|
void GrConfigConversionEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
uint32_t* validFlags) const {
|
this->updateInvariantOutputForModulation(inout);
|
||||||
this->updateConstantColorComponentsForModulation(color, validFlags);
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -43,8 +43,6 @@ public:
|
|||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
bool swapsRedAndBlue() const { return fSwapRedAndBlue; }
|
bool swapsRedAndBlue() const { return fSwapRedAndBlue; }
|
||||||
PMConversion pmConversion() const { return fPMConversion; }
|
PMConversion pmConversion() const { return fPMConversion; }
|
||||||
|
|
||||||
@ -65,6 +63,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
bool fSwapRedAndBlue;
|
bool fSwapRedAndBlue;
|
||||||
PMConversion fPMConversion;
|
PMConversion fPMConversion;
|
||||||
|
|
||||||
|
@ -29,17 +29,6 @@ public:
|
|||||||
return SkNEW_ARGS(AARectEffect, (edgeType, rect));
|
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; }
|
GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
@ -54,6 +43,17 @@ private:
|
|||||||
return fRect == aare.fRect;
|
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;
|
SkRect fRect;
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
|
|
||||||
@ -328,8 +328,9 @@ GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, co
|
|||||||
|
|
||||||
GrConvexPolyEffect::~GrConvexPolyEffect() {}
|
GrConvexPolyEffect::~GrConvexPolyEffect() {}
|
||||||
|
|
||||||
void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrConvexPolyEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& GrConvexPolyEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& GrConvexPolyEffect::getFactory() const {
|
||||||
|
@ -70,8 +70,6 @@ public:
|
|||||||
|
|
||||||
typedef GrGLConvexPolyEffect GLProcessor;
|
typedef GrGLConvexPolyEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -79,6 +77,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
int fEdgeCount;
|
int fEdgeCount;
|
||||||
SkScalar fEdges[3 * kMaxEdges];
|
SkScalar fEdges[3 * kMaxEdges];
|
||||||
|
@ -64,12 +64,6 @@ public:
|
|||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
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 {
|
enum {
|
||||||
// This was decided based on the min allowed value for the max texture
|
// 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
|
// 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 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;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
typedef Gr1DKernelEffect INHERITED;
|
typedef Gr1DKernelEffect INHERITED;
|
||||||
|
@ -72,14 +72,13 @@ bool GrCustomCoordsTextureEffect::onIsEqual(const GrProcessor& other) const {
|
|||||||
return fTextureAccess == cte.fTextureAccess;
|
return fTextureAccess == cte.fTextureAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrCustomCoordsTextureEffect::getConstantColorComponents(GrColor* color,
|
void GrCustomCoordsTextureEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
uint32_t* validFlags) const {
|
if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
||||||
if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
|
inout->fValidFlags = kA_GrColorComponentFlag;
|
||||||
GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
|
||||||
*validFlags = kA_GrColorComponentFlag;
|
|
||||||
} else {
|
} else {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
}
|
}
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendGeometryProcessorFactory& GrCustomCoordsTextureEffect::getFactory() const {
|
const GrBackendGeometryProcessorFactory& GrCustomCoordsTextureEffect::getFactory() const {
|
||||||
|
@ -28,8 +28,6 @@ public:
|
|||||||
|
|
||||||
static const char* Name() { return "Texture"; }
|
static const char* Name() { return "Texture"; }
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
|
const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
|
||||||
|
|
||||||
typedef GrGLCustomCoordsTextureEffect GLProcessor;
|
typedef GrGLCustomCoordsTextureEffect GLProcessor;
|
||||||
@ -41,6 +39,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrTextureAccess fTextureAccess;
|
GrTextureAccess fTextureAccess;
|
||||||
const GrShaderVar& fInTextureCoords;
|
const GrShaderVar& fInTextureCoords;
|
||||||
|
|
||||||
|
@ -456,8 +456,6 @@ public:
|
|||||||
|
|
||||||
typedef GLDashingCircleEffect GLProcessor;
|
typedef GLDashingCircleEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -465,6 +463,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
const GrShaderVar& fInCoord;
|
const GrShaderVar& fInCoord;
|
||||||
SkScalar fIntervalLength;
|
SkScalar fIntervalLength;
|
||||||
@ -584,8 +584,9 @@ GrGeometryProcessor* DashingCircleEffect::Create(GrPrimitiveEdgeType edgeType, c
|
|||||||
|
|
||||||
DashingCircleEffect::~DashingCircleEffect() {}
|
DashingCircleEffect::~DashingCircleEffect() {}
|
||||||
|
|
||||||
void DashingCircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void DashingCircleEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const {
|
const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const {
|
||||||
@ -668,8 +669,6 @@ public:
|
|||||||
|
|
||||||
typedef GLDashingLineEffect GLProcessor;
|
typedef GLDashingLineEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -677,6 +676,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
const GrShaderVar& fInCoord;
|
const GrShaderVar& fInCoord;
|
||||||
SkRect fRect;
|
SkRect fRect;
|
||||||
@ -807,8 +808,9 @@ GrGeometryProcessor* DashingLineEffect::Create(GrPrimitiveEdgeType edgeType,
|
|||||||
|
|
||||||
DashingLineEffect::~DashingLineEffect() {}
|
DashingLineEffect::~DashingLineEffect() {}
|
||||||
|
|
||||||
void DashingLineEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void DashingLineEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const {
|
const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const {
|
||||||
|
@ -206,14 +206,14 @@ bool GrDistanceFieldTextureEffect::onIsEqual(const GrProcessor& other) const {
|
|||||||
fFlags == cte.fFlags;
|
fFlags == cte.fFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color,
|
void GrDistanceFieldTextureEffect::onComputeInvariantOutput(
|
||||||
uint32_t* validFlags) const {
|
InvariantOutput* inout) const {
|
||||||
if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
|
if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
||||||
GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
inout->fValidFlags = kA_GrColorComponentFlag;
|
||||||
*validFlags = kA_GrColorComponentFlag;
|
|
||||||
} else {
|
} else {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
}
|
}
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactory() const {
|
const GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactory() const {
|
||||||
@ -476,14 +476,14 @@ bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrProcessor& other) const
|
|||||||
fFlags == cte.fFlags);
|
fFlags == cte.fFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color,
|
void GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput(
|
||||||
uint32_t* validFlags) const {
|
InvariantOutput* inout) const {
|
||||||
if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
|
if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
||||||
GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
inout->fValidFlags = kA_GrColorComponentFlag;
|
||||||
*validFlags = kA_GrColorComponentFlag;
|
|
||||||
} else {
|
} else {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
}
|
}
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFactory() const {
|
const GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFactory() const {
|
||||||
|
@ -58,8 +58,6 @@ public:
|
|||||||
|
|
||||||
static const char* Name() { return "DistanceFieldTexture"; }
|
static const char* Name() { return "DistanceFieldTexture"; }
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
|
const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
|
||||||
#ifdef SK_GAMMA_APPLY_TO_A8
|
#ifdef SK_GAMMA_APPLY_TO_A8
|
||||||
float getLuminance() const { return fLuminance; }
|
float getLuminance() const { return fLuminance; }
|
||||||
@ -79,6 +77,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrTextureAccess fTextureAccess;
|
GrTextureAccess fTextureAccess;
|
||||||
#ifdef SK_GAMMA_APPLY_TO_A8
|
#ifdef SK_GAMMA_APPLY_TO_A8
|
||||||
GrTextureAccess fGammaTextureAccess;
|
GrTextureAccess fGammaTextureAccess;
|
||||||
@ -112,7 +112,6 @@ public:
|
|||||||
static const char* Name() { return "DistanceFieldLCDTexture"; }
|
static const char* Name() { return "DistanceFieldLCDTexture"; }
|
||||||
|
|
||||||
const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
|
const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
GrColor getTextColor() const { return fTextColor; }
|
GrColor getTextColor() const { return fTextColor; }
|
||||||
uint32_t getFlags() const { return fFlags; }
|
uint32_t getFlags() const { return fFlags; }
|
||||||
|
|
||||||
@ -128,6 +127,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GrTextureAccess fTextureAccess;
|
GrTextureAccess fTextureAccess;
|
||||||
GrTextureAccess fGammaTextureAccess;
|
GrTextureAccess fGammaTextureAccess;
|
||||||
GrColor fTextColor;
|
GrColor fTextColor;
|
||||||
|
@ -30,8 +30,6 @@ public:
|
|||||||
|
|
||||||
typedef GLDitherEffect GLProcessor;
|
typedef GLDitherEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
return GrTBackendFragmentProcessorFactory<DitherEffect>::getInstance();
|
return GrTBackendFragmentProcessorFactory<DitherEffect>::getInstance();
|
||||||
}
|
}
|
||||||
@ -44,13 +42,16 @@ private:
|
|||||||
// All dither effects are equal
|
// All dither effects are equal
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
typedef GrFragmentProcessor INHERITED;
|
typedef GrFragmentProcessor INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DitherEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void DitherEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -52,12 +52,6 @@ public:
|
|||||||
|
|
||||||
virtual ~GrMatrixConvolutionEffect();
|
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"; }
|
static const char* Name() { return "MatrixConvolution"; }
|
||||||
const SkIRect& bounds() const { return fBounds; }
|
const SkIRect& bounds() const { return fBounds; }
|
||||||
const SkISize& kernelSize() const { return fKernelSize; }
|
const SkISize& kernelSize() const { return fKernelSize; }
|
||||||
@ -85,6 +79,12 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
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;
|
SkIRect fBounds;
|
||||||
SkISize fKernelSize;
|
SkISize fKernelSize;
|
||||||
float fKernel[MAX_KERNEL_SIZE];
|
float fKernel[MAX_KERNEL_SIZE];
|
||||||
|
@ -32,8 +32,6 @@ public:
|
|||||||
|
|
||||||
typedef GLCircleEffect GLProcessor;
|
typedef GLCircleEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -41,6 +39,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
SkPoint fCenter;
|
SkPoint fCenter;
|
||||||
SkScalar fRadius;
|
SkScalar fRadius;
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
@ -56,8 +56,9 @@ GrFragmentProcessor* CircleEffect::Create(GrPrimitiveEdgeType edgeType, const Sk
|
|||||||
return SkNEW_ARGS(CircleEffect, (edgeType, center, radius));
|
return SkNEW_ARGS(CircleEffect, (edgeType, center, radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void CircleEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& CircleEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& CircleEffect::getFactory() const {
|
||||||
@ -204,8 +205,6 @@ public:
|
|||||||
|
|
||||||
typedef GLEllipseEffect GLProcessor;
|
typedef GLEllipseEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -213,6 +212,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
SkPoint fCenter;
|
SkPoint fCenter;
|
||||||
SkVector fRadii;
|
SkVector fRadii;
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
@ -230,8 +231,9 @@ GrFragmentProcessor* EllipseEffect::Create(GrPrimitiveEdgeType edgeType,
|
|||||||
return SkNEW_ARGS(EllipseEffect, (edgeType, center, rx, ry));
|
return SkNEW_ARGS(EllipseEffect, (edgeType, center, rx, ry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EllipseEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void EllipseEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& EllipseEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& EllipseEffect::getFactory() const {
|
||||||
|
@ -59,8 +59,6 @@ public:
|
|||||||
|
|
||||||
typedef GLCircularRRectEffect GLProcessor;
|
typedef GLCircularRRectEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -68,6 +66,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
SkRRect fRRect;
|
SkRRect fRRect;
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
uint32_t fCircularCornerFlags;
|
uint32_t fCircularCornerFlags;
|
||||||
@ -86,8 +86,9 @@ GrFragmentProcessor* CircularRRectEffect::Create(GrPrimitiveEdgeType edgeType,
|
|||||||
return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect));
|
return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void CircularRRectEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& CircularRRectEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& CircularRRectEffect::getFactory() const {
|
||||||
@ -399,8 +400,6 @@ public:
|
|||||||
|
|
||||||
typedef GLEllipticalRRectEffect GLProcessor;
|
typedef GLEllipticalRRectEffect GLProcessor;
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -408,6 +407,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
SkRRect fRRect;
|
SkRRect fRRect;
|
||||||
GrPrimitiveEdgeType fEdgeType;
|
GrPrimitiveEdgeType fEdgeType;
|
||||||
|
|
||||||
@ -424,8 +425,9 @@ EllipticalRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect
|
|||||||
return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect));
|
return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void EllipticalRRectEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& EllipticalRRectEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& EllipticalRRectEffect::getFactory() const {
|
||||||
|
@ -41,8 +41,9 @@ private:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
void GrSimpleTextureEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
|
||||||
this->updateConstantColorComponentsForModulation(color, validFlags);
|
this->updateInvariantOutputForModulation(inout);
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFragmentProcessorFactory& GrSimpleTextureEffect::getFactory() const {
|
const GrBackendFragmentProcessorFactory& GrSimpleTextureEffect::getFactory() const {
|
||||||
|
@ -49,8 +49,6 @@ public:
|
|||||||
|
|
||||||
static const char* Name() { return "Texture"; }
|
static const char* Name() { return "Texture"; }
|
||||||
|
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
typedef GrGLSimpleTextureEffect GLProcessor;
|
typedef GrGLSimpleTextureEffect GLProcessor;
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
@ -75,6 +73,8 @@ private:
|
|||||||
return this->hasSameTextureParamsMatrixAndSourceCoords(ste);
|
return this->hasSameTextureParamsMatrixAndSourceCoords(ste);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
typedef GrSingleTextureEffect INHERITED;
|
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
|
* the subclass output color will be a modulation of the input color with a value read from the
|
||||||
* texture.
|
* texture.
|
||||||
*/
|
*/
|
||||||
void updateConstantColorComponentsForModulation(GrColor* color, uint32_t* validFlags) const {
|
void updateInvariantOutputForModulation(InvariantOutput* inout) const {
|
||||||
if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
|
if (inout->isOpaque() && GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
||||||
GrPixelConfigIsOpaque(this->texture(0)->config())) {
|
inout->fValidFlags = kA_GrColorComponentFlag;
|
||||||
*validFlags = kA_GrColorComponentFlag;
|
|
||||||
} else {
|
} else {
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,12 +269,13 @@ bool GrTextureDomainEffect::onIsEqual(const GrProcessor& sBase) const {
|
|||||||
this->fTextureDomain == s.fTextureDomain;
|
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
|
if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper
|
||||||
*validFlags = 0;
|
inout->fValidFlags = 0;
|
||||||
} else {
|
} else {
|
||||||
this->updateConstantColorComponentsForModulation(color, validFlags);
|
this->updateInvariantOutputForModulation(inout);
|
||||||
}
|
}
|
||||||
|
inout->fIsSingleComponent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -159,7 +159,6 @@ public:
|
|||||||
typedef GrGLTextureDomainEffect GLProcessor;
|
typedef GrGLTextureDomainEffect GLProcessor;
|
||||||
|
|
||||||
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
|
||||||
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
|
||||||
|
|
||||||
const GrTextureDomain& textureDomain() const { return fTextureDomain; }
|
const GrTextureDomain& textureDomain() const { return fTextureDomain; }
|
||||||
|
|
||||||
@ -176,6 +175,8 @@ private:
|
|||||||
|
|
||||||
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE;
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||||
|
|
||||||
typedef GrSingleTextureEffect INHERITED;
|
typedef GrSingleTextureEffect INHERITED;
|
||||||
|
@ -28,13 +28,6 @@ public:
|
|||||||
return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::getInstance();
|
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 {
|
SkYUVColorSpace getColorSpace() const {
|
||||||
return fColorSpace;
|
return fColorSpace;
|
||||||
}
|
}
|
||||||
@ -117,6 +110,13 @@ private:
|
|||||||
fColorSpace == s.getColorSpace();
|
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;
|
GrCoordTransform fCoordTransform;
|
||||||
GrTextureAccess fYAccess;
|
GrTextureAccess fYAccess;
|
||||||
GrTextureAccess fUAccess;
|
GrTextureAccess fUAccess;
|
||||||
|
@ -99,12 +99,14 @@ static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrCont
|
|||||||
const GetConstantComponentTestCase& test = filterTests[i];
|
const GetConstantComponentTestCase& test = filterTests[i];
|
||||||
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
|
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
|
||||||
SkAutoTUnref<GrFragmentProcessor> effect(cf->asFragmentProcessor(grContext));
|
SkAutoTUnref<GrFragmentProcessor> effect(cf->asFragmentProcessor(grContext));
|
||||||
GrColor color = test.inputColor;
|
GrProcessor::InvariantOutput inout;
|
||||||
uint32_t components = test.inputComponents;
|
inout.fColor = test.inputColor;
|
||||||
effect->getConstantColorComponents(&color, &components);
|
inout.fValidFlags = test.inputComponents;
|
||||||
|
inout.fIsSingleComponent = false;
|
||||||
|
effect->computeInvariantOutput(&inout);
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, filterColor(color, components) == test.outputColor);
|
REPORTER_ASSERT(reporter, filterColor(inout.fColor, inout.fValidFlags) == test.outputColor);
|
||||||
REPORTER_ASSERT(reporter, test.outputComponents == components);
|
REPORTER_ASSERT(reporter, test.outputComponents == inout.fValidFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user