replace impl of SkLightingColorFilter with SkColorMatrixFilter
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 6 Feb 2014 20:59:47 +0000 (20:59 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 6 Feb 2014 20:59:47 +0000 (20:59 +0000)
BUG=skia:
R=djsollen@google.com

Review URL: https://codereview.chromium.org/135123008

git-svn-id: http://skia.googlecode.com/svn/trunk@13350 2bbb7eff-a529-9590-31e7-b0007b416f81

include/effects/SkColorMatrix.h
src/effects/SkColorFilters.cpp
src/effects/SkColorMatrix.cpp
src/effects/SkColorMatrixFilter.cpp

index 84a3b7c4970efff02dcd7a7a881a91948876e412..8ff45f9277289b02fd6b2776dd120bb05ee9d4a6 100644 (file)
@@ -14,6 +14,18 @@ class SK_API SkColorMatrix {
 public:
     SkScalar    fMat[20];
 
+    enum Elem {
+        kR_Scale    = 0,
+        kG_Scale    = 6,
+        kB_Scale    = 12,
+        kA_Scale    = 18,
+        
+        kR_Trans    = 4,
+        kG_Trans    = 9,
+        kB_Trans    = 14,
+        kA_Trans    = 19,
+    };
+
     void setIdentity();
     void setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
                   SkScalar aScale = SK_Scalar1);
@@ -21,6 +33,8 @@ public:
                   SkScalar aScale = SK_Scalar1);
     void postScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
                    SkScalar aScale = SK_Scalar1);
+    void postTranslate(SkScalar rTrans, SkScalar gTrans, SkScalar bTrans,
+                       SkScalar aTrans = 0);
 
     enum Axis {
         kR_Axis = 0,
index f9fa1fd82bfa16f53053cbeaf9f7759bd8012060..d947bbc1ad80b11f550a515b242f94710366716a 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2006 The Android Open Source Project
  *
@@ -6,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #include "SkBlitRow.h"
 #include "SkColorFilter.h"
 #include "SkColorPriv.h"
 #include "SkUtils.h"
 #include "SkString.h"
 #include "SkValidationUtils.h"
+#include "SkColorMatrixFilter.h"
+
+#define SK_MAP_LIGHTINGCOLORFILTER_TO_COLORMATRIX
+
 
 #define ILLEGAL_XFERMODE_MODE   ((SkXfermode::Mode)-1)
 
@@ -539,6 +541,19 @@ SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
 
 ///////////////////////////////////////////////////////////////////////////////
 
+#ifdef SK_MAP_LIGHTINGCOLORFILTER_TO_COLORMATRIX
+
+static SkScalar byte_to_scale(U8CPU byte) {
+    if (0xFF == byte) {
+        // want to get this exact
+        return 1;
+    } else {
+        return byte * 0.00392156862745f;
+    }
+}
+
+#else
+
 static inline unsigned pin(unsigned value, unsigned max) {
     if (value > max) {
         value = max;
@@ -778,8 +793,6 @@ private:
     typedef SkLightingColorFilter INHERITED;
 };
 
-///////////////////////////////////////////////////////////////////////////////
-
 class SkSimpleColorFilter : public SkColorFilter {
 public:
     static SkFlattenable* CreateProc(SkReadBuffer& buffer) {
@@ -808,7 +821,21 @@ protected:
 
 };
 
+#endif  // SK_MAP_LIGHTINGCOLORFILTER_TO_COLORMATRIX
+
 SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
+#ifdef SK_MAP_LIGHTINGCOLORFILTER_TO_COLORMATRIX
+    SkColorMatrix matrix;
+    matrix.setScale(byte_to_scale(SkColorGetR(mul)),
+                    byte_to_scale(SkColorGetG(mul)),
+                    byte_to_scale(SkColorGetB(mul)),
+                    1);
+    matrix.postTranslate(SkIntToScalar(SkColorGetR(add)),
+                         SkIntToScalar(SkColorGetG(add)),
+                         SkIntToScalar(SkColorGetB(add)),
+                         0);
+    return SkNEW_ARGS(SkColorMatrixFilter, (matrix));
+#else
     mul &= 0x00FFFFFF;
     add &= 0x00FFFFFF;
 
@@ -836,16 +863,19 @@ SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) {
     }
 
     return SkNEW_ARGS(SkLightingColorFilter, (mul, add));
+#endif
 }
 
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
+#ifndef SK_MAP_LIGHTINGCOLORFILTER_TO_COLORMATRIX
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter)
+#endif
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
index 0e2ede2ce0196b27f0e616ae53d184e7b39d0a92..b07f3d50f9eda83893794fd95a1ca296188f3af3 100644 (file)
@@ -9,23 +9,26 @@
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 
-#define kRScale     0
-#define kGScale     6
-#define kBScale     12
-#define kAScale     18
-
 void SkColorMatrix::setIdentity() {
     memset(fMat, 0, sizeof(fMat));
-    fMat[kRScale] = fMat[kGScale] = fMat[kBScale] = fMat[kAScale] = SK_Scalar1;
+    fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1;
 }
 
 void SkColorMatrix::setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
                              SkScalar aScale) {
     memset(fMat, 0, sizeof(fMat));
-    fMat[kRScale] = rScale;
-    fMat[kGScale] = gScale;
-    fMat[kBScale] = bScale;
-    fMat[kAScale] = aScale;
+    fMat[kR_Scale] = rScale;
+    fMat[kG_Scale] = gScale;
+    fMat[kB_Scale] = bScale;
+    fMat[kA_Scale] = aScale;
+}
+
+void SkColorMatrix::postTranslate(SkScalar dr, SkScalar dg, SkScalar db,
+                                  SkScalar da) {
+    fMat[kR_Trans] += dr;
+    fMat[kG_Trans] += dg;
+    fMat[kB_Trans] += db;
+    fMat[kA_Trans] += da;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -116,14 +119,14 @@ static const SkScalar kHueB = 0.072f;
 void SkColorMatrix::setSaturation(SkScalar sat) {
     memset(fMat, 0, sizeof(fMat));
 
-    const SkScalar R = SkScalarMul(kHueR, SK_Scalar1 - sat);
-    const SkScalar G = SkScalarMul(kHueG, SK_Scalar1 - sat);
-    const SkScalar B = SkScalarMul(kHueB, SK_Scalar1 - sat);
+    const SkScalar R = kHueR * (1 - sat);
+    const SkScalar G = kHueG * (1 - sat);
+    const SkScalar B = kHueB * (1 - sat);
 
     setrow(fMat +  0, R + sat, G, B);
     setrow(fMat +  5, R, G + sat, B);
     setrow(fMat + 10, R, G, B + sat);
-    fMat[18] = SK_Scalar1;
+    fMat[kA_Scale] = 1;
 }
 
 static const SkScalar kR2Y = 0.299f;
@@ -144,7 +147,7 @@ void SkColorMatrix::setRGB2YUV() {
     setrow(fMat +  0, kR2Y, kG2Y, kB2Y);
     setrow(fMat +  5, kR2U, kG2U, kB2U);
     setrow(fMat + 10, kR2V, kG2V, kB2V);
-    fMat[18] = SK_Scalar1;
+    fMat[kA_Scale] = 1;
 }
 
 static const SkScalar kV2R = 1.402f;
@@ -155,8 +158,8 @@ static const SkScalar kU2B = 1.772f;
 void SkColorMatrix::setYUV2RGB() {
     memset(fMat, 0, sizeof(fMat));
 
-    setrow(fMat +  0, SK_Scalar1, 0, kV2R);
-    setrow(fMat +  5, SK_Scalar1, kU2G, kV2G);
-    setrow(fMat + 10, SK_Scalar1, kU2B, 0);
-    fMat[18] = SK_Scalar1;
+    setrow(fMat +  0, 1, 0, kV2R);
+    setrow(fMat +  5, 1, kU2G, kV2G);
+    setrow(fMat + 10, 1, kU2B, 0);
+    fMat[kA_Scale] = 1;
 }
index 6b925710c96bcc88ca004b76beaee24cd3abed88..bb85485050813e776aa1ecd6489819cbc5aef79c 100644 (file)
@@ -76,9 +76,9 @@ static void ScaleAdd(const SkColorMatrixFilter::State& state,
     const int shift = state.fShift;
 
     // cast to (int) to keep the expression signed for the shift
-    result[0] = (array[0] * (int)r + array[4]) >> shift;
-    result[1] = (array[6] * (int)g + array[9]) >> shift;
-    result[2] = (array[12] * (int)b + array[14]) >> shift;
+    result[0] = (array[SkColorMatrix::kR_Scale] * (int)r + array[4]) >> shift;
+    result[1] = (array[SkColorMatrix::kG_Scale] * (int)g + array[9]) >> shift;
+    result[2] = (array[SkColorMatrix::kB_Scale] * (int)b + array[14]) >> shift;
     result[3] = a;
 }
 
@@ -88,9 +88,9 @@ static void ScaleAdd16(const SkColorMatrixFilter::State& state,
     const int32_t* SK_RESTRICT array = state.fArray;
 
     // cast to (int) to keep the expression signed for the shift
-    result[0] = (array[0] * (int)r + array[4]) >> 16;
-    result[1] = (array[6] * (int)g + array[9]) >> 16;
-    result[2] = (array[12] * (int)b + array[14]) >> 16;
+    result[0] = (array[SkColorMatrix::kR_Scale] * (int)r + array[4]) >> 16;
+    result[1] = (array[SkColorMatrix::kG_Scale] * (int)g + array[9]) >> 16;
+    result[2] = (array[SkColorMatrix::kB_Scale] * (int)b + array[14]) >> 16;
     result[3] = a;
 }
 
@@ -100,9 +100,9 @@ static void Add(const SkColorMatrixFilter::State& state,
     const int32_t* SK_RESTRICT array = state.fArray;
     const int shift = state.fShift;
 
-    result[0] = r + (array[4] >> shift);
-    result[1] = g + (array[9] >> shift);
-    result[2] = b + (array[14] >> shift);
+    result[0] = r + (array[SkColorMatrix::kR_Trans] >> shift);
+    result[1] = g + (array[SkColorMatrix::kG_Trans] >> shift);
+    result[2] = b + (array[SkColorMatrix::kB_Trans] >> shift);
     result[3] = a;
 }
 
@@ -111,9 +111,9 @@ static void Add16(const SkColorMatrixFilter::State& state,
                   int32_t* SK_RESTRICT result) {
     const int32_t* SK_RESTRICT array = state.fArray;
 
-    result[0] = r + (array[4] >> 16);
-    result[1] = g + (array[9] >> 16);
-    result[2] = b + (array[14] >> 16);
+    result[0] = r + (array[SkColorMatrix::kR_Trans] >> 16);
+    result[1] = g + (array[SkColorMatrix::kG_Trans] >> 16);
+    result[2] = b + (array[SkColorMatrix::kB_Trans] >> 16);
     result[3] = a;
 }
 
@@ -161,9 +161,9 @@ void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) {
     } else {
         fFlags = kNO_ALPHA_FLAGS;
 
-        int32_t needsScale = (array[0] - one) |       // red axis
-                             (array[6] - one) |       // green axis
-                             (array[12] - one);       // blue axis
+        int32_t needsScale = (array[SkColorMatrix::kR_Scale] - one) |
+                             (array[SkColorMatrix::kG_Scale] - one) |
+                             (array[SkColorMatrix::kB_Scale] - one);
 
         int32_t needs3x3 =  array[1] | array[2] |     // red off-axis
                             array[5] | array[7] |     // green off-axis
@@ -173,7 +173,9 @@ void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) {
             fProc = shiftIs16 ? AffineAdd16 : AffineAdd;
         } else if (needsScale) {
             fProc = shiftIs16 ? ScaleAdd16 : ScaleAdd;
-        } else if (array[4] | array[9] | array[14]) {   // needs add
+        } else if (array[SkColorMatrix::kR_Trans] |
+                   array[SkColorMatrix::kG_Trans] |
+                   array[SkColorMatrix::kB_Trans]) {
             fProc = shiftIs16 ? Add16 : Add;
         } else {
             fProc = NULL;   // identity