Index: src/effects/SkArithmeticMode.cpp |
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp |
index 034ea376743d614eb63360bc4ba25717459748e8..41cc2667416e34a572246874d80fc54bdbcfd8d2 100644 |
--- a/src/effects/SkArithmeticMode.cpp |
+++ b/src/effects/SkArithmeticMode.cpp |
@@ -22,8 +22,9 @@ static const bool gUseUnpremul = false; |
class SkArithmeticMode_scalar : public SkXfermode { |
public: |
- static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { |
- return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4)); |
+ static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, |
+ bool enforcePMColor) { |
+ return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, enforcePMColor)); |
} |
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, |
@@ -37,11 +38,12 @@ public: |
#endif |
private: |
- SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { |
+ SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool enforcePMColor) { |
fK[0] = k1; |
fK[1] = k2; |
fK[2] = k3; |
fK[3] = k4; |
+ fEnforcePMColor = enforcePMColor; |
} |
SkArithmeticMode_scalar(SkReadBuffer& buffer) : INHERITED(buffer) { |
@@ -49,6 +51,7 @@ private: |
fK[1] = buffer.readScalar(); |
fK[2] = buffer.readScalar(); |
fK[3] = buffer.readScalar(); |
+ fEnforcePMColor = buffer.readBool(); |
} |
virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { |
@@ -57,8 +60,10 @@ private: |
buffer.writeScalar(fK[1]); |
buffer.writeScalar(fK[2]); |
buffer.writeScalar(fK[3]); |
+ buffer.writeBool(fEnforcePMColor); |
} |
SkScalar fK[4]; |
+ bool fEnforcePMColor; |
typedef SkXfermode INHERITED; |
}; |
@@ -145,11 +150,13 @@ void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], |
} else { |
a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc)); |
r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)); |
- r = SkMin32(r, a); |
g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)); |
- g = SkMin32(g, a); |
b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)); |
- b = SkMin32(b, a); |
+ if (fEnforcePMColor) { |
+ r = SkMin32(r, a); |
+ g = SkMin32(g, a); |
+ b = SkMin32(b, a); |
+ } |
} |
// apply antialias coverage if necessary |
@@ -168,7 +175,7 @@ void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], |
g = SkAlphaMul(g, scale); |
b = SkAlphaMul(b, scale); |
} |
- dst[i] = SkPackARGB32(a, r, g, b); |
+ dst[i] = fEnforcePMColor ? SkPackARGB32(a, r, g, b) : SkPackARGB32NoCheck(a, r, g, b); |
} |
} |
} |
@@ -178,10 +185,9 @@ void SkArithmeticMode_scalar::toString(SkString* str) const { |
str->append("SkArithmeticMode_scalar: "); |
for (int i = 0; i < 4; ++i) { |
str->appendScalar(fK[i]); |
- if (i < 3) { |
- str->append(" "); |
- } |
+ str->append(" "); |
} |
+ str->appendS32(fEnforcePMColor ? 1 : 0); |
} |
#endif |
@@ -198,7 +204,8 @@ static int32_t toDot8(SkScalar x) { |
#endif |
SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, |
- SkScalar k3, SkScalar k4) { |
+ SkScalar k3, SkScalar k4, |
+ bool enforcePMColor) { |
if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && |
fitsInBits(k2, 16) && fitsInBits(k2, 24)) { |
@@ -219,7 +226,7 @@ SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, |
return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); |
#endif |
} |
- return SkArithmeticMode_scalar::Create(k1, k2, k3, k4); |
+ return SkArithmeticMode_scalar::Create(k1, k2, k3, k4, enforcePMColor); |
} |
@@ -242,8 +249,11 @@ public: |
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; |
+ static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
+ |
private: |
GrGLUniformManager::UniformHandle fKUni; |
+ bool fEnforcePMColor; |
typedef GrGLEffect INHERITED; |
}; |
@@ -252,8 +262,10 @@ private: |
class GrArithmeticEffect : public GrEffect { |
public: |
- static GrEffectRef* Create(float k1, float k2, float k3, float k4, GrTexture* background) { |
- AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, background))); |
+ static GrEffectRef* Create(float k1, float k2, float k3, float k4, bool enforcePMColor, |
+ GrTexture* background) { |
+ AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, |
+ background))); |
return CreateEffectRef(effect); |
} |
@@ -271,12 +283,15 @@ public: |
float k2() const { return fK2; } |
float k3() const { return fK3; } |
float k4() const { return fK4; } |
+ bool enforcePMColor() const { return fEnforcePMColor; } |
private: |
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
- GrArithmeticEffect(float k1, float k2, float k3, float k4, GrTexture* background); |
+ GrArithmeticEffect(float k1, float k2, float k3, float k4, bool enforcePMColor, |
+ GrTexture* background); |
float fK1, fK2, fK3, fK4; |
+ bool fEnforcePMColor; |
GrCoordTransform fBackgroundTransform; |
GrTextureAccess fBackgroundAccess; |
@@ -288,8 +303,8 @@ private: |
/////////////////////////////////////////////////////////////////////////////// |
GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, |
- GrTexture* background) |
- : fK1(k1), fK2(k2), fK3(k3), fK4(k4) { |
+ bool enforcePMColor, GrTexture* background) |
+ : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) { |
if (background) { |
fBackgroundTransform.reset(kLocal_GrCoordSet, background); |
this->addCoordTransform(&fBackgroundTransform); |
@@ -309,6 +324,7 @@ bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { |
fK2 == s.fK2 && |
fK3 == s.fK3 && |
fK4 == s.fK4 && |
+ fEnforcePMColor == s.fEnforcePMColor && |
backgroundTexture() == s.backgroundTexture(); |
} |
@@ -325,7 +341,8 @@ void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va |
GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory, |
const GrDrawEffect& drawEffect) |
- : INHERITED(factory) { |
+ : INHERITED(factory), |
+ fEnforcePMColor(true) { |
} |
GrGLArithmeticEffect::~GrGLArithmeticEffect() { |
@@ -374,7 +391,7 @@ void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, |
builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor); |
if (gUseUnpremul) { |
builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor); |
- } else { |
+ } else if (fEnforcePMColor) { |
builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor); |
} |
} |
@@ -382,6 +399,17 @@ void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, |
void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { |
const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(); |
uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); |
+ fEnforcePMColor = arith.enforcePMColor(); |
+} |
+ |
+GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffect, |
+ const GrGLCaps&) { |
+ const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(); |
+ EffectKey key = arith.enforcePMColor() ? 1 : 0; |
+ if (arith.backgroundTexture()) { |
+ key |= 2; |
+ } |
+ return key; |
} |
GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand, |
@@ -392,8 +420,10 @@ GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand, |
float k2 = rand->nextF(); |
float k3 = rand->nextF(); |
float k4 = rand->nextF(); |
+ bool enforcePMColor = rand->nextBool(); |
- AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, NULL))); |
+ AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, |
+ (k1, k2, k3, k4, enforcePMColor, NULL))); |
return CreateEffectRef(gEffect); |
} |
@@ -405,6 +435,7 @@ bool SkArithmeticMode_scalar::asNewEffect(GrEffectRef** effect, GrTexture* backg |
SkScalarToFloat(fK[1]), |
SkScalarToFloat(fK[2]), |
SkScalarToFloat(fK[3]), |
+ fEnforcePMColor, |
background); |
} |
return true; |