Fix SkColorFilterImageFilter matrix optimization.
authorsenorblanco <senorblanco@chromium.org>
Thu, 3 Jul 2014 18:13:09 +0000 (11:13 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 3 Jul 2014 18:13:09 +0000 (11:13 -0700)
The order of matrices passed to multiplication was wrong (apparently,
this optimization was only being tested with matrices which commute).

See Chrome bug http://crbug.com/378362

R=sugoi@chromium.org

Author: senorblanco@chromium.org

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

src/effects/SkColorFilterImageFilter.cpp
tests/ImageFilterTest.cpp

index 8cdd546..f2490e3 100755 (executable)
@@ -68,7 +68,7 @@ SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
         SkAutoUnref autoUnref(inputColorFilter);
         if (inputColorFilter->asColorMatrix(inputMatrix) && !matrix_needs_clamping(inputMatrix)) {
             SkScalar combinedMatrix[20];
-            mult_color_matrix(inputMatrix, colorMatrix, combinedMatrix);
+            mult_color_matrix(colorMatrix, inputMatrix, combinedMatrix);
             SkAutoTUnref<SkColorFilter> newCF(SkColorMatrixFilter::Create(combinedMatrix));
             return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect));
         }
index d3471ad..3f71b01 100644 (file)
@@ -158,6 +158,33 @@ DEF_TEST(ImageFilter, reporter) {
     }
 
     {
+        // Check that two non-commutative matrices are concatenated in
+        // the correct order.
+        SkScalar blueToRedMatrix[20] = { 0 };
+        blueToRedMatrix[2] = blueToRedMatrix[18] = SK_Scalar1;
+        SkScalar redToGreenMatrix[20] = { 0 };
+        redToGreenMatrix[5] = redToGreenMatrix[18] = SK_Scalar1;
+        SkAutoTUnref<SkColorFilter> blueToRed(SkColorMatrixFilter::Create(blueToRedMatrix));
+        SkAutoTUnref<SkImageFilter> filter1(SkColorFilterImageFilter::Create(blueToRed.get()));
+        SkAutoTUnref<SkColorFilter> redToGreen(SkColorMatrixFilter::Create(redToGreenMatrix));
+        SkAutoTUnref<SkImageFilter> filter2(SkColorFilterImageFilter::Create(redToGreen.get(), filter1.get()));
+
+        SkBitmap result;
+        result.allocN32Pixels(kBitmapSize, kBitmapSize);
+
+        SkPaint paint;
+        paint.setColor(SK_ColorBLUE);
+        paint.setImageFilter(filter2.get());
+        SkCanvas canvas(result);
+        canvas.clear(0x0);
+        SkRect rect = SkRect::Make(SkIRect::MakeWH(kBitmapSize, kBitmapSize));
+        canvas.drawRect(rect, paint);
+        uint32_t pixel = *result.getAddr32(0, 0);
+        // The result here should be green, since we have effectively shifted blue to green.
+        REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
+    }
+
+    {
         // Tests pass by not asserting
         SkBitmap bitmap, result;
         make_small_bitmap(bitmap);