First step in pulling SkPicturePlayback & SkPictureRecord out of SkPicture
This CL begins the process of making SkPicturePlayback & SkPictureRecord independent of SkPicture. It just moves the PathHeap into SkPicture to get a feel for where all this is going to lead.
Some items of note:
SkTimedPicture (debugger/QT) should wind up being just an SkPicturePlayback-derived object.
All the flattening & unflattening should migrate out of SkPicturePlayback and into SkPicture.
SkPicture::initForPlayback should eventually become something just SkPictureRecorder::endRecording calls.
SkPicture is passed into SkPicturePlayback's & SkPictureRecord's constructors. SkPicturePlayback only
holds onto a "const SkPicture*". The SkPicturePlayback:: CreateFromStream & CreateFromBuffer methods pass a non-const
SkPicture* down the call stack.
BUG=skia:2315
R=reed@google.com
Author: robertphillips@google.com
Review URL: https://codereview.chromium.org/249453002
git-svn-id: http://skia.googlecode.com/svn/trunk/src@14341 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkPicture.cpp b/core/SkPicture.cpp
index 316994a..05e5791 100644
--- a/core/SkPicture.cpp
+++ b/core/SkPicture.cpp
@@ -31,6 +31,10 @@
#include "GrContext.h"
#endif
+template <typename T> int SafeCount(const T* obj) {
+ return obj ? obj->count() : 0;
+}
+
#define DUMP_BUFFER_SIZE 65536
//#define ENABLE_TIME_DRAW // dumps milliseconds for each draw
@@ -139,17 +143,48 @@
it (since it is destructive, and we don't want to change src).
*/
if (src.fPlayback) {
- fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback));
+ fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fPlayback));
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, (*src.fRecord, info));
+ fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fRecord, info));
} else {
fPlayback = NULL;
}
+
+ fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
+}
+
+const SkPath& SkPicture::getPath(int index) const {
+ return (*fPathHeap.get())[index];
+}
+
+int SkPicture::addPathToHeap(const SkPath& path) {
+ if (NULL == fPathHeap) {
+ fPathHeap.reset(SkNEW(SkPathHeap));
+ }
+#ifdef SK_DEDUP_PICTURE_PATHS
+ return fPathHeap->insert(path);
+#else
+ return fPathHeap->append(path);
+#endif
+}
+
+void SkPicture::initForPlayback() const {
+ // ensure that the paths bounds are pre-computed
+ if (NULL != fPathHeap.get()) {
+ for (int i = 0; i < fPathHeap->count(); i++) {
+ (*fPathHeap.get())[i].updateBoundsCache();
+ }
+ }
+}
+
+void SkPicture::dumpSize() const {
+ SkDebugf("--- picture size: paths=%d\n",
+ SafeCount(fPathHeap.get()));
}
SkPicture::~SkPicture() {
@@ -171,6 +206,7 @@
SkTSwap(fAccelData, other.fAccelData);
SkTSwap(fWidth, other.fWidth);
SkTSwap(fHeight, other.fHeight);
+ fPathHeap.swap(&other.fPathHeap);
}
SkPicture* SkPicture::clone() const {
@@ -198,15 +234,17 @@
it (since it is destructive, and we don't want to change src).
*/
if (fPlayback) {
- clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, ©Info));
+ clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fPlayback, ©Info));
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, (*fRecord, info, true));
+ clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fRecord, info, true));
} else {
clone->fPlayback = NULL;
}
+
+ clone->fPathHeap.reset(SkSafeRef(fPathHeap.get()));
}
}
@@ -266,6 +304,7 @@
}
SkSafeUnref(fAccelData);
SkSafeSetNull(fRecord);
+ SkASSERT(NULL == fPathHeap);
this->needsNewGenID();
@@ -277,12 +316,12 @@
if (NULL != bbhFactory) {
SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
SkASSERT(NULL != tree);
- fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size,
+ fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size,
recordingFlags|
kOptimizeForClippedPlayback_RecordingFlag,
tree.get()));
} else {
- fRecord = SkNEW_ARGS(SkPictureRecord, (size, recordingFlags));
+ fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags));
}
fRecord->beginRecording();
@@ -323,7 +362,7 @@
fRecord->endRecording();
SkPictInfo info;
this->createHeader(&info);
- fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
+ fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
SkSafeSetNull(fRecord);
}
}
@@ -424,18 +463,20 @@
return NULL;
}
- SkPicturePlayback* playback;
+ SkPicture* newPict = SkNEW_ARGS(SkPicture, (NULL, info.fWidth, info.fHeight));
+
// Check to see if there is a playback to recreate.
if (stream->readBool()) {
- playback = SkPicturePlayback::CreateFromStream(stream, info, proc);
+ SkPicturePlayback* playback = SkPicturePlayback::CreateFromStream(newPict, stream,
+ info, proc);
if (NULL == playback) {
+ SkDELETE(newPict);
return NULL;
}
- } else {
- playback = NULL;
+ newPict->fPlayback = playback;
}
- return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
+ return newPict;
}
SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
@@ -445,18 +486,19 @@
return NULL;
}
- SkPicturePlayback* playback;
+ SkPicture* newPict = SkNEW_ARGS(SkPicture, (NULL, info.fWidth, info.fHeight));
+
// Check to see if there is a playback to recreate.
if (buffer.readBool()) {
- playback = SkPicturePlayback::CreateFromBuffer(buffer, info);
+ SkPicturePlayback* playback = SkPicturePlayback::CreateFromBuffer(newPict, buffer, info);
if (NULL == playback) {
+ SkDELETE(newPict);
return NULL;
}
- } else {
- playback = NULL;
+ newPict->fPlayback = playback;
}
- return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
+ return newPict;
}
void SkPicture::createHeader(SkPictInfo* info) const {
@@ -484,7 +526,7 @@
SkPictInfo info;
this->createHeader(&info);
if (NULL == playback && fRecord) {
- playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
+ playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
}
stream->write(&info, sizeof(info));
@@ -500,13 +542,49 @@
}
}
+void SkPicture::WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
+ buffer.writeUInt(tag);
+ buffer.writeUInt(SkToU32(size));
+}
+
+void SkPicture::WriteTagSize(SkWStream* stream, uint32_t tag, size_t size) {
+ stream->write32(tag);
+ stream->write32(SkToU32(size));
+}
+
+bool SkPicture::parseBufferTag(SkReadBuffer& buffer,
+ uint32_t tag,
+ uint32_t size) {
+ switch (tag) {
+ case SK_PICT_PATH_BUFFER_TAG:
+ if (size > 0) {
+ fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
+ }
+ break;
+ default:
+ // The tag was invalid.
+ return false;
+ }
+
+ return true; // success
+}
+
+void SkPicture::flattenToBuffer(SkWriteBuffer& buffer) const {
+ int n;
+
+ if ((n = SafeCount(fPathHeap.get())) > 0) {
+ WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n);
+ fPathHeap->flatten(buffer);
+ }
+}
+
void SkPicture::flatten(SkWriteBuffer& buffer) const {
SkPicturePlayback* playback = fPlayback;
SkPictInfo info;
this->createHeader(&info);
if (NULL == playback && fRecord) {
- playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
+ playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
}
buffer.writeByteArray(&info, sizeof(info));