[go: nahoru, domu]

Implement multi-threaded picture playback via cloning.

The CL adds SkPicture.clone() which produces a thread-safe copy by
creating a shallow copy of the thread-safe data within the picture and
a deep copy of the data that is not (e.g. SkPaint).  This implementation
re-flattens the paints when cloning instead of retaining the flattened
paints from the recording process.

Changes were also needed to various classes to ensure thread safety

Review URL: https://codereview.appspot.com/6459105

git-svn-id: http://skia.googlecode.com/svn/trunk/src@5335 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkPicture.cpp b/core/SkPicture.cpp
index 70e329e..13c5f6c 100644
--- a/core/SkPicture.cpp
+++ b/core/SkPicture.cpp
@@ -138,6 +138,37 @@
     SkTSwap(fHeight, other.fHeight);
 }
 
+SkPicture* SkPicture::clone() const {
+    SkPicture* clonedPicture = SkNEW(SkPicture);
+    clone(clonedPicture, 1);
+    return clonedPicture;
+}
+
+void SkPicture::clone(SkPicture* pictures, int count) const {
+    SkPictCopyInfo copyInfo;
+
+    for (int i = 0; i < count; i++) {
+        SkPicture* clone = &pictures[i];
+
+        clone->fWidth = fWidth;
+        clone->fHeight = fHeight;
+        clone->fRecord = NULL;
+
+        /*  We want to copy the src's playback. However, if that hasn't been built
+            yet, we need to fake a call to endRecording() without actually calling
+            it (since it is destructive, and we don't want to change src).
+         */
+        if (fPlayback) {
+            clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyInfo));
+        } else if (fRecord) {
+            // here we do a fake src.endRecording()
+            clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, true));
+        } else {
+            clone->fPlayback = NULL;
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 SkCanvas* SkPicture::beginRecording(int width, int height,