Expose color filter mutate methods

Bug: 36025103
Test: cts-tradefed run singleCommand cts-dev --module CtsGraphicsTestCases

Now, similar to Shaders, we defer native creation until Paint is being
used, and ensure that we have an up to date filter when drawing.

Also implements ColorMatrix#equals to behave like Matrix#equals.

Change-Id: I5f74addd97f5662800802e6f660fead58d518725
diff --git a/api/current.txt b/api/current.txt
index 77cb9e4..5908e429e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12757,7 +12757,7 @@
   }
 
   public class ColorFilter {
-    ctor public ColorFilter();
+    ctor public deprecated ColorFilter();
   }
 
   public class ColorMatrix {
@@ -12781,6 +12781,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public void getColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13004,6 +13007,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -13520,6 +13527,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -45423,7 +45434,7 @@
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
-    method public void setAutofillHint(java.lang.String[]);
+    method public void setAutofillHint(java.lang.String...);
     method public void setAutofillMode(int);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 827b46c..3142e71 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -13495,7 +13495,7 @@
   }
 
   public class ColorFilter {
-    ctor public ColorFilter();
+    ctor public deprecated ColorFilter();
   }
 
   public class ColorMatrix {
@@ -13519,6 +13519,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public void getColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13742,6 +13745,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -14258,6 +14265,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -48889,7 +48900,7 @@
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
-    method public void setAutofillHint(java.lang.String[]);
+    method public void setAutofillHint(java.lang.String...);
     method public void setAutofillMode(int);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 04f4f21..9eacfac 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -12795,7 +12795,7 @@
   }
 
   public class ColorFilter {
-    ctor public ColorFilter();
+    ctor public deprecated ColorFilter();
   }
 
   public class ColorMatrix {
@@ -12819,6 +12819,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public void getColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13042,6 +13045,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -13558,6 +13565,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -45786,7 +45797,7 @@
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
-    method public void setAutofillHint(java.lang.String[]);
+    method public void setAutofillHint(java.lang.String...);
     method public void setAutofillMode(int);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 79439e2..5553a3e 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -30,7 +30,7 @@
 
 class SkColorFilterGlue {
 public:
-    static void finalizer(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
+    static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
         SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
         SkSafeUnref(filter);
     }
@@ -57,19 +57,19 @@
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
-    {"destroyFilter", "(J)V", (void*) SkColorFilterGlue::finalizer}
+    {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref}
 };
 
 static const JNINativeMethod porterduff_methods[] = {
-    { "native_CreatePorterDuffFilter", "(II)J", (void*) SkColorFilterGlue::CreatePorterDuffFilter   },
+    { "native_CreatePorterDuffFilter", "(II)J", (void*) SkColorFilterGlue::CreatePorterDuffFilter },
 };
 
 static const JNINativeMethod lighting_methods[] = {
-    { "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter   },
+    { "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter },
 };
 
 static const JNINativeMethod colormatrix_methods[] = {
-    { "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter   },
+    { "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter },
 };
 
 int register_android_graphics_ColorFilter(JNIEnv* env) {
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index ac62bf4..0ca3729 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -28,21 +28,51 @@
  */
 public class ColorFilter {
     /**
-     * Holds the pointer to the native SkColorFilter instance.
-     *
-     * @hide
+     * @deprecated Use subclass constructors directly instead.
      */
-    public long native_instance;
+    @Deprecated
+    public ColorFilter() {}
+
+    /**
+     * Holds the pointer to the native SkColorFilter instance.
+     */
+    private long mNativeInstance;
+
+    long createNativeInstance() {
+        return 0;
+    }
+
+    void discardNativeInstance() {
+        if (mNativeInstance != 0) {
+            nSafeUnref(mNativeInstance);
+            mNativeInstance = 0;
+        }
+    }
 
     @Override
     protected void finalize() throws Throwable {
         try {
-            super.finalize();
+            if (mNativeInstance != 0) {
+                nSafeUnref(mNativeInstance);
+            }
+            mNativeInstance = -1;
         } finally {
-            destroyFilter(native_instance);
-            native_instance = 0;
+            super.finalize();
         }
     }
 
-    static native void destroyFilter(long native_instance);
+    /** @hide */
+    public long getNativeInstance() {
+        if (mNativeInstance == -1) {
+            throw new IllegalStateException("attempting to use a finalized ColorFilter");
+        }
+
+        if (mNativeInstance == 0) {
+            mNativeInstance = createNativeInstance();
+        }
+        return mNativeInstance;
+
+    }
+
+    static native void nSafeUnref(long native_instance);
 }
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index 1b1849e..6299b2c 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -268,4 +268,21 @@
         m[5] = 1;   m[6] = -0.34414f;   m[7] = -0.71414f;
         m[10] = 1;  m[11] = 1.772f;     m[12] = 0;
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        // if (obj == this) return true; -- NaN value would mean matrix != itself
+        if (!(obj instanceof ColorMatrix)) {
+            return false;
+        }
+
+        // we don't use Arrays.equals(), since that considers NaN == NaN
+        final float[] other = ((ColorMatrix) obj).mArray;
+        for (int i = 0; i < 20; i++) {
+            if (other[i] != mArray[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 291c8ff..61f6cc5 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -16,6 +16,9 @@
 
 package android.graphics;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 /**
  * A color filter that transforms colors through a 4x5 color matrix. This filter
  * can be used to change the saturation of pixels, convert from YUV to RGB, etc.
@@ -32,9 +35,8 @@
      *               the filter, so changes made to the matrix after the filter
      *               is constructed will not be reflected in the filter.
      */
-    public ColorMatrixColorFilter(ColorMatrix matrix) {
+    public ColorMatrixColorFilter(@NonNull ColorMatrix matrix) {
         mMatrix.set(matrix);
-        update();
     }
 
     /**
@@ -44,84 +46,76 @@
      *              matrix. The first 20 entries of the array are copied into
      *              the filter. See ColorMatrix.
      */
-    public ColorMatrixColorFilter(float[] array) {
+    public ColorMatrixColorFilter(@NonNull float[] array) {
         if (array.length < 20) {
             throw new ArrayIndexOutOfBoundsException();
         }
         mMatrix.set(array);
-        update();
     }
 
     /**
-     * Returns the {@link ColorMatrix} used by this filter. The returned
-     * value is never null. Modifying the returned matrix does not have
-     * any effect until you call {@link #setColorMatrix(ColorMatrix)}.
+     * Copies the ColorMatrix from the filter into the passed ColorMatrix.
      *
-     * @see #setColorMatrix(ColorMatrix)
-     *
-     * @hide
+     * @param colorMatrix Set to the current value of the filter's ColorMatrix.
      */
-    public ColorMatrix getColorMatrix() {
-        return mMatrix;
+    public void getColorMatrix(ColorMatrix colorMatrix) {
+        colorMatrix.set(mMatrix);
     }
 
     /**
-     * Specifies the color matrix used by this filter. If the specified
-     * color matrix is null, this filter's color matrix will be reset to
-     * the identity matrix.
+     * Copies the provided color matrix to be used by this filter.
+     *
+     * If the specified color matrix is null, this filter's color matrix will be reset to the
+     * identity matrix.
      *
      * @param matrix A {@link ColorMatrix} or null
      *
-     * @see #getColorMatrix()
-     * @see android.graphics.ColorMatrix#reset()
-     * @see #setColorMatrix(float[])
-     *
-     * @hide
+     * @see #getColorMatrix(ColorMatrix)
+     * @see #setColorMatrixArray(float[])
+     * @see ColorMatrix#reset()
      */
-    public void setColorMatrix(ColorMatrix matrix) {
+    public void setColorMatrix(@Nullable ColorMatrix matrix) {
+        discardNativeInstance();
         if (matrix == null) {
             mMatrix.reset();
-        } else if (matrix != mMatrix) {
+        } else {
             mMatrix.set(matrix);
         }
-        update();
     }
 
     /**
-     * Specifies the color matrix used by this filter. If the specified
-     * color matrix is null, this filter's color matrix will be reset to
-     * the identity matrix.
+     * Copies the provided color matrix to be used by this filter.
+     *
+     * If the specified color matrix is null, this filter's color matrix will be reset to the
+     * identity matrix.
      *
      * @param array Array of floats used to transform colors, treated as a 4x5
      *              matrix. The first 20 entries of the array are copied into
      *              the filter. See {@link ColorMatrix}.
      *
-     * @see #getColorMatrix()
-     * @see android.graphics.ColorMatrix#reset()
+     * @see #getColorMatrix(ColorMatrix)
      * @see #setColorMatrix(ColorMatrix)
+     * @see ColorMatrix#reset()
      *
      * @throws ArrayIndexOutOfBoundsException if the specified array's
      *         length is < 20
-     *
-     * @hide
      */
-    public void setColorMatrix(float[] array) {
+    public void setColorMatrixArray(@Nullable float[] array) {
+        // called '...Array' so that passing null isn't ambiguous
+        discardNativeInstance();
         if (array == null) {
             mMatrix.reset();
         } else {
             if (array.length < 20) {
                 throw new ArrayIndexOutOfBoundsException();
             }
-
             mMatrix.set(array);
         }
-        update();
     }
 
-    private void update() {
-        final float[] colorMatrix = mMatrix.getArray();
-        destroyFilter(native_instance);
-        native_instance = nativeColorMatrixFilter(colorMatrix);
+    @Override
+    long createNativeInstance() {
+        return nativeColorMatrixFilter(mMatrix.getArray());
     }
 
     private static native long nativeColorMatrixFilter(float[] array);
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index ad78430..b0c145b 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -21,6 +21,8 @@
 
 package android.graphics;
 
+import android.annotation.ColorInt;
+
 /**
  * A color filter that can be used to simulate simple lighting effects.
  * A <code>LightingColorFilter</code> is defined by two parameters, one
@@ -37,7 +39,9 @@
  * The result is pinned to the <code>[0..255]</code> range for each channel.
  */
 public class LightingColorFilter extends ColorFilter {
+    @ColorInt
     private int mMul;
+    @ColorInt
     private int mAdd;
 
     /**
@@ -45,10 +49,9 @@
      * and then adds a second color. The alpha components of the mul and add
      * arguments are ignored.
      */
-    public LightingColorFilter(int mul, int add) {
+    public LightingColorFilter(@ColorInt int mul, @ColorInt int add) {
         mMul = mul;
         mAdd = add;
-        update();
     }
 
     /**
@@ -56,9 +59,8 @@
      * color filter is applied.
      *
      * @see #setColorMultiply(int)
-     *
-     * @hide
      */
+    @ColorInt
     public int getColorMultiply() {
         return mMul;
     }
@@ -69,12 +71,12 @@
      * The alpha channel of this color is ignored.
      *
      * @see #getColorMultiply()
-     *
-     * @hide
      */
-    public void setColorMultiply(int mul) {
-        mMul = mul;
-        update();
+    public void setColorMultiply(@ColorInt int mul) {
+        if (mMul != mul) {
+            mMul = mul;
+            discardNativeInstance();
+        }
     }
 
     /**
@@ -82,9 +84,8 @@
      * when the color filter is applied.
      *
      * @see #setColorAdd(int)
-     *
-     * @hide
      */
+    @ColorInt
     public int getColorAdd() {
         return mAdd;
     }
@@ -95,17 +96,17 @@
      * The alpha channel of this color is ignored.
      *
      * @see #getColorAdd()
-     *
-     * @hide
      */
-    public void setColorAdd(int add) {
-        mAdd = add;
-        update();
+    public void setColorAdd(@ColorInt int add) {
+        if (mAdd != add) {
+            mAdd = add;
+            discardNativeInstance();
+        }
     }
 
-    private void update() {
-        destroyFilter(native_instance);
-        native_instance = native_CreateLightingFilter(mMul, mAdd);
+    @Override
+    long createNativeInstance() {
+        return native_CreateLightingFilter(mMul, mAdd);
     }
 
     private static native long native_CreateLightingFilter(int mul, int add);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 7ca4615..5d6aa8a 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -42,7 +42,8 @@
 public class Paint {
 
     private long mNativePaint;
-    private long mNativeShader = 0;
+    private long mNativeShader;
+    private long mNativeColorFilter;
 
     // The approximate size of a native paint object.
     private static final long NATIVE_PAINT_SIZE = 98;
@@ -584,6 +585,11 @@
             mNativeShader = newNativeShader;
             nSetShader(mNativePaint, mNativeShader);
         }
+        long newNativeColorFilter = mColorFilter == null ? 0 : mColorFilter.getNativeInstance();
+        if (newNativeColorFilter != mNativeColorFilter) {
+            mNativeColorFilter = newNativeColorFilter;
+            nSetColorFilter(mNativePaint, mNativeColorFilter);
+        }
         return mNativePaint;
     }
 
@@ -1044,10 +1050,13 @@
      * @return       filter
      */
     public ColorFilter setColorFilter(ColorFilter filter) {
-        long filterNative = 0;
-        if (filter != null)
-            filterNative = filter.native_instance;
-        nSetColorFilter(mNativePaint, filterNative);
+        // If mColorFilter changes, cached value of native shader aren't valid, since
+        // old shader's pointer may be reused by another shader allocation later
+        if (mColorFilter != filter) {
+            mNativeColorFilter = -1;
+        }
+
+        // Defer setting the filter natively until getNativeInstance() is called
         mColorFilter = filter;
         return filter;
     }
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index 69d6891..ccc6ead 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -24,6 +24,7 @@
  * color and a specific {@link PorterDuff Porter-Duff composite mode}.
  */
 public class PorterDuffColorFilter extends ColorFilter {
+    @ColorInt
     private int mColor;
     private PorterDuff.Mode mMode;
 
@@ -40,7 +41,6 @@
     public PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
         mColor = color;
         mMode = mode;
-        update();
     }
 
     /**
@@ -49,9 +49,8 @@
      *
      * @see Color
      * @see #setColor(int)
-     *
-     * @hide
      */
+    @ColorInt
     public int getColor() {
         return mColor;
     }
@@ -65,12 +64,12 @@
      * @see Color
      * @see #getColor()
      * @see #getMode()
-     *
-     * @hide
      */
-    public void setColor(int color) {
-        mColor = color;
-        update();
+    public void setColor(@ColorInt int color) {
+        if (mColor != color) {
+            mColor = color;
+            discardNativeInstance();
+        }
     }
 
     /**
@@ -79,8 +78,6 @@
      *
      * @see PorterDuff
      * @see #setMode(android.graphics.PorterDuff.Mode)
-     *
-     * @hide
      */
     public PorterDuff.Mode getMode() {
         return mMode;
@@ -93,17 +90,18 @@
      * @see PorterDuff
      * @see #getMode()
      * @see #getColor()
-     *
-     * @hide
      */
     public void setMode(@NonNull PorterDuff.Mode mode) {
+        if (mode == null) {
+            throw new IllegalArgumentException("mode must be non-null");
+        }
         mMode = mode;
-        update();
+        discardNativeInstance();
     }
 
-    private void update() {
-        destroyFilter(native_instance);
-        native_instance = native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
+    @Override
+    long createNativeInstance() {
+        return native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
     }
 
     @Override
@@ -115,10 +113,7 @@
             return false;
         }
         final PorterDuffColorFilter other = (PorterDuffColorFilter) object;
-        if (mColor != other.mColor || mMode != other.mMode) {
-            return false;
-        }
-        return true;
+        return (mColor == other.mColor && mMode.nativeInt == other.mMode.nativeInt);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index b584e0d..8410ab2 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -106,8 +106,10 @@
     }
 
     void discardNativeInstance() {
-        nativeSafeUnref(mNativeInstance);
-        mNativeInstance = 0;
+        if (mNativeInstance != 0) {
+            nativeSafeUnref(mNativeInstance);
+            mNativeInstance = 0;
+        }
     }
 
     /**
@@ -120,7 +122,9 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            nativeSafeUnref(mNativeInstance);
+            if (mNativeInstance != 0) {
+                nativeSafeUnref(mNativeInstance);
+            }
             mNativeInstance = -1;
         } finally {
             super.finalize();
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 3a12419..a1539b8 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -333,7 +333,7 @@
         // Color filters always override tint filters.
         final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter);
         final long colorFilterNativeInstance = colorFilter == null ? 0 :
-                colorFilter.native_instance;
+                colorFilter.getNativeInstance();
         boolean canReuseCache = mVectorState.canReuseCache();
         int pixelCount = nDraw(mVectorState.getNativeRenderer(), canvas.getNativeCanvasWrapper(),
                 colorFilterNativeInstance, mTmpBounds, needMirroring(),
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
index 808b5d3..a7bdabd 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
@@ -138,7 +138,7 @@
             mSaturation = saturation;
             final ColorMatrixColorFilter filter =
                     (ColorMatrixColorFilter) mColorMatrixPaint.getColorFilter();
-            final ColorMatrix m = filter.getColorMatrix();
+            final ColorMatrix m = new ColorMatrix();
             m.setSaturation(saturation);
             filter.setColorMatrix(m);
             invalidate();