Index: src/core/SkPictureRecorder.cpp |
diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp |
index 3262938ed1b62817fda591dfe360ee89269e7ea6..d64390c6ef80d58e0c3c26015f8b80ad24b7c02b 100644 |
--- a/src/core/SkPictureRecorder.cpp |
+++ b/src/core/SkPictureRecorder.cpp |
@@ -5,6 +5,7 @@ |
* found in the LICENSE file. |
*/ |
+#include "SkCanvasDrawable.h" |
#include "SkData.h" |
#include "SkLayerInfo.h" |
#include "SkPictureRecorder.h" |
@@ -14,7 +15,7 @@ |
#include "SkRecordOpts.h" |
#include "SkTypes.h" |
-SkPictureRecorder::SkPictureRecorder() {} |
+SkPictureRecorder::SkPictureRecorder() : fBBHFactory(NULL) {} |
SkPictureRecorder::~SkPictureRecorder() {} |
@@ -22,6 +23,7 @@ SkCanvas* SkPictureRecorder::beginRecording(const SkRect& cullRect, |
SkBBHFactory* bbhFactory /* = NULL */, |
uint32_t recordFlags /* = 0 */) { |
fCullRect = cullRect; |
+ fBBHFactory = bbhFactory; |
fFlags = recordFlags; |
if (bbhFactory) { |
@@ -38,7 +40,7 @@ SkCanvas* SkPictureRecorder::getRecordingCanvas() { |
return fRecorder.get(); |
} |
-SkPicture* SkPictureRecorder::endRecording() { |
+SkPicture* SkPictureRecorder::endRecordingAsPicture() { |
// TODO: delay as much of this work until just before first playback? |
SkRecordOptimize(fRecord); |
@@ -50,26 +52,23 @@ SkPicture* SkPictureRecorder::endRecording() { |
saveLayerData.reset(SkNEW_ARGS(SkLayerInfo, (key))); |
} |
+ SkCanvasDrawableList* drawableList = fRecorder->getDrawableList(); |
+ SkPicture::SnapshotArray* pictList = drawableList ? drawableList->newDrawableSnapshot() : NULL; |
+ |
if (fBBH.get()) { |
if (saveLayerData) { |
- SkRecordComputeLayers(fCullRect, *fRecord, fBBH.get(), saveLayerData); |
+ SkRecordComputeLayers(fCullRect, *fRecord, pictList, fBBH.get(), saveLayerData); |
} else { |
SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); |
} |
} |
- // TODO: we should remember these from our caller |
- SkBBHFactory* factory = NULL; |
- uint32_t recordFlags = 0; |
- SkAutoTDelete<SkPicture::SnapshotArray> drawablePicts( |
- fRecorder->newDrawableSnapshot(factory, recordFlags)); |
- SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullRect, fRecord.detach(), |
- drawablePicts.detach(), fBBH.get())); |
+ SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullRect, fRecord, pictList, fBBH)); |
if (saveLayerData) { |
pict->EXPERIMENTAL_addAccelData(saveLayerData); |
} |
- |
+ |
return pict; |
} |
@@ -79,5 +78,86 @@ void SkPictureRecorder::partialReplay(SkCanvas* canvas) const { |
} |
int drawableCount = 0; |
- SkRecordDraw(*fRecord, canvas, NULL, drawableCount, NULL/*bbh*/, NULL/*callback*/); |
+ SkCanvasDrawable* const* drawables = NULL; |
+ SkCanvasDrawableList* drawableList = fRecorder->getDrawableList(); |
+ if (drawableList) { |
+ drawableCount = drawableList->count(); |
+ drawables = drawableList->begin(); |
+ } |
+ SkRecordDraw(*fRecord, canvas, NULL, drawables, drawableCount, NULL/*bbh*/, NULL/*callback*/); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+class SkRecordedDrawable : public SkCanvasDrawable { |
+ SkAutoTUnref<SkRecord> fRecord; |
+ SkAutoTUnref<SkBBoxHierarchy> fBBH; |
+ SkAutoTDelete<SkCanvasDrawableList> fDrawableList; |
+ const SkRect fBounds; |
+ const bool fDoSaveLayerInfo; |
+ |
+public: |
+ SkRecordedDrawable(SkRecord* record, SkBBoxHierarchy* bbh, SkCanvasDrawableList* drawableList, |
+ const SkRect& bounds, bool doSaveLayerInfo) |
+ : fRecord(SkRef(record)) |
+ , fBBH(SkSafeRef(bbh)) |
+ , fDrawableList(drawableList) // we take ownership |
+ , fBounds(bounds) |
+ , fDoSaveLayerInfo(doSaveLayerInfo) |
+ {} |
+ |
+protected: |
+ SkRect onGetBounds() SK_OVERRIDE { return fBounds; } |
+ |
+ void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
+ SkCanvasDrawable* const* drawables = NULL; |
+ int drawableCount = 0; |
+ if (fDrawableList) { |
+ drawables = fDrawableList->begin(); |
+ drawableCount = fDrawableList->count(); |
+ } |
+ SkRecordDraw(*fRecord, canvas, NULL, drawables, drawableCount, fBBH, NULL/*callback*/); |
+ } |
+ |
+ SkPicture* onNewPictureSnapshot() SK_OVERRIDE { |
+ SkPicture::SnapshotArray* pictList = NULL; |
+ if (fDrawableList) { |
+ // TODO: should we plumb-down the BBHFactory and recordFlags from our host |
+ // PictureRecorder? |
+ pictList = fDrawableList->newDrawableSnapshot(); |
+ } |
+ |
+ SkAutoTUnref<SkLayerInfo> saveLayerData; |
+ |
+ if (fBBH && fDoSaveLayerInfo) { |
+ SkPicture::AccelData::Key key = SkLayerInfo::ComputeKey(); |
+ |
+ saveLayerData.reset(SkNEW_ARGS(SkLayerInfo, (key))); |
+ |
+ SkBBoxHierarchy* bbh = NULL; // we've already computed fBBH (received in constructor) |
+ // TODO: update saveLayer info computation to reuse the already computed |
+ // bounds in 'fBBH' |
+ SkRecordComputeLayers(fBounds, *fRecord, pictList, bbh, saveLayerData); |
+ } |
+ |
+ SkPicture* pict = SkNEW_ARGS(SkPicture, (fBounds, fRecord, pictList, fBBH)); |
+ |
+ if (saveLayerData) { |
+ pict->EXPERIMENTAL_addAccelData(saveLayerData); |
+ } |
+ return pict; |
+ } |
+}; |
+ |
+SkCanvasDrawable* SkPictureRecorder::EXPERIMENTAL_endRecordingAsDrawable() { |
+ // TODO: delay as much of this work until just before first playback? |
+ SkRecordOptimize(fRecord); |
+ |
+ if (fBBH.get()) { |
+ SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); |
+ } |
+ |
+ return SkNEW_ARGS(SkRecordedDrawable, (fRecord, fBBH, fRecorder->detachDrawableList(), |
+ fCullRect, |
+ SkToBool(fFlags & kComputeSaveLayerInfo_RecordFlag))); |
} |