| Index: src/effects/SkArithmeticMode.cpp
|
| diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
|
| index e9dc7824bca5a1fd96c9578042bf5bc6c1393fc5..3d03a2d58f9c2be16d810604ae63832e56ba643f 100644
|
| --- a/src/effects/SkArithmeticMode.cpp
|
| +++ b/src/effects/SkArithmeticMode.cpp
|
| @@ -20,11 +20,12 @@
|
|
|
| class SkArithmeticMode_scalar : public SkXfermode {
|
| public:
|
| - SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) {
|
| + SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool unpremultiply) {
|
| fK[0] = k1;
|
| fK[1] = k2;
|
| fK[2] = k3;
|
| fK[3] = k4;
|
| + fUnpremultiply = unpremultiply;
|
| }
|
|
|
| virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
|
| @@ -43,6 +44,7 @@ private:
|
| fK[1] = buffer.readScalar();
|
| fK[2] = buffer.readScalar();
|
| fK[3] = buffer.readScalar();
|
| + fUnpremultiply = buffer.readBool();
|
| }
|
|
|
| virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
|
| @@ -51,8 +53,10 @@ private:
|
| buffer.writeScalar(fK[1]);
|
| buffer.writeScalar(fK[2]);
|
| buffer.writeScalar(fK[3]);
|
| + buffer.writeBool(fUnpremultiply);
|
| }
|
| SkScalar fK[4];
|
| + bool fUnpremultiply;
|
|
|
| typedef SkXfermode INHERITED;
|
| };
|
| @@ -98,8 +102,8 @@ void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[],
|
| int sa = SkGetPackedA32(sc);
|
| int da = SkGetPackedA32(dc);
|
|
|
| - int srcNeedsUnpremul = needsUnpremul(sa);
|
| - int dstNeedsUnpremul = needsUnpremul(da);
|
| + int srcNeedsUnpremul = fUnpremultiply && needsUnpremul(sa);
|
| + int dstNeedsUnpremul = fUnpremultiply && needsUnpremul(da);
|
|
|
| int a, r, g, b;
|
|
|
| @@ -145,7 +149,7 @@ void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[],
|
| }
|
|
|
| // turn the result back into premul
|
| - if (0xFF != a) {
|
| + if (fUnpremultiply && 0xFF != a) {
|
| int scale = a + (a >> 7);
|
| r = SkAlphaMul(r, scale);
|
| g = SkAlphaMul(g, scale);
|
| @@ -194,7 +198,7 @@ static int32_t toDot8(SkScalar x) {
|
| #endif
|
|
|
| SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2,
|
| - SkScalar k3, SkScalar k4) {
|
| + SkScalar k3, SkScalar k4, bool unpremultiply) {
|
| if (fitsInBits(k1, 8) && fitsInBits(k2, 16) &&
|
| fitsInBits(k2, 16) && fitsInBits(k2, 24)) {
|
|
|
| @@ -215,7 +219,7 @@ SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2,
|
| return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4));
|
| #endif
|
| }
|
| - return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4));
|
| + return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, unpremultiply));
|
| }
|
|
|
|
|
| @@ -251,8 +255,8 @@ 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 unpremultiply, GrTexture* background) {
|
| + AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, unpremultiply, background)));
|
| return CreateEffectRef(effect);
|
| }
|
|
|
| @@ -270,12 +274,14 @@ public:
|
| float k2() const { return fK2; }
|
| float k3() const { return fK3; }
|
| float k4() const { return fK4; }
|
| + bool unpremultiply() const { return fUnpremultiply; }
|
|
|
| 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 unpremultiply, GrTexture* background);
|
| float fK1, fK2, fK3, fK4;
|
| + bool fUnpremultiply;
|
| GrTextureAccess fBackgroundAccess;
|
|
|
| GR_DECLARE_EFFECT_TEST;
|
| @@ -286,8 +292,8 @@ private:
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4,
|
| - GrTexture* background)
|
| - : fK1(k1), fK2(k2), fK3(k3), fK4(k4) {
|
| + bool unpremultiply, GrTexture* background)
|
| + : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fUnpremultiply(unpremultiply) {
|
| if (background) {
|
| fBackgroundAccess.reset(background);
|
| this->addTextureAccess(&fBackgroundAccess);
|
| @@ -305,6 +311,7 @@ bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const {
|
| fK2 == s.fK2 &&
|
| fK3 == s.fK3 &&
|
| fK4 == s.fK4 &&
|
| + fUnpremultiply == s.fUnpremultiply &&
|
| backgroundTexture() == s.backgroundTexture();
|
| }
|
|
|
| @@ -335,7 +342,9 @@ void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
|
| const char* inputColor,
|
| const TextureSamplerArray& samplers) {
|
|
|
| - GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backgroundTexture();
|
| + const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
|
| + GrTexture* backgroundTex = arith.backgroundTexture();
|
| + bool unpremultiply = arith.unpremultiply();
|
| const char* dstColor;
|
| if (backgroundTex) {
|
| const char* bgCoords;
|
| @@ -361,15 +370,23 @@ void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
|
| builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4));
|
| } else {
|
| builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor);
|
| - builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
|
| + if (unpremultiply) {
|
| + builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
|
| + }
|
| }
|
|
|
| builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor);
|
| - builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
|
| + if (unpremultiply) {
|
| + builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
|
| + }
|
|
|
| builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
|
| builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
|
| - builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
|
| + if (unpremultiply) {
|
| + builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
|
| + } else {
|
| + builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor);
|
| + }
|
| }
|
|
|
| void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
|
| @@ -394,7 +411,8 @@ GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec
|
| GrGLArithmeticEffect::kCoordsType,
|
| bgTex);
|
| }
|
| - return bgKey;
|
| + EffectKey unpremulKey = (effect.unpremultiply() ? 0x1 : 0x0) << GrGLEffectMatrix::kKeyBits;
|
| + return unpremulKey | bgKey;
|
| }
|
|
|
| GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand,
|
| @@ -405,8 +423,9 @@ GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand,
|
| float k2 = rand->nextF();
|
| float k3 = rand->nextF();
|
| float k4 = rand->nextF();
|
| + bool unpremultiply = rand->nextBool();
|
|
|
| - static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, NULL)));
|
| + static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, unpremultiply, NULL)));
|
| return CreateEffectRef(gEffect);
|
| }
|
|
|
| @@ -422,6 +441,7 @@ bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*,
|
| SkScalarToFloat(fK[1]),
|
| SkScalarToFloat(fK[2]),
|
| SkScalarToFloat(fK[3]),
|
| + fUnpremultiply,
|
| background);
|
| }
|
| return true;
|
|
|