#if SK_SUPPORT_GPU
#include "GrContext.h"
-#include "effects/GrSingleTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
#include "SkColorPriv.h"
#include "SkDevice.h"
SkMatrix tm;
tm = vm;
tm.postIDiv(2*S, 2*S);
- paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(texture, tm))->unref();
+ paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(texture, tm))->unref();
ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S));
'<(skia_src_path)/gpu/effects/GrConfigConversionEffect.h',
'<(skia_src_path)/gpu/effects/GrConvolutionEffect.cpp',
'<(skia_src_path)/gpu/effects/GrConvolutionEffect.h',
+ '<(skia_src_path)/gpu/effects/GrSimpleTextureEffect.cpp',
+ '<(skia_src_path)/gpu/effects/GrSimpleTextureEffect.h',
'<(skia_src_path)/gpu/effects/GrSingleTextureEffect.cpp',
'<(skia_src_path)/gpu/effects/GrSingleTextureEffect.h',
'<(skia_src_path)/gpu/effects/GrTextureDomainEffect.cpp',
*/
virtual const GrBackendEffectFactory& getFactory() const = 0;
- /** Returns true if the other effect will generate identical output.
- Must only be called if the two are already known to be of the
- same type (i.e. they return the same value from getFactory()).
-
- Equality is not the same thing as equivalence.
- To test for equivalence (that they will generate the same
- shader code, but may have different uniforms), check equality
- of the EffectKey produced by the GrBackendEffectFactory:
- a.getFactory().glEffectKey(a) == b.getFactory().glEffectKey(b).
-
- The default implementation of this function returns true iff
- the two stages have the same return value for numTextures() and
- for texture() over all valid indices.
+ /** Returns true if this and other effect conservatively draw identically. It can only return
+ true when the two effects are of the same subclass (i.e. they return the same object from
+ from getFactory()).
+
+ A return value of true from isEqual() should not be used to test whether the effects would
+ generate the same shader code. To test for identical code generation use the EffectKey
+ computed by the GrBackendEffectFactory:
+ effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
*/
- virtual bool isEqual(const GrEffect&) const;
+ bool isEqual(const GrEffect& other) const {
+ if (&this->getFactory() != &other.getFactory()) {
+ return false;
+ }
+ bool result = this->onIsEqual(other);
+#if GR_DEBUG
+ if (result) {
+ GrAssert(this->numTextures() == other.numTextures());
+ for (int i = 0; i < this->numTextures(); ++i) {
+ GrAssert(*fTextureAccesses[i] == *other.fTextureAccesses[i]);
+ }
+ }
+#endif
+ return result;
+ }
/** Human-meaningful string to identify this effect; may be embedded
in generated shader code. */
}
private:
+
+ /** Subclass implements this to support isEqual(). It will only be called if it is known that
+ the two effects are of the same subclass (i.e. they return the same object
+ from getFactory()).*/
+ virtual bool onIsEqual(const GrEffect& other) const = 0;
+
void EffectRefDestroyed() {
fEffectRef = NULL;
}
return false;
}
- if (this->getEffect()->getFactory() != other.getEffect()->getFactory()) {
- return false;
- }
-
if (!this->getEffect()->isEqual(*other.getEffect())) {
return false;
}
#if SK_SUPPORT_GPU
#include "GrTextureAccess.h"
-#include "effects/GrSingleTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
#include "SkGr.h"
GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
return NULL;
}
- GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix, params);
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
GrUnlockCachedBitmapTexture(texture);
return effect;
}
virtual ~GrBlendEffect();
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
const GrBackendEffectFactory& getFactory() const;
SkBlendImageFilter::Mode mode() const { return fMode; }
void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTexture* background);
GrTextureAccess fForegroundAccess;
GrTextureAccess fBackgroundAccess;
GrBlendEffect::~GrBlendEffect() {
}
-bool GrBlendEffect::isEqual(const GrEffect& sBase) const {
+bool GrBlendEffect::onIsEqual(const GrEffect& sBase) const {
const GrBlendEffect& s = static_cast<const GrBlendEffect&>(sBase);
- return INHERITED::isEqual(sBase) && fMode == s.fMode;
+ return fForegroundAccess.getTexture() == s.fForegroundAccess.getTexture() &&
+ fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture() &&
+ fMode == s.fMode;
}
const GrBackendEffectFactory& GrBlendEffect::getFactory() const {
return GrTBackendEffectFactory<ColorMatrixEffect>::getInstance();
}
- virtual bool isEqual(const GrEffect& s) const {
- const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(s);
- return cme.fMatrix == fMatrix;
- }
-
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
private:
ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {}
+ virtual bool onIsEqual(const GrEffect& s) const {
+ const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(s);
+ return cme.fMatrix == fMatrix;
+ }
+
SkColorMatrix fMatrix;
typedef GrGLEffect INHERITED;
virtual ~GrDisplacementMapEffect();
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
const GrBackendEffectFactory& getFactory() const;
SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
{ return fXChannelSelector; }
void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
SkScalar scale, GrTexture* displacement, GrTexture* color);
GrDisplacementMapEffect::~GrDisplacementMapEffect() {
}
-bool GrDisplacementMapEffect::isEqual(const GrEffect& sBase) const {
+bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const {
const GrDisplacementMapEffect& s = static_cast<const GrDisplacementMapEffect&>(sBase);
- return INHERITED::isEqual(sBase) && fXChannelSelector == s.fXChannelSelector &&
- fYChannelSelector == s.fYChannelSelector && fScale == s.fScale;
+ return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture() &&
+ fColorAccess.getTexture() == s.fColorAccess.getTexture() &&
+ fXChannelSelector == s.fXChannelSelector &&
+ fYChannelSelector == s.fYChannelSelector &&
+ fScale == s.fScale;
}
const GrBackendEffectFactory& GrDisplacementMapEffect::getFactory() const {
GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale);
virtual ~GrLightingEffect();
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
-
const SkLight* light() const { return fLight; }
SkScalar surfaceScale() const { return fSurfaceScale; }
*validFlags = 0;
}
+protected:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
private:
typedef GrSingleTextureEffect INHERITED;
const SkLight* fLight;
typedef GrGLDiffuseLightingEffect GLEffect;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
SkScalar kd() const { return fKD; }
+
private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GrDiffuseLightingEffect(GrTexture* texture,
const SkLight* light,
SkScalar surfaceScale,
typedef GrGLSpecularLightingEffect GLEffect;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
SkScalar ks() const { return fKS; }
SkScalar shininess() const { return fShininess; }
private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GrSpecularLightingEffect(GrTexture* texture,
const SkLight* light,
SkScalar surfaceScale,
fLight->unref();
}
-bool GrLightingEffect::isEqual(const GrEffect& sBase) const {
- const GrLightingEffect& s =
- static_cast<const GrLightingEffect&>(sBase);
- return INHERITED::isEqual(sBase) &&
+bool GrLightingEffect::onIsEqual(const GrEffect& sBase) const {
+ const GrLightingEffect& s = static_cast<const GrLightingEffect&>(sBase);
+ return this->texture(0) == s.texture(0) &&
fLight->isEqual(*s.fLight) &&
fSurfaceScale == s.fSurfaceScale;
}
return GrTBackendEffectFactory<GrDiffuseLightingEffect>::getInstance();
}
-bool GrDiffuseLightingEffect::isEqual(const GrEffect& sBase) const {
+bool GrDiffuseLightingEffect::onIsEqual(const GrEffect& sBase) const {
const GrDiffuseLightingEffect& s =
static_cast<const GrDiffuseLightingEffect&>(sBase);
- return INHERITED::isEqual(sBase) &&
+ return INHERITED::onIsEqual(sBase) &&
this->kd() == s.kd();
}
return GrTBackendEffectFactory<GrSpecularLightingEffect>::getInstance();
}
-bool GrSpecularLightingEffect::isEqual(const GrEffect& sBase) const {
+bool GrSpecularLightingEffect::onIsEqual(const GrEffect& sBase) const {
const GrSpecularLightingEffect& s =
static_cast<const GrSpecularLightingEffect&>(sBase);
- return INHERITED::isEqual(sBase) &&
+ return INHERITED::onIsEqual(sBase) &&
this->ks() == s.ks() &&
this->shininess() == s.shininess();
}
static const char* Name() { return "Magnifier"; }
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
float x_offset() const { return fXOffset; }
float y_offset() const { return fYOffset; }
, fXInset(xInset)
, fYInset(yInset) {}
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GR_DECLARE_EFFECT_TEST;
float fXOffset;
return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance();
}
-bool GrMagnifierEffect::isEqual(const GrEffect& sBase) const {
- const GrMagnifierEffect& s =
- static_cast<const GrMagnifierEffect&>(sBase);
- return (this->fXOffset == s.fXOffset &&
+bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const {
+ const GrMagnifierEffect& s = static_cast<const GrMagnifierEffect&>(sBase);
+ return (this->texture(0) == s.texture(0) &&
+ this->fXOffset == s.fXOffset &&
this->fYOffset == s.fYOffset &&
this->fXZoom == s.fXZoom &&
this->fYZoom == s.fYZoom &&
this->fYInset == s.fYInset);
}
+void GrMagnifierEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+ this->updateConstantColorComponentsForModulation(color, validFlags);
+}
+
#endif
////////////////////////////////////////////////////////////////////////////////
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
private:
GrMatrixConvolutionEffect(GrTexture*,
TileMode tileMode,
bool convolveAlpha);
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
SkISize fKernelSize;
float *fKernel;
float fGain;
return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance();
}
-bool GrMatrixConvolutionEffect::isEqual(const GrEffect& sBase) const {
+bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
const GrMatrixConvolutionEffect& s =
static_cast<const GrMatrixConvolutionEffect&>(sBase);
- return INHERITED::isEqual(sBase) &&
+ return this->texture(0) == s.texture(0) &&
fKernelSize == s.kernelSize() &&
!memcmp(fKernel, s.kernel(), fKernelSize.width() * fKernelSize.height() * sizeof(float)) &&
fGain == s.gain() &&
typedef GrGLMorphologyEffect GLEffect;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
protected:
MorphologyType fType;
private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
GR_DECLARE_EFFECT_TEST;
return GrTBackendEffectFactory<GrMorphologyEffect>::getInstance();
}
-bool GrMorphologyEffect::isEqual(const GrEffect& sBase) const {
+bool GrMorphologyEffect::onIsEqual(const GrEffect& sBase) const {
const GrMorphologyEffect& s =
static_cast<const GrMorphologyEffect&>(sBase);
- return (INHERITED::isEqual(sBase) &&
+ return (this->texture(0) == s.texture(0) &&
this->radius() == s.radius() &&
this->direction() == s.direction() &&
this->type() == s.type());
}
+void GrMorphologyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+ // This is valid because the color components of the result of the kernel all come
+ // exactly from existing values in the source texture.
+ this->updateConstantColorComponentsForModulation(color, validFlags);
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_EFFECT_TEST(GrMorphologyEffect);
static const char* Name() { return "ColorTable"; }
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
typedef GLColorTableEffect GLEffect;
private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
explicit ColorTableEffect(GrTexture* texture, unsigned flags);
GR_DECLARE_EFFECT_TEST;
return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
}
-bool ColorTableEffect::isEqual(const GrEffect& sBase) const {
- return INHERITED::isEqual(sBase);
+bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
+ return this->texture(0) == sBase.texture(0);
}
void ColorTableEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
}
}
+bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
+ const GrGradientEffect& s = static_cast<const GrGradientEffect&>(effect);
+ return fTextureAccess.getTexture() == s.fTextureAccess.getTexture() &&
+ fTextureAccess.getParams().getTileModeX() ==
+ s.fTextureAccess.getParams().getTileModeX() &&
+ this->useAtlas() == s.useAtlas() &&
+ fYCoord == s.getYCoord() &&
+ fMatrix.cheapEqualTo(s.getMatrix());
+}
+
+void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+ if (fIsOpaque && (kA_ValidComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) {
+ *validFlags = kA_ValidComponentFlag;
+ } else {
+ *validFlags = 0;
+ }
+}
+
int GrGradientEffect::RandomGradientParams(SkRandom* random,
SkColor colors[],
SkScalar** stops,
SkScalar getYCoord() const { return fYCoord; };
const SkMatrix& getMatrix() const { return fMatrix;}
- virtual bool isEqual(const GrEffect& effect) const SK_OVERRIDE {
- const GrGradientEffect& s = static_cast<const GrGradientEffect&>(effect);
- return INHERITED::isEqual(effect) && this->useAtlas() == s.useAtlas() &&
- fYCoord == s.getYCoord() && fMatrix.cheapEqualTo(s.getMatrix());
- }
-
- virtual void getConstantColorComponents(GrColor* color,
- uint32_t* validFlags) const SK_OVERRIDE {
- if (fIsOpaque && (kA_ValidComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) {
- *validFlags = kA_ValidComponentFlag;
- } else {
- *validFlags = 0;
- }
- }
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
protected:
SkScalar** stops,
SkShader::TileMode* tm);
+ virtual bool onIsEqual(const GrEffect& effect) const SK_OVERRIDE;
+
private:
+
GrTextureAccess fTextureAccess;
SkScalar fYCoord;
GrTextureStripAtlas* fAtlas;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
return GrTBackendEffectFactory<GrConical2Gradient>::getInstance();
}
- virtual bool isEqual(const GrEffect& sBase) const SK_OVERRIDE {
- const GrConical2Gradient& s = static_cast<const GrConical2Gradient&>(sBase);
- return (INHERITED::isEqual(sBase) &&
- this->fCenterX1 == s.fCenterX1 &&
- this->fRadius0 == s.fRadius0 &&
- this->fDiffRadius == s.fDiffRadius);
- }
// The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(fCenterX1); }
typedef GrGLConical2Gradient GLEffect;
private:
+ virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
+ const GrConical2Gradient& s = static_cast<const GrConical2Gradient&>(sBase);
+ return (INHERITED::onIsEqual(sBase) &&
+ this->fCenterX1 == s.fCenterX1 &&
+ this->fRadius0 == s.fRadius0 &&
+ this->fDiffRadius == s.fDiffRadius);
+ }
+
GrConical2Gradient(GrContext* ctx,
const SkTwoPointConicalGradient& shader,
const SkMatrix& matrix,
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
return GrTBackendEffectFactory<GrRadial2Gradient>::getInstance();
}
- virtual bool isEqual(const GrEffect& sBase) const SK_OVERRIDE {
- const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
- return (INHERITED::isEqual(sBase) &&
- this->fCenterX1 == s.fCenterX1 &&
- this->fRadius0 == s.fRadius0 &&
- this->fPosRoot == s.fPosRoot);
- }
// The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
bool isDegenerate() const { return SK_Scalar1 == fCenterX1; }
typedef GrGLRadial2Gradient GLEffect;
private:
+ virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
+ const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
+ return (INHERITED::isEqual(sBase) &&
+ this->fCenterX1 == s.fCenterX1 &&
+ this->fRadius0 == s.fRadius0 &&
+ this->fPosRoot == s.fPosRoot);
+ }
+
GrRadial2Gradient(GrContext* ctx,
const SkTwoPointRadialGradient& shader,
const SkMatrix& matrix,
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
i < scaleFactorY ? 0.5f : 1.0f);
- paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(srcTexture,
+ paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture,
matrix,
true))->unref();
this->drawRectToRect(paint, dstRect, srcRect);
// FIXME: This should be mitchell, not bilinear.
matrix.setIDiv(srcTexture->width(), srcTexture->height());
this->setRenderTarget(dstTexture->asRenderTarget());
- paint.colorStage(0)->setEffect(GrSingleTextureEffect::Create(srcTexture,
+ paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture,
matrix,
true))->unref();
SkRect dstRect(srcRect);
#include "GrStencil.h"
#include "GrTexture.h"
#include "GrRenderTarget.h"
-#include "effects/GrSingleTextureEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
#include "SkXfermode.h"
////
/**
- * Creates a GrSingleTextureEffect.
+ * Creates a GrSimpleTextureEffect.
*/
void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
GrAssert(!this->getStage(stageIdx).getEffect());
- GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix);
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
this->stage(stageIdx)->setEffect(effect)->unref();
}
void createTextureEffect(int stageIdx,
const SkMatrix& matrix,
const GrTextureParams& params) {
GrAssert(!this->getStage(stageIdx).getEffect());
- GrEffectRef* effect = GrSingleTextureEffect::Create(texture, matrix, params);
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
this->stage(stageIdx)->setEffect(effect)->unref();
}
return this->getFactory().name();
}
-bool GrEffect::isEqual(const GrEffect& s) const {
- if (this->numTextures() != s.numTextures()) {
- return false;
- }
- for (int i = 0; i < this->numTextures(); ++i) {
- if (this->textureAccess(i) != s.textureAccess(i)) {
- return false;
- }
- }
- return true;
-}
-
void GrEffect::addTextureAccess(const GrTextureAccess* access) {
fTextureAccesses.push_back(access);
}
#include "SkGpuDevice.h"
#include "effects/GrTextureDomainEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
#include "GrContext.h"
#include "GrTextContext.h"
GrTexture* texture = fRenderTarget->asTexture();
if (NULL != texture) {
paint->colorStage(kBitmapTextureIdx)->setEffect(
- GrSingleTextureEffect::Create(texture, SkMatrix::I()))->unref();
+ GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref();
return true;
}
return false;
// Blend pathTexture over blurTexture.
context->setRenderTarget(blurTexture->asRenderTarget());
paint.colorStage(0)->setEffect(
- GrSingleTextureEffect::Create(pathTexture, matrix))->unref();
+ GrSimpleTextureEffect::Create(pathTexture, matrix))->unref();
if (SkMaskFilter::kInner_BlurType == blurType) {
// inner: dst = dst * src
paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
grp->coverageStage(MASK_IDX)->reset();
grp->coverageStage(MASK_IDX)->setEffect(
- GrSingleTextureEffect::Create(blurTexture, matrix))->unref();
+ GrSimpleTextureEffect::Create(blurTexture, matrix))->unref();
context->drawRect(*grp, finalRect);
return true;
}
m.setTranslate(-dstM.fBounds.fLeft*SK_Scalar1, -dstM.fBounds.fTop*SK_Scalar1);
m.postIDiv(texture->width(), texture->height());
- grp->coverageStage(MASK_IDX)->setEffect(GrSingleTextureEffect::Create(texture, m))->unref();
+ grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(texture, m))->unref();
GrRect d;
d.setLTRB(SkIntToScalar(dstM.fBounds.fLeft),
SkIntToScalar(dstM.fBounds.fTop),
GrTextureDomainEffect::kClamp_WrapMode,
params.isBilerp()));
} else {
- effect.reset(GrSingleTextureEffect::Create(texture, SkMatrix::I(), params));
+ effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
}
grPaint->colorStage(kBitmapTextureIdx)->setEffect(effect);
fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
// draw sprite uses the default texture params
SkAutoCachedTexture act(this, bitmap, NULL, &texture);
grPaint.colorStage(kBitmapTextureIdx)->setEffect(
- GrSingleTextureEffect::Create(texture, SkMatrix::I()))->unref();
+ GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref();
SkImageFilter* filter = paint.getImageFilter();
if (NULL != filter) {
GrRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)));
if (filteredTexture) {
grPaint.colorStage(kBitmapTextureIdx)->setEffect(
- GrSingleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
+ GrSimpleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
texture = filteredTexture;
filteredTexture->unref();
}
GrTexture* filteredTexture = filter_texture(this, fContext, devTex, filter, rect);
if (filteredTexture) {
grPaint.colorStage(kBitmapTextureIdx)->setEffect(
- GrSingleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
+ GrSimpleTextureEffect::Create(filteredTexture, SkMatrix::I()))->unref();
devTex = filteredTexture;
filteredTexture->unref();
}
#include "GrConfigConversionEffect.h"
#include "GrContext.h"
#include "GrTBackendEffectFactory.h"
+#include "GrSimpleTextureEffect.h"
#include "gl/GrGLEffect.h"
#include "gl/GrGLEffectMatrix.h"
#include "SkMatrix.h"
return GrTBackendEffectFactory<GrConfigConversionEffect>::getInstance();
}
-bool GrConfigConversionEffect::isEqual(const GrEffect& s) const {
+bool GrConfigConversionEffect::onIsEqual(const GrEffect& s) const {
const GrConfigConversionEffect& other = static_cast<const GrConfigConversionEffect&>(s);
- return other.fSwapRedAndBlue == fSwapRedAndBlue && other.fPMConversion == fPMConversion;
+ return this->texture(0) == s.texture(0) &&
+ other.fSwapRedAndBlue == fSwapRedAndBlue &&
+ other.fPMConversion == fPMConversion;
+}
+
+void GrConfigConversionEffect::getConstantColorComponents(GrColor* color,
+ uint32_t* validFlags) const {
+ this->updateConstantColorComponentsForModulation(color, validFlags);
}
///////////////////////////////////////////////////////////////////////////////
// If we returned a GrConfigConversionEffect that was equivalent to a GrSingleTextureEffect
// then we may pollute our texture cache with redundant shaders. So in the case that no
// conversions were requested we instead return a GrSingleTextureEffect.
- stage->setEffect(GrSingleTextureEffect::Create(texture, matrix))->unref();
+ stage->setEffect(GrSimpleTextureEffect::Create(texture, matrix))->unref();
return true;
} else {
if (kRGBA_8888_GrPixelConfig != texture->config() &&
typedef GrGLConfigConversionEffect GLEffect;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
bool swapsRedAndBlue() const { return fSwapRedAndBlue; }
PMConversion pmConversion() const { return fPMConversion; }
PMConversion pmConversion,
const SkMatrix& matrix);
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
bool fSwapRedAndBlue;
PMConversion fPMConversion;
return GrTBackendEffectFactory<GrConvolutionEffect>::getInstance();
}
-bool GrConvolutionEffect::isEqual(const GrEffect& sBase) const {
- const GrConvolutionEffect& s =
- static_cast<const GrConvolutionEffect&>(sBase);
- return (INHERITED::isEqual(sBase) &&
+bool GrConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
+ const GrConvolutionEffect& s = static_cast<const GrConvolutionEffect&>(sBase);
+ return (this->texture(0) == s.texture(0) &&
this->radius() == s.radius() &&
this->direction() == s.direction() &&
0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
typedef GrGLConvolutionEffect GLEffect;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+ // If the texture was opaque we could know that the output color if we knew the sum of the
+ // kernel values.
+ *validFlags = 0;
+ }
enum {
// This was decided based on the min allowed value for the max texture
int halfWidth,
float gaussianSigma);
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GR_DECLARE_EFFECT_TEST;
typedef Gr1DKernelEffect INHERITED;
--- /dev/null
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrSimpleTextureEffect.h"
+#include "gl/GrGLEffect.h"
+#include "gl/GrGLEffectMatrix.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLTexture.h"
+#include "GrTBackendEffectFactory.h"
+#include "GrTexture.h"
+
+class GrGLSimpleTextureEffect : public GrGLEffect {
+public:
+ GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
+ : INHERITED (factory) {}
+
+ virtual void emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey key,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) SK_OVERRIDE {
+ const char* coordName;
+ GrSLType coordType = fEffectMatrix.emitCode(builder, key, vertexCoords, &coordName);
+ builder->fFSCode.appendf("\t%s = ", outputColor);
+ builder->appendTextureLookupAndModulate(&builder->fFSCode,
+ inputColor,
+ samplers[0],
+ coordName,
+ coordType);
+ builder->fFSCode.append(";\n");
+ }
+
+ static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
+ const GrSimpleTextureEffect& ste =
+ static_cast<const GrSimpleTextureEffect&>(*stage.getEffect());
+ return GrGLEffectMatrix::GenKey(ste.getMatrix(),
+ stage.getCoordChangeMatrix(),
+ ste.texture(0));
+ }
+
+ virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
+ const GrSimpleTextureEffect& ste =
+ static_cast<const GrSimpleTextureEffect&>(*stage.getEffect());
+ fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
+ }
+
+private:
+ GrGLEffectMatrix fEffectMatrix;
+ typedef GrGLEffect INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+ this->updateConstantColorComponentsForModulation(color, validFlags);
+}
+
+const GrBackendEffectFactory& GrSimpleTextureEffect::getFactory() const {
+ return GrTBackendEffectFactory<GrSimpleTextureEffect>::getInstance();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_EFFECT_TEST(GrSimpleTextureEffect);
+
+GrEffectRef* GrSimpleTextureEffect::TestCreate(SkRandom* random,
+ GrContext* context,
+ GrTexture* textures[]) {
+ int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
+ GrEffectUnitTest::kAlphaTextureIdx;
+ const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
+ return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
+}
--- /dev/null
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSimpleTextureEffect_DEFINED
+#define GrSimpleTextureEffect_DEFINED
+
+#include "GrSingleTextureEffect.h"
+
+class GrGLSimpleTextureEffect;
+
+/**
+ * The output color of this effect is a modulation of the input color and a sample from a texture.
+ * The coord to sample the texture is determine by a matrix. It allows explicit specification of
+ * the filtering and wrap modes (GrTextureParams).
+ */
+class GrSimpleTextureEffect : public GrSingleTextureEffect {
+public:
+ /* unfiltered, clamp mode */
+ static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
+ SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix)));
+ return CreateEffectRef(effect);
+ }
+
+ /* clamp mode */
+ static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
+ SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp)));
+ return CreateEffectRef(effect);
+ }
+
+ static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
+ SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p)));
+ return CreateEffectRef(effect);
+ }
+
+ virtual ~GrSimpleTextureEffect() {}
+
+ static const char* Name() { return "Texture"; }
+
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
+
+ typedef GrGLSimpleTextureEffect GLEffect;
+
+ virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+
+private:
+ GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix)
+ : GrSingleTextureEffect(texture, matrix) {}
+ GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, bool bilerp)
+ : GrSingleTextureEffect(texture, matrix, bilerp) {}
+ GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params)
+ : GrSingleTextureEffect(texture, matrix, params) {}
+
+ virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
+ const GrSimpleTextureEffect& ste = static_cast<const GrSimpleTextureEffect&>(other);
+ return this->hasSameTextureParamsAndMatrix(ste);
+ }
+
+ GR_DECLARE_EFFECT_TEST;
+
+ typedef GrSingleTextureEffect INHERITED;
+};
+
+#endif
*/
#include "effects/GrSingleTextureEffect.h"
-#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
-#include "gl/GrGLSL.h"
-#include "gl/GrGLTexture.h"
-#include "GrTBackendEffectFactory.h"
-#include "GrTexture.h"
-
-class GrGLSingleTextureEffect : public GrGLEffect {
-public:
- GrGLSingleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
- : INHERITED (factory) {}
-
- virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage&,
- EffectKey key,
- const char* vertexCoords,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) SK_OVERRIDE {
- const char* coordName;
- GrSLType coordType = fEffectMatrix.emitCode(builder, key, vertexCoords, &coordName);
- builder->fFSCode.appendf("\t%s = ", outputColor);
- builder->appendTextureLookupAndModulate(&builder->fFSCode,
- inputColor,
- samplers[0],
- coordName,
- coordType);
- builder->fFSCode.append(";\n");
- }
-
- static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
- const GrSingleTextureEffect& ste =
- static_cast<const GrSingleTextureEffect&>(*stage.getEffect());
- return GrGLEffectMatrix::GenKey(ste.getMatrix(),
- stage.getCoordChangeMatrix(),
- ste.texture(0));
- }
-
- virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
- const GrSingleTextureEffect& ste =
- static_cast<const GrSingleTextureEffect&>(*stage.getEffect());
- fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
- }
-
-private:
- GrGLEffectMatrix fEffectMatrix;
- typedef GrGLEffect INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, const SkMatrix& m)
: fTextureAccess(texture)
GrSingleTextureEffect::~GrSingleTextureEffect() {
}
-
-void GrSingleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
- // If the input alpha is 0xff and the texture has no alpha channel, then the output alpha is
- // 0xff
- if ((*validFlags & kA_ValidComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
- GrPixelConfigIsOpaque(fTextureAccess.getTexture()->config())) {
- *validFlags = kA_ValidComponentFlag;
- } else {
- *validFlags = 0;
- }
-}
-
-const GrBackendEffectFactory& GrSingleTextureEffect::getFactory() const {
- return GrTBackendEffectFactory<GrSingleTextureEffect>::getInstance();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GR_DEFINE_EFFECT_TEST(GrSingleTextureEffect);
-
-GrEffectRef* GrSingleTextureEffect::TestCreate(SkRandom* random,
- GrContext* context,
- GrTexture* textures[]) {
- int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
- GrEffectUnitTest::kAlphaTextureIdx;
- const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
- return GrSingleTextureEffect::Create(textures[texIdx], matrix);
-}
#include "GrEffect.h"
#include "SkMatrix.h"
-class GrGLSingleTextureEffect;
class GrTexture;
/**
- * An effect that draws a single texture with a texture matrix; commonly used as a base class. The
- * output color is the texture color is modulated against the input color.
+ * A base class for effects that draw a single texture with a texture matrix.
*/
class GrSingleTextureEffect : public GrEffect {
public:
- /* unfiltered, clamp mode */
- static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
- SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix)));
- return CreateEffectRef(effect);
- }
-
- /* clamp mode */
- static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
- SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix, bilerp)));
- return CreateEffectRef(effect);
- }
-
- static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
- SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSingleTextureEffect, (tex, matrix, p)));
- return CreateEffectRef(effect);
- }
-
virtual ~GrSingleTextureEffect();
- static const char* Name() { return "Single Texture"; }
-
- /** Note that if this class is sub-classed, the subclass may have to override this function.
- */
- virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
-
const SkMatrix& getMatrix() const { return fMatrix; }
- typedef GrGLSingleTextureEffect GLEffect;
-
- virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-
- virtual bool isEqual(const GrEffect& effect) const SK_OVERRIDE {
- const GrSingleTextureEffect& ste = static_cast<const GrSingleTextureEffect&>(effect);
- return INHERITED::isEqual(effect) && fMatrix.cheapEqualTo(ste.getMatrix());
- }
-
protected:
GrSingleTextureEffect(GrTexture*, const SkMatrix&); /* unfiltered, clamp mode */
GrSingleTextureEffect(GrTexture*, const SkMatrix&, bool bilerp); /* clamp mode */
GrSingleTextureEffect(GrTexture*, const SkMatrix&, const GrTextureParams&);
-private:
+ /**
+ * Helper for subclass onIsEqual() functions.
+ */
+ bool hasSameTextureParamsAndMatrix(const GrSingleTextureEffect& other) const {
+ const GrTextureAccess& otherAccess = other.fTextureAccess;
+ // We don't have to check the accesses' swizzles because they are inferred from the texture.
+ return fTextureAccess.getTexture() == otherAccess.getTexture() &&
+ fTextureAccess.getParams() == otherAccess.getParams() &&
+ this->getMatrix().cheapEqualTo(other.getMatrix());
+ }
- GR_DECLARE_EFFECT_TEST;
+ /**
+ * Can be used as a helper to implement subclass getConstantColorComponents(). It assumes that
+ * the subclass output color will be a modulation of the input color with a value read from the
+ * texture.
+ */
+ void updateConstantColorComponentsForModulation(GrColor* color, uint32_t* validFlags) const {
+ if ((*validFlags & kA_ValidComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
+ GrPixelConfigIsOpaque(this->texture(0)->config())) {
+ *validFlags = kA_ValidComponentFlag;
+ } else {
+ *validFlags = 0;
+ }
+ }
+private:
GrTextureAccess fTextureAccess;
SkMatrix fMatrix;
*/
#include "GrTextureDomainEffect.h"
+#include "GrSimpleTextureEffect.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
#include "gl/GrGLEffectMatrix.h"
bool bilerp) {
static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
- return GrSingleTextureEffect::Create(texture, matrix, bilerp);
+ return GrSimpleTextureEffect::Create(texture, matrix, bilerp);
} else {
SkRect clippedDomain;
// We don't currently handle domains that are empty or don't intersect the texture.
return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance();
}
-bool GrTextureDomainEffect::isEqual(const GrEffect& sBase) const {
+bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
- return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
+ return this->hasSameTextureParamsAndMatrix(s) && this->fTextureDomain == s.fTextureDomain;
+}
+
+void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+ if (kDecal_WrapMode == fWrapMode) {
+ *validFlags = 0;
+ } else {
+ this->updateConstantColorComponentsForModulation(color, validFlags);
+ }
}
///////////////////////////////////////////////////////////////////////////////
typedef GrGLTextureDomainEffect GLEffect;
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
- virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
const SkRect& domain() const { return fTextureDomain; }
WrapMode wrapMode() const { return fWrapMode; }
WrapMode,
bool bilerp);
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
GR_DECLARE_EFFECT_TEST;
typedef GrSingleTextureEffect INHERITED;