add sample for filter quality

BUG=skia:
TBR=

Review URL: https://codereview.chromium.org/788163007
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp
index 96d4acc..7767835 100644
--- a/gyp/SampleApp.gyp
+++ b/gyp/SampleApp.gyp
@@ -64,6 +64,7 @@
         '../samplecode/SampleFillType.cpp',
         '../samplecode/SampleFilter.cpp',
         '../samplecode/SampleFilter2.cpp',
+        '../samplecode/SampleFilterQuality.cpp',
         '../samplecode/SampleFilterFuzz.cpp',
         '../samplecode/SampleFontCache.cpp',
         '../samplecode/SampleFontScalerTest.cpp',
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
new file mode 100644
index 0000000..4c778e3
--- /dev/null
+++ b/samplecode/SampleFilterQuality.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+
+#include "Resources.h"
+#include "SampleCode.h"
+#include "SkCanvas.h"
+#include "SkInterpolator.h"
+#include "SkSurface.h"
+#include "SkRandom.h"
+#include "SkTime.h"
+
+#define N   128
+
+static SkImage* make_image() {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
+    SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+    SkCanvas* canvas = surface->getCanvas();
+
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+
+    path.addRect(SkRect::MakeWH(N/2, N));
+    path.addRect(SkRect::MakeWH(N, N/2));
+    path.moveTo(0, 0); path.lineTo(N, 0); path.lineTo(0, N); path.close();
+
+    canvas->drawPath(path, SkPaint());
+    return surface->newImageSnapshot();
+}
+
+struct AnimValue {
+    SkScalar fValue;
+    SkScalar fMin;
+    SkScalar fMax;
+    SkScalar fMod;
+
+    operator SkScalar() const { return fValue; }
+
+    void set(SkScalar value, SkScalar min, SkScalar max) {
+        fValue = value;
+        fMin = min;
+        fMax = max;
+        fMod = 0;
+    }
+
+    void setMod(SkScalar value, SkScalar mod) {
+        fValue = value;
+        fMin = 0;
+        fMax = 0;
+        fMod = mod;
+    }
+
+    SkScalar inc(SkScalar delta) {
+        fValue += delta;
+        return this->fixUp();
+    }
+
+    SkScalar fixUp() {
+        if (fMod) {
+            fValue = SkScalarMod(fValue, fMod);
+        } else {
+            if (fValue > fMax) {
+                fValue = fMax;
+            } else if (fValue < fMin) {
+                fValue = fMin;
+            }
+        }
+        return fValue;
+    }
+};
+
+#define ANGLE_DELTA 3
+#define SCALE_DELTA (SK_Scalar1 / 32)
+
+class FilterQualityView : public SampleView {
+    SkAutoTUnref<SkImage> fImage;
+    AnimValue             fScale, fAngle;
+
+    SkInterpolator      fTrans;
+
+public:
+    FilterQualityView() : fImage(make_image()), fTrans(2, 2) {
+        fScale.set(1, SK_Scalar1 / 8, 1);
+        fAngle.setMod(0, 360);
+
+        SkScalar values[2];
+        fTrans.setMirror(true);
+        fTrans.setReset(true);
+
+        fTrans.setRepeatCount(999);
+        values[0] = values[1] = 0;
+        fTrans.setKeyFrame(0, SkTime::GetMSecs(), values);
+        values[0] = values[1] = 1;
+        fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values);
+    }
+
+protected:
+
+    // overrides from SkEventSink
+    bool onQuery(SkEvent* evt) SK_OVERRIDE {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "FilterQuality");
+            return true;
+        }
+        SkUnichar uni;
+        if (SampleCode::CharQ(*evt, &uni)) {
+            switch (uni) {
+                case '1': fAngle.inc(-ANGLE_DELTA); this->inval(NULL); return true;
+                case '2': fAngle.inc( ANGLE_DELTA); this->inval(NULL); return true;
+                case '3': fScale.inc(-SCALE_DELTA); this->inval(NULL); return true;
+                case '4': fScale.inc( SCALE_DELTA); this->inval(NULL); return true;
+                default: break;
+            }
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    void drawHere(SkCanvas* canvas, SkScalar x, SkScalar y, SkPaint::FilterLevel filter) {
+        SkAutoCanvasRestore acr(canvas, true);
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setFilterLevel(filter);
+
+        canvas->translate(x, y);
+        canvas->scale(fScale, fScale);
+        canvas->rotate(fAngle);
+        canvas->drawImage(fImage, -SkScalarHalf(fImage->width()), -SkScalarHalf(fImage->height()),
+                          &paint);
+    }
+
+    void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
+        SkScalar trans[2];
+        fTrans.timeToValues(SkTime::GetMSecs(), trans);
+        canvas->translate(trans[0], trans[1]);
+        this->inval(NULL);
+
+        const struct {
+            SkScalar                fX;
+            SkScalar                fY;
+            SkPaint::FilterLevel    fFilter;
+        } rec[] = {
+            { 100, 100, SkPaint::kNone_FilterLevel },
+            { 300, 100, SkPaint::kLow_FilterLevel },
+            { 100, 300, SkPaint::kMedium_FilterLevel },
+            { 300, 300, SkPaint::kHigh_FilterLevel },
+        };
+
+        for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
+            this->drawHere(canvas, rec[i].fX, rec[i].fY, rec[i].fFilter);
+        }
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setTextSize(40);
+        SkString str;
+        str.appendScalar(fScale);
+        canvas->drawText(str.c_str(), str.size(), 450, 100, paint);
+        str.reset(); str.appendScalar(fAngle);
+        canvas->drawText(str.c_str(), str.size(), 450, 150, paint);
+
+        str.reset(); str.appendScalar(trans[0]);
+        canvas->drawText(str.c_str(), str.size(), 450, 200, paint);
+        str.reset(); str.appendScalar(trans[1]);
+        canvas->drawText(str.c_str(), str.size(), 450, 250, paint);
+}
+
+    virtual bool handleKey(SkKey key) {
+        this->inval(NULL);
+        return true;
+    }
+
+private:
+    typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new FilterQualityView; }
+static SkViewRegister reg(MyFactory);