Tweak SkPictureShader's tile semantics.

Currently, the tile offset is added when drawing the picture. This might
have made a tiny bit of sense when the picture was always positioned at
origin, but with a picture cull rect offset things looks really strange.

For example, to specify a tile == the picture cull rect we have to pass
in [-cullrect.x, -cullrect.y, cullrect.width, cullrect.height]. Yikes.

(there's also a bug when not passing a tile, as we use a default tile
== cullrect but don't compensate for the above oddity)

This changes the semantics of the tile offset: it is now subtracted when
drawing the picture tile. As a consequence, one can pass in a tile equal
to the cull rect and get the expected behavior (same when not passing
a tile).

This will require a minor Blink change with the roll, as one client
works around the current behavior:
https://codereview.chromium.org/789503003

R=reed@google.com,robertphillips@google.com
BUG=440046

Review URL: https://codereview.chromium.org/733203005
diff --git a/gm/pictureshadertile.cpp b/gm/pictureshadertile.cpp
index ecea553..ae87a55 100644
--- a/gm/pictureshadertile.cpp
+++ b/gm/pictureshadertile.cpp
@@ -21,68 +21,43 @@
     SkScalar offsetX, offsetY;
 } tiles[] = {
     {      0,      0,    1,    1,      0,    0 },
-    {   0.5f,   0.5f,    1,    1,      0,    0 },
     {  -0.5f,  -0.5f,    1,    1,      0,    0 },
+    {   0.5f,   0.5f,    1,    1,      0,    0 },
 
     {      0,      0, 1.5f, 1.5f,      0,    0 },
-    {   0.5f,   0.5f, 1.5f, 1.5f,      0,    0 },
     {  -0.5f,  -0.5f, 1.5f, 1.5f,      0,    0 },
+    {   0.5f,   0.5f, 1.5f, 1.5f,      0,    0 },
 
     {      0,      0, 0.5f, 0.5f,      0,    0 },
-    { -0.25f, -0.25f, 0.5f, 0.5f,      0,    0 },
     {  0.25f,  0.25f, 0.5f, 0.5f,      0,    0 },
+    { -0.25f, -0.25f, 0.5f, 0.5f,      0,    0 },
 
     {      0,      0,    1,    1,   0.5f, 0.5f },
-    {   0.5f,   0.5f,    1,    1,   0.5f, 0.5f },
     {  -0.5f,  -0.5f,    1,    1,   0.5f, 0.5f },
+    {   0.5f,   0.5f,    1,    1,   0.5f, 0.5f },
 
     {      0,      0, 1.5f, 1.5f,   0.5f, 0.5f },
-    {   0.5f,   0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
     {  -0.5f,  -0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
+    {   0.5f,   0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
 
     {      0,      0, 1.5f,    1,      0,    0 },
-    {   0.5f,   0.5f, 1.5f,    1,      0,    0 },
     {  -0.5f,  -0.5f, 1.5f,    1,      0,    0 },
+    {   0.5f,   0.5f, 1.5f,    1,      0,    0 },
 
     {      0,      0, 0.5f,    1,      0,    0 },
-    { -0.25f, -0.25f, 0.5f,    1,      0,    0 },
     {  0.25f,  0.25f, 0.5f,    1,      0,    0 },
+    { -0.25f, -0.25f, 0.5f,    1,      0,    0 },
 
     {      0,      0,    1, 1.5f,      0,    0 },
-    {   0.5f,   0.5f,    1, 1.5f,      0,    0 },
     {  -0.5f,  -0.5f,    1, 1.5f,      0,    0 },
+    {   0.5f,   0.5f,    1, 1.5f,      0,    0 },
 
     {      0,      0,    1, 0.5f,      0,    0 },
-    { -0.25f, -0.25f,    1, 0.5f,      0,    0 },
     {  0.25f,  0.25f,    1, 0.5f,      0,    0 },
+    { -0.25f, -0.25f,    1, 0.5f,      0,    0 },
 };
 
 class PictureShaderTileGM : public skiagm::GM {
-public:
-    PictureShaderTileGM() {
-        SkPictureRecorder recorder;
-        SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize, NULL, 0);
-        drawScene(pictureCanvas, kPictureSize);
-        SkAutoTUnref<SkPicture> picture(recorder.endRecording());
-
-        for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
-            SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
-                                           tiles[i].y * kPictureSize,
-                                           tiles[i].w * kPictureSize,
-                                           tiles[i].h * kPictureSize);
-            SkMatrix localMatrix;
-            localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
-                                     tiles[i].offsetY * kPictureSize);
-            localMatrix.postScale(kFillSize / (2 * kPictureSize),
-                                  kFillSize / (2 * kPictureSize));
-            fShaders[i].reset(SkShader::CreatePictureShader(picture,
-                              SkShader::kRepeat_TileMode,
-                              SkShader::kRepeat_TileMode,
-                              &localMatrix,
-                              &tile));
-        }
-    }
-
 protected:
     virtual uint32_t onGetFlags() const SK_OVERRIDE {
         return kSkipTiled_Flag;
@@ -96,6 +71,47 @@
         return SkISize::Make(800, 600);
     }
 
+    virtual void onOnceBeforeDraw() SK_OVERRIDE {
+        SkPictureRecorder recorder;
+        SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize);
+        drawScene(pictureCanvas, kPictureSize);
+        SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+
+        SkPoint offset = SkPoint::Make(100, 100);
+        pictureCanvas = recorder.beginRecording(SkRect::MakeXYWH(offset.x(), offset.y(),
+                                                                 kPictureSize, kPictureSize));
+        pictureCanvas->translate(offset.x(), offset.y());
+        drawScene(pictureCanvas, kPictureSize);
+        SkAutoTUnref<SkPicture> offsetPicture(recorder.endRecording());
+
+        for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
+            SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
+                                           tiles[i].y * kPictureSize,
+                                           tiles[i].w * kPictureSize,
+                                           tiles[i].h * kPictureSize);
+            SkMatrix localMatrix;
+            localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
+                                     tiles[i].offsetY * kPictureSize);
+            localMatrix.postScale(kFillSize / (2 * kPictureSize),
+                                  kFillSize / (2 * kPictureSize));
+
+            SkPicture* picturePtr = picture.get();
+            SkRect* tilePtr = &tile;
+
+            if (tile == SkRect::MakeWH(kPictureSize, kPictureSize)) {
+                // When the tile == picture bounds, exercise the picture + offset path.
+                picturePtr = offsetPicture.get();
+                tilePtr = NULL;
+            }
+
+            fShaders[i].reset(SkShader::CreatePictureShader(picturePtr,
+                              SkShader::kRepeat_TileMode,
+                              SkShader::kRepeat_TileMode,
+                              &localMatrix,
+                              tilePtr));
+        }
+    }
+
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         canvas->clear(SK_ColorBLACK);