Add choke point for performing a fake endRecording

My goal here was to add a single location where we could patch up the created PicturePlayback. Unfortunately, the complexity of the recording process (e.g., the BBH) makes this quite complex.

I will investigate altering the behavior of SkPicturePlayback to account for a potentially unbalanced set of saves/saveLayers.

R=reed@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/283333007

git-svn-id: http://skia.googlecode.com/svn/trunk@14773 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index c0b776c..e17a0d4 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -472,6 +472,9 @@
 
     void createHeader(SkPictInfo* info) const;
     static bool IsValidPictInfo(const SkPictInfo& info);
+    static SkPicturePlayback* FakeEndRecording(const SkPicture* resourceSrc,
+                                               const SkPictureRecord& record,
+                                               bool deepCopy);
 
     friend class SkFlatPicture;
     friend class SkPicturePlayback;
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 6843430..0f016ac 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -131,6 +131,17 @@
     fWidth = fHeight = 0;
 }
 
+// This method makes a SkPicturePlayback object from an in-progress recording.
+// Unfortunately, it does not include the restoreToCount of a real endRecording
+// call.
+SkPicturePlayback* SkPicture::FakeEndRecording(const SkPicture* resourceSrc,
+                                               const SkPictureRecord& record,
+                                               bool deepCopy) {
+    SkPictInfo info;
+    resourceSrc->createHeader(&info);
+    return SkNEW_ARGS(SkPicturePlayback, (resourceSrc, record, info, deepCopy));
+}
+
 SkPicture::SkPicture(const SkPicture& src)
     : INHERITED()
     , fAccelData(NULL)
@@ -149,10 +160,7 @@
         SkASSERT(NULL == src.fRecord);
         fUniqueID = src.uniqueID();     // need to call method to ensure != 0
     } else if (src.fRecord) {
-        SkPictInfo info;
-        this->createHeader(&info);
-        // here we do a fake src.endRecording()
-        fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fRecord, info));
+        fPlayback = FakeEndRecording(this, *src.fRecord, false);
     } else {
         fPlayback = NULL;
     }
@@ -220,8 +228,6 @@
 
 void SkPicture::clone(SkPicture* pictures, int count) const {
     SkPictCopyInfo copyInfo;
-    SkPictInfo info;
-    this->createHeader(&info);
 
     for (int i = 0; i < count; i++) {
         SkPicture* clone = &pictures[i];
@@ -284,8 +290,7 @@
             SkASSERT(NULL == fRecord);
             clone->fUniqueID = this->uniqueID(); // need to call method to ensure != 0
         } else if (fRecord) {
-            // here we do a fake src.endRecording()
-            clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fRecord, info, true));
+            clone->fPlayback = FakeEndRecording(clone, *fRecord, true);
         } else {
             clone->fPlayback = NULL;
         }
@@ -571,12 +576,12 @@
 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
     SkPicturePlayback* playback = fPlayback;
 
-    SkPictInfo info;
-    this->createHeader(&info);
     if (NULL == playback && fRecord) {
-        playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
+        playback = FakeEndRecording(this, *fRecord, false);
     }
 
+    SkPictInfo info;
+    this->createHeader(&info);
     stream->write(&info, sizeof(info));
     if (playback) {
         stream->writeBool(true);
@@ -629,12 +634,12 @@
 void SkPicture::flatten(SkWriteBuffer& buffer) const {
     SkPicturePlayback* playback = fPlayback;
 
-    SkPictInfo info;
-    this->createHeader(&info);
     if (NULL == playback && fRecord) {
-        playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
+        playback = FakeEndRecording(this, *fRecord, false);
     }
 
+    SkPictInfo info;
+    this->createHeader(&info);
     buffer.writeByteArray(&info, sizeof(info));
     if (playback) {
         buffer.writeBool(true);