Add tiled rendering as an option to GM.

Use an SkGPipe to play back drawing into tiles.
This will help us to debug differences in drawing
while tiled.

Pass --tiledPipe to gm to use the tiled pipe.
Review URL: https://codereview.appspot.com/6295050

git-svn-id: http://skia.googlecode.com/svn/trunk@4199 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 08c7c52..34ded4a 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -20,8 +20,9 @@
 #include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkPicture.h"
-#include "SkStream.h"
 #include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SamplePipeControllers.h"
 
 static bool gForceBWtext;
 
@@ -619,45 +620,6 @@
     }
 }
 
-class PipeController : public SkGPipeController {
-public:
-    PipeController(SkCanvas* target);
-    ~PipeController();
-    virtual void* requestBlock(size_t minRequest, size_t* actual);
-    virtual void notifyWritten(size_t bytes);
-private:
-    SkGPipeReader fReader;
-    void* fBlock;
-    size_t fBlockSize;
-    size_t fBytesWritten;
-    SkGPipeReader::Status fStatus;
-};
-
-PipeController::PipeController(SkCanvas* target)
-:fReader(target) {
-    fBlock = NULL;
-    fBlockSize = fBytesWritten = 0;
-}
-
-PipeController::~PipeController() {
-    sk_free(fBlock);
-}
-
-void* PipeController::requestBlock(size_t minRequest, size_t *actual) {
-    sk_free(fBlock);
-    fBlockSize = minRequest * 4;
-    fBlock = sk_malloc_throw(fBlockSize);
-    fBytesWritten = 0;
-    *actual = fBlockSize;
-    return fBlock;
-}
-
-void PipeController::notifyWritten(size_t bytes) {
-    fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes);
-    SkASSERT(SkGPipeReader::kError_Status != fStatus);
-    fBytesWritten += bytes;
-}
-
 static ErrorBitfield test_pipe_playback(GM* gm,
                                         const ConfigData& gRec,
                                         const SkBitmap& comparisonBitmap,
@@ -680,6 +642,27 @@
                                "-pipe", bitmap, NULL, &comparisonBitmap);
 }
 
+static ErrorBitfield test_tiled_pipe_playback(GM* gm,
+                                        const ConfigData& gRec,
+                                        const SkBitmap& comparisonBitmap,
+                                        const char readPath [],
+                                        const char diffPath []) {
+    if (kRaster_Backend != gRec.fBackend) {
+        return ERROR_NONE;
+    }
+    SkBitmap bitmap;
+    SkISize size = gm->getISize();
+    setup_bitmap(gRec, size, &bitmap);
+    TiledPipeController pipeController(bitmap);
+    SkGPipeWriter writer;
+    SkCanvas* pipeCanvas = writer.startRecording(&pipeController,
+                                                 SkGPipeWriter::kCrossProcess_Flag);
+    invokeGM(gm, pipeCanvas);
+    writer.endRecording();
+    return handle_test_results(gm, gRec, NULL, NULL, diffPath,
+                               "-tiled pipe", bitmap, NULL, &comparisonBitmap);
+}
+
 static void write_picture_serialization(GM* gm, const ConfigData& rec,
                                         const char writePicturePath[]) {
     // only do this once, so we pick raster
@@ -701,6 +684,7 @@
     SkDebugf(
         "%s [-w writePath] [-r readPath] [-d diffPath] [-i resourcePath]\n"
         "    [--noreplay] [--pipe] [--serialize] [--forceBWtext] [--nopdf] \n"
+        "    [--tiledPipe] \n"
         "    [--nodeferred] [--match substring] [--notexturecache]\n"
         , argv0);
     SkDebugf("    writePath: directory to write rendered images in.\n");
@@ -711,6 +695,7 @@
     SkDebugf("    resourcePath: directory that stores image resources.\n");
     SkDebugf("    --noreplay: do not exercise SkPicture replay.\n");
     SkDebugf("    --pipe: Exercise SkGPipe replay.\n");
+    SkDebugf("    --tiledPipe: Exercise tiled SkGPipe replay.\n");
     SkDebugf(
 "    --serialize: exercise SkPicture serialization & deserialization.\n");
     SkDebugf("    --forceBWtext: disable text anti-aliasing.\n");
@@ -823,6 +808,7 @@
     bool doPDF = true;
     bool doReplay = true;
     bool doPipe = false;
+    bool doTiledPipe = false;
     bool doSerialize = false;
     bool doDeferred = true;
     bool disableTextureCache = false;
@@ -861,6 +847,8 @@
             gForceBWtext = true;
         } else if (strcmp(*argv, "--pipe") == 0) {
             doPipe = true;
+        } else if (strcmp(*argv, "--tiledPipe") == 0) {
+            doTiledPipe = true;
         } else if (strcmp(*argv, "--noreplay") == 0) {
             doReplay = false;
         } else if (strcmp(*argv, "--nopdf") == 0) {
@@ -1007,6 +995,13 @@
                                                  readPath, diffPath);
             }
 
+            if ((ERROR_NONE == testErrors) && doTiledPipe &&
+                !(gmFlags & GM::kSkipPipe_Flag)) {
+                testErrors |= test_tiled_pipe_playback(gm, gRec[i],
+                                                 forwardRenderedBitmap,
+                                                 readPath, diffPath);
+            }
+
             if ((ERROR_NONE == testErrors) && doSerialize  &&
                 !(gmFlags & GM::kSkipPicture_Flag)) {
                 testErrors |= test_picture_serialization(gm, gRec[i],