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, ©Info));
+ } 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,