Sketch splitting SkPicture into an interface and SkBigPicture.

Adds small pictures for drawRect(), drawTextBlob(), and drawPath().
These cover about 89% of draw calls from Blink SKPs,
and about 25% of draw calls from our GMs.

SkPicture handles:
  - serialization and deserialization
  - unique IDs

Everything else is left to the subclasses:
  - playback(), cullRect()
  - hasBitmap(), hasText(), suitableForGPU(), etc.
  - LayerInfo / AccelData if applicable.

The time to record a 1-op picture improves a good chunk
(2 mallocs to 1), and the time to record a 0-op picture
greatly improves (2 mallocs to none):

    picture_overhead_draw:   450ns -> 350ns
    picture_overhead_nodraw: 300ns -> 90ns

BUG=skia:

Committed: https://skia.googlesource.com/skia/+/c92c129ff85b05a714bd1bf921c02d5e14651f8b

Latest blink_linux_rel:

http://build.chromium.org/p/tryserver.blink/builders/linux_blink_rel/builds/61248

Committed: https://skia.googlesource.com/skia/+/15877b6eae33a9282458bdb904a6d00440eca0ec

http://build.chromium.org/p/tryserver.blink/builders/linux_blink_rel/builds/62015

Review URL: https://codereview.chromium.org/1112523006
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 0a2d43e..45283f8 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "SkBigPicture.h"
 #include "SkPatchUtils.h"
 #include "SkPicture.h"
 #include "SkPictureUtils.h"
@@ -14,7 +15,7 @@
     fArray.unrefAll();
 }
 
-SkPicture::SnapshotArray* SkDrawableList::newDrawableSnapshot() {
+SkBigPicture::SnapshotArray* SkDrawableList::newDrawableSnapshot() {
     const int count = fArray.count();
     if (0 == count) {
         return NULL;
@@ -23,7 +24,7 @@
     for (int i = 0; i < count; ++i) {
         pics[i] = fArray[i]->newPictureSnapshot();
     }
-    return SkNEW_ARGS(SkPicture::SnapshotArray, (pics.detach(), count));
+    return SkNEW_ARGS(SkBigPicture::SnapshotArray, (pics.detach(), count));
 }
 
 void SkDrawableList::append(SkDrawable* drawable) {
@@ -32,20 +33,23 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-SkRecorder::SkRecorder(SkRecord* record, int width, int height)
+SkRecorder::SkRecorder(SkRecord* record, int width, int height, SkMiniRecorder* mr)
     : SkCanvas(SkIRect::MakeWH(width, height), SkCanvas::kConservativeRasterClip_InitFlag)
     , fApproxBytesUsedBySubPictures(0)
-    , fRecord(record) {}
+    , fRecord(record)
+    , fMiniRecorder(mr) {}
 
-SkRecorder::SkRecorder(SkRecord* record, const SkRect& bounds)
+SkRecorder::SkRecorder(SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr)
     : SkCanvas(bounds.roundOut(), SkCanvas::kConservativeRasterClip_InitFlag)
     , fApproxBytesUsedBySubPictures(0)
-    , fRecord(record) {}
+    , fRecord(record)
+    , fMiniRecorder(mr) {}
 
-void SkRecorder::reset(SkRecord* record, const SkRect& bounds) {
+void SkRecorder::reset(SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr) {
     this->forgetRecord();
     fRecord = record;
     this->resetForNextPicture(bounds.roundOut());
+    fMiniRecorder = mr;
 }
 
 void SkRecorder::forgetRecord() {
@@ -55,9 +59,13 @@
 }
 
 // To make appending to fRecord a little less verbose.
-#define APPEND(T, ...) \
+#define APPEND(T, ...)                                    \
+        if (fMiniRecorder) { this->flushMiniRecorder(); } \
         SkNEW_PLACEMENT_ARGS(fRecord->append<SkRecords::T>(), SkRecords::T, (__VA_ARGS__))
 
+#define TRY_MINIRECORDER(method, ...)                       \
+    if (fMiniRecorder && fMiniRecorder->method(__VA_ARGS__)) { return; }
+
 // For methods which must call back into SkCanvas.
 #define INHERITED(method, ...) this->SkCanvas::method(__VA_ARGS__)
 
@@ -125,6 +133,15 @@
     return this->copy(src, strlen(src)+1);
 }
 
+void SkRecorder::flushMiniRecorder() {
+    if (fMiniRecorder) {
+        SkMiniRecorder* mr = fMiniRecorder;
+        fMiniRecorder = nullptr;  // Needs to happen before p->playback(this) or we loop forever.
+        // TODO: this can probably be done more efficiently by SkMiniRecorder if it matters.
+        SkAutoTUnref<SkPicture> p(mr->detachAsPicture(SkRect::MakeEmpty()));
+        p->playback(this);
+    }
+}
 
 void SkRecorder::onDrawPaint(const SkPaint& paint) {
     APPEND(DrawPaint, delay_copy(paint));
@@ -138,6 +155,7 @@
 }
 
 void SkRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) {
+    TRY_MINIRECORDER(drawRect, rect, paint);
     APPEND(DrawRect, delay_copy(paint), rect);
 }
 
@@ -162,6 +180,7 @@
 }
 
 void SkRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) {
+    TRY_MINIRECORDER(drawPath, path, paint);
     APPEND(DrawPath, delay_copy(paint), delay_copy(path));
 }
 
@@ -248,6 +267,7 @@
 
 void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                 const SkPaint& paint) {
+    TRY_MINIRECORDER(drawTextBlob, blob, x, y, paint);
     APPEND(DrawTextBlob, delay_copy(paint), blob, x, y);
 }