Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / effects / SkArithmeticMode.cpp
index 052b065..7d9997a 100644 (file)
 #include "GrContext.h"
 #include "GrCoordTransform.h"
 #include "gl/GrGLEffect.h"
+#include "gl/GrGLShaderBuilder.h"
 #include "GrTBackendEffectFactory.h"
-#include "SkImageFilterUtils.h"
 #endif
 
 static const bool gUseUnpremul = false;
 
 class SkArithmeticMode_scalar : public SkXfermode {
 public:
-    SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) {
-        fK[0] = k1;
-        fK[1] = k2;
-        fK[2] = k3;
-        fK[3] = 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,
                         const SkAlpha aa[]) const SK_OVERRIDE;
 
-    SK_DEVELOPER_TO_STRING()
+    SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar)
 
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrEffect** effect, GrTexture* background) const SK_OVERRIDE;
 #endif
 
 private:
+    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) {
         fK[0] = buffer.readScalar();
         fK[1] = buffer.readScalar();
         fK[2] = buffer.readScalar();
         fK[3] = buffer.readScalar();
+        fEnforcePMColor = buffer.readBool();
     }
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
@@ -54,8 +61,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;
 };
@@ -142,11 +151,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
@@ -165,20 +176,19 @@ 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);
         }
     }
 }
 
-#ifdef SK_DEVELOPER
+#ifndef SK_IGNORE_TO_STRING
 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
 
@@ -195,7 +205,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)) {
 
@@ -216,7 +227,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 SkArithmeticMode_scalar::Create(k1, k2, k3, k4, enforcePMColor);
 }
 
 
@@ -231,16 +242,19 @@ public:
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE;
+
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 private:
-    GrGLUniformManager::UniformHandle fKUni;
+    GrGLProgramDataManager::UniformHandle fKUni;
+    bool fEnforcePMColor;
 
     typedef GrGLEffect INHERITED;
 };
@@ -249,9 +263,9 @@ 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)));
-        return CreateEffectRef(effect);
+    static GrEffect* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
+                               GrTexture* background) {
+        return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, background));
     }
 
     virtual ~GrArithmeticEffect();
@@ -268,12 +282,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;
 
@@ -285,8 +302,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);
@@ -306,6 +323,7 @@ bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const {
            fK2 == s.fK2 &&
            fK3 == s.fK3 &&
            fK4 == s.fK4 &&
+           fEnforcePMColor == s.fEnforcePMColor &&
            backgroundTexture() == s.backgroundTexture();
 }
 
@@ -322,7 +340,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() {
@@ -330,7 +349,7 @@ GrGLArithmeticEffect::~GrGLArithmeticEffect() {
 
 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
                                     const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+                                    const GrEffectKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray& coords,
@@ -371,37 +390,49 @@ 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);
     }
 }
 
-void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
+void GrGLArithmeticEffect::setData(const GrGLProgramDataManager& pdman, const GrDrawEffect& drawEffect) {
     const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
-    uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
+    pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
+    fEnforcePMColor = arith.enforcePMColor();
+}
+
+void GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffect,
+                                  const GrGLCaps&, GrEffectKeyBuilder* b) {
+    const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
+    uint32_t key = arith.enforcePMColor() ? 1 : 0;
+    if (arith.backgroundTexture()) {
+        key |= 2;
+    }
+    b->add32(key);
 }
 
-GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand,
-                                            GrContext*,
-                                            const GrDrawTargetCaps&,
-                                            GrTexture*[]) {
+GrEffect* GrArithmeticEffect::TestCreate(SkRandom* rand,
+                                         GrContext*,
+                                         const GrDrawTargetCaps&,
+                                         GrTexture*[]) {
     float k1 = rand->nextF();
     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)));
-    return CreateEffectRef(gEffect);
+    return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, NULL));
 }
 
 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect);
 
-bool SkArithmeticMode_scalar::asNewEffect(GrEffectRef** effect, GrTexture* background) const {
+bool SkArithmeticMode_scalar::asNewEffect(GrEffect** effect, GrTexture* background) const {
     if (effect) {
         *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]),
                                              SkScalarToFloat(fK[1]),
                                              SkScalarToFloat(fK[2]),
                                              SkScalarToFloat(fK[3]),
+                                             fEnforcePMColor,
                                              background);
     }
     return true;