work in progress

Review URL: https://codereview.chromium.org/769423002
diff --git a/experimental/tools/PageCachingDocument.cpp b/experimental/tools/PageCachingDocument.cpp
new file mode 100644
index 0000000..38e883e
--- /dev/null
+++ b/experimental/tools/PageCachingDocument.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "PageCachingDocument.h"
+#include "SkCanvas.h"
+#include "SkDocument.h"
+#include "SkPictureRecorder.h"
+#include "SkRect.h"
+#include "SkTDArray.h"
+
+namespace {
+
+typedef void (*DoneProc)(SkWStream*, bool);
+typedef SkData* (*Encoder)(size_t*, const SkBitmap&);
+
+// This class allows us to compare the relative memory consumption of
+// the PDF and SkPicture backends.
+class PageCachingDocument : public SkDocument {
+public:
+    PageCachingDocument(SkWStream*, DoneProc, Encoder, SkScalar rasterDpi);
+    virtual ~PageCachingDocument();
+    virtual SkCanvas* onBeginPage(SkScalar width,
+                                  SkScalar height,
+                                  const SkRect& content) SK_OVERRIDE;
+    virtual void onEndPage() SK_OVERRIDE;
+    virtual bool onClose(SkWStream*) SK_OVERRIDE;
+    virtual void onAbort() SK_OVERRIDE;
+
+private:
+    struct Page {
+        SkScalar fWidth;
+        SkScalar fHeight;
+        SkAutoTUnref<SkPicture> fPic;
+    };
+    SkPictureRecorder fRecorder;
+    SkTDArray<Page> fPages;
+    Encoder fEncoder;
+    SkScalar fRasterDpi;
+};
+
+PageCachingDocument::PageCachingDocument(SkWStream* stream,
+                                         DoneProc done,
+                                         Encoder encoder,
+                                         SkScalar rasterDpi)
+    : SkDocument(stream, done), fEncoder(encoder), fRasterDpi(rasterDpi) {
+}
+
+PageCachingDocument::~PageCachingDocument() {
+    for (Page* p = fPages.begin(); p != fPages.end(); ++p) {
+        p->~Page();
+    }
+}
+
+SkCanvas* PageCachingDocument::onBeginPage(SkScalar width,
+                                           SkScalar height,
+                                           const SkRect& content) {
+    Page* page = fPages.push();
+    sk_bzero(page, sizeof(*page));
+    page->fWidth = width;
+    page->fHeight = height;
+    SkASSERT(!page->fPic.get());
+    SkCanvas* canvas = fRecorder.beginRecording(content);
+    return canvas;
+}
+
+void PageCachingDocument::onEndPage() {
+    SkASSERT(fPages.count() > 0);
+    SkASSERT(!fPages[fPages.count() - 1].fPic);
+    fPages[fPages.count() - 1].fPic.reset(fRecorder.endRecording());
+}
+
+bool PageCachingDocument::onClose(SkWStream* stream) {
+    SkAutoTUnref<SkDocument> doc(
+        SkDocument::CreatePDF(stream, NULL, fEncoder, fRasterDpi));
+    for (Page* page = fPages.begin(); page != fPages.end(); ++page) {
+        SkRect cullRect = page->fPic->cullRect();
+        SkCanvas* canvas =
+            doc->beginPage(page->fWidth, page->fHeight, &cullRect);
+        canvas->drawPicture(page->fPic);
+        doc->endPage();
+    }
+    return doc->close();
+}
+
+void PageCachingDocument::onAbort() {
+}
+}  // namespace
+
+SkDocument* CreatePageCachingDocument(SkWStream* stream,
+                                      DoneProc done,
+                                      Encoder encoder,
+                                      SkScalar rasterDpi) {
+    return SkNEW_ARGS(PageCachingDocument, (stream, done, encoder, rasterDpi));
+}
diff --git a/experimental/tools/PageCachingDocument.h b/experimental/tools/PageCachingDocument.h
new file mode 100644
index 0000000..19be1ae
--- /dev/null
+++ b/experimental/tools/PageCachingDocument.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef PageCachingDocument_DEFINED
+#define PageCachingDocument_DEFINED
+
+#include "SkScalar.h"
+
+class SkBitmap;
+class SkData;
+class SkDocument;
+class SkWStream;
+
+SkDocument* CreatePageCachingDocument(
+    SkWStream* stream,
+    void (*done)(SkWStream*, bool) = NULL,
+    SkData* (*encoder)(size_t*, const SkBitmap&) = NULL,
+    SkScalar rasterDpi = 72.0);
+#endif  // PageCachingDocument_DEFINED
diff --git a/experimental/tools/gmtoskp.cpp b/experimental/tools/gmtoskp.cpp
index bafd3d3..124c7f6 100644
--- a/experimental/tools/gmtoskp.cpp
+++ b/experimental/tools/gmtoskp.cpp
@@ -28,7 +28,7 @@
                "If a GM does not match any list entry,\n"
                "it is skipped unless some list entry starts with ~");
 
-DEFINE_string2(writePath, w, "", "Write output here as .skps.");
+DEFINE_string2(writePath, w, "", "Write output in this directory as .skps.");
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
 
@@ -49,11 +49,13 @@
     SkCommandLineFlags::SetUsage("");
     SkCommandLineFlags::Parse(argc, argv);
     if (FLAGS_writePath.isEmpty()) {
+        SkDebugf("You need to specify a --writePath option");
         return 1;
     }
     const char* writePath = FLAGS_writePath[0];
     if (!sk_mkdir(writePath)) {
-        return 1;
+        
+        return 2;
     }
     for (const skiagm::GMRegistry* reg = skiagm::GMRegistry::Head();
          reg != NULL;
@@ -69,7 +71,7 @@
             SkFILEWStream outputStream(path.c_str());
             if (!outputStream.isValid()) {
                 SkDebugf("Could not open file %s\n", path.c_str());
-                return 1;
+                return 3;
             }
             gmtoskp(gm, &outputStream);
         }
diff --git a/experimental/tools/multipage_pdf_profiler.cpp b/experimental/tools/multipage_pdf_profiler.cpp
index 93c8df9..4f8eae2 100644
--- a/experimental/tools/multipage_pdf_profiler.cpp
+++ b/experimental/tools/multipage_pdf_profiler.cpp
@@ -12,19 +12,16 @@
 #include "SkPicture.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
+#include "PageCachingDocument.h"
 #include "ProcStats.h"
 #include "flags/SkCommandLineFlags.h"
 
-#ifdef SK_ENABLE_NEW_SKPDF_BACKEND
-#include "skpdf.h"
-#endif
-
 DEFINE_string2(readPath,
                r,
                "",
                "(Required)  The path to a .skp Skia Picture file.");
 DEFINE_string2(writePath, w, "", "If set, write PDF output to this file.");
-DEFINE_bool(newPdf, false, "Use the new PDF backend.");
+DEFINE_bool(cachePages, false, "Use a PageCachingDocument.");
 DEFINE_bool(nullCanvas, true, "Render to a SkNullCanvas as a control.");
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
@@ -45,12 +42,11 @@
 };
 
 SkDocument* CreatePDFDocument(SkWStream* out) {
-#ifdef SK_ENABLE_NEW_SKPDF_BACKEND
-    if (FLAGS_newPdf) {
-        return skpdf::CreatePDFDocument(out);
+    if (FLAGS_cachePages) {
+        return CreatePageCachingDocument(out);
+    } else {
+        return SkDocument::CreatePDF(out);
     }
-#endif
-    return SkDocument::CreatePDF(out);
 }
 }  // namespace
 
@@ -119,7 +115,8 @@
                 canvas->clipRect(letterRect);
                 canvas->translate(SkIntToScalar(-kLetterWidth * x),
                                   SkIntToScalar(-kLetterHeight * y));
-                canvas->drawPicture(picture);
+                picture->playback(canvas);
+                //canvas->drawPicture(picture);
             }
             canvas->flush();
             if (!FLAGS_nullCanvas) {
diff --git a/gm/smallimage.cpp b/gm/smallimage.cpp
new file mode 100644
index 0000000..6eb48d8
--- /dev/null
+++ b/gm/smallimage.cpp
@@ -0,0 +1,11 @@
+#include "Resources.h"
+#include "gm.h"
+
+DEF_SIMPLE_GM(small_image, canvas, 8, 8) {
+    SkBitmap bitmap;
+    if (GetResourceAsBitmap("randPixels.png", &bitmap)) {
+        canvas->drawBitmap(bitmap, 0.0f, 0.0f);
+    } else {
+        SkDebugf("\nCould not decode resource.\n");
+    }
+}
diff --git a/gyp/experimental.gyp b/gyp/experimental.gyp
index 9e4e934..87fe920 100644
--- a/gyp/experimental.gyp
+++ b/gyp/experimental.gyp
@@ -79,6 +79,7 @@
       'type': 'executable',
       'sources': [
         '../experimental/tools/multipage_pdf_profiler.cpp',
+        '../experimental/tools/PageCachingDocument.cpp',
       ],
       'dependencies': [
         'skia_lib.gyp:skia_lib',
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index 5e1ae47..bba3ea0 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -170,6 +170,7 @@
         '../gm/simpleaaclip.cpp',
         '../gm/skbug1719.cpp',
         '../gm/smallarc.cpp',
+        '../gm/smallimage.cpp',
         '../gm/stringart.cpp',
         '../gm/spritebitmap.cpp',
         '../gm/srcmode.cpp',