Add bigtileimagefilter GM & improvements to toString

This is all the ancillary code from https://codereview.chromium.org/1152553006/ (Fix dst bound reported by SkTileImageFilter).

TBR=reed@google.com, senorblanco@google.com

Review URL: https://codereview.chromium.org/1169713003
diff --git a/gm/bigtileimagefilter.cpp b/gm/bigtileimagefilter.cpp
new file mode 100644
index 0000000..97de0d2
--- /dev/null
+++ b/gm/bigtileimagefilter.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 "SkBitmapSource.h"
+#include "SkTileImageFilter.h"
+#include "gm.h"
+
+namespace skiagm {
+
+class BigTileImageFilterGM : public GM {
+public:
+    BigTileImageFilterGM() {
+        this->setBGColor(0xFF000000);
+    }
+
+protected:
+
+    SkString onShortName() override {
+        return SkString("bigtileimagefilter");
+    }
+
+    SkISize onISize() override{
+        return SkISize::Make(kWidth, kHeight);
+    }
+
+    void onOnceBeforeDraw() override {
+        fBitmap.allocN32Pixels(kBitmapSize, kBitmapSize);
+
+        SkCanvas canvas(fBitmap);
+        canvas.clear(0xFF000000);
+
+        SkPaint paint;
+        paint.setColor(SK_ColorRED);
+        paint.setStrokeWidth(3);
+        paint.setStyle(SkPaint::kStroke_Style);
+
+        canvas.drawCircle(SkScalarHalf(kBitmapSize), SkScalarHalf(kBitmapSize),
+                          SkScalarHalf(kBitmapSize), paint);
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        canvas->clear(SK_ColorBLACK);
+
+        SkPaint p;
+
+        SkAutoTUnref<SkBitmapSource> bms(SkBitmapSource::Create(fBitmap));
+        SkAutoTUnref<SkTileImageFilter> tif(SkTileImageFilter::Create(
+                            SkRect::MakeWH(SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize)),
+                            SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)),
+                            bms));
+        p.setImageFilter(tif);
+
+        SkRect bound = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
+        canvas->saveLayer(&bound, &p);
+        canvas->restore();
+    }
+
+private:
+    static const int kWidth = 512;
+    static const int kHeight = 512;
+    static const int kBitmapSize = 64;
+
+    SkBitmap fBitmap;
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM( return SkNEW(BigTileImageFilterGM); )
+
+}
diff --git a/gm/tileimagefilter.cpp b/gm/tileimagefilter.cpp
index 2c4f6b2..8239308 100644
--- a/gm/tileimagefilter.cpp
+++ b/gm/tileimagefilter.cpp
@@ -16,46 +16,48 @@
 #define HEIGHT 100
 #define MARGIN 12
 
+static SkBitmap make_bitmap() {
+    SkBitmap bitmap;
+    bitmap.allocN32Pixels(50, 50);
+    SkCanvas canvas(bitmap);
+    canvas.clear(0xFF000000);
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
+    paint.setColor(0xD000D000);
+    paint.setTextSize(SkIntToScalar(50));
+    const char* str = "e";
+    canvas.drawText(str, strlen(str), SkIntToScalar(10), SkIntToScalar(45), paint);
+    return bitmap;
+}
+
+
 namespace skiagm {
 
 class TileImageFilterGM : public GM {
 public:
-    TileImageFilterGM() : fInitialized(false) {
+    TileImageFilterGM() {
         this->setBGColor(0xFF000000);
     }
 
 protected:
-    virtual SkString onShortName() {
+    SkString onShortName() override {
         return SkString("tileimagefilter");
     }
 
-    void make_bitmap() {
-        fBitmap.allocN32Pixels(50, 50);
-        SkCanvas canvas(fBitmap);
-        canvas.clear(0xFF000000);
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        sk_tool_utils::set_portable_typeface(&paint);
-        paint.setColor(0xD000D000);
-        paint.setTextSize(SkIntToScalar(50));
-        const char* str = "e";
-        canvas.drawText(str, strlen(str), SkIntToScalar(10), SkIntToScalar(45), paint);
-    }
-
-    virtual SkISize onISize() {
+    SkISize onISize() override{
         return SkISize::Make(WIDTH, HEIGHT);
     }
 
-    virtual void onDraw(SkCanvas* canvas) {
-        if (!fInitialized) {
-            make_bitmap();
+    void onOnceBeforeDraw() override {
+        fBitmap = make_bitmap();
 
-            fCheckerboard.allocN32Pixels(80, 80);
-            SkCanvas checkerboardCanvas(fCheckerboard);
-            sk_tool_utils::draw_checkerboard(&checkerboardCanvas, 0xFFA0A0A0, 0xFF404040, 8);
+        fCheckerboard.allocN32Pixels(80, 80);
+        SkCanvas checkerboardCanvas(fCheckerboard);
+        sk_tool_utils::draw_checkerboard(&checkerboardCanvas, 0xFFA0A0A0, 0xFF404040, 8);
+    }
 
-            fInitialized = true;
-        }
+    void onDraw(SkCanvas* canvas) override {
         canvas->clear(SK_ColorBLACK);
 
         int x = 0, y = 0;
@@ -109,14 +111,14 @@
         canvas->restore();
     }
 private:
+    SkBitmap fBitmap;
+    SkBitmap fCheckerboard;
+
     typedef GM INHERITED;
-    SkBitmap fBitmap, fCheckerboard;
-    bool fInitialized;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static GM* MyFactory(void*) { return new TileImageFilterGM; }
-static GMRegistry reg(MyFactory);
+DEF_GM( return SkNEW(TileImageFilterGM); )
 
 }
diff --git a/include/effects/SkTileImageFilter.h b/include/effects/SkTileImageFilter.h
index a010205..f695355 100644
--- a/include/effects/SkTileImageFilter.h
+++ b/include/effects/SkTileImageFilter.h
@@ -22,10 +22,10 @@
     static SkTileImageFilter* Create(const SkRect& srcRect, const SkRect& dstRect,
                                      SkImageFilter* input);
 
-    virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
-                               SkBitmap* dst, SkIPoint* offset) const override;
-    virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
-                                SkIRect* dst) const override;
+    bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
+                       SkBitmap* dst, SkIPoint* offset) const override;
+    bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+                        SkIRect* dst) const override;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter)
diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp
index c5cf518..b2244b9 100644
--- a/src/effects/SkTileImageFilter.cpp
+++ b/src/effects/SkTileImageFilter.cpp
@@ -110,6 +110,15 @@
 #ifndef SK_IGNORE_TO_STRING
 void SkTileImageFilter::toString(SkString* str) const {
     str->appendf("SkTileImageFilter: (");
+    str->appendf("src: %.2f %.2f %.2f %.2f",
+                 fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBottom);
+    str->appendf(" dst: %.2f %.2f %.2f %.2f",
+                 fDstRect.fLeft, fDstRect.fTop, fDstRect.fRight, fDstRect.fBottom);
+    if (this->getInput(0)) {
+        str->appendf("input: (");
+        this->getInput(0)->toString(str);
+        str->appendf(")");
+    }
     str->append(")");
 }
 #endif
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index f98247a..599fd42 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -105,7 +105,18 @@
     if (fMode) {
         fMode->toString(str);
     }
-    str->append("))");
+    str->append(")");
+    if (this->getInput(0)) {
+        str->appendf("foreground: (");
+        this->getInput(0)->toString(str);
+        str->appendf(")");
+    }
+    if (this->getInput(1)) {
+        str->appendf("background: (");
+        this->getInput(1)->toString(str);
+        str->appendf(")");
+    }
+    str->append(")");
 }
 #endif