diff options
author | reed <reed@google.com> | 2014-11-24 14:41:51 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-24 14:41:51 -0800 |
commit | 1bdfd3f4f09e47364f76d3f08177b1ce844ac786 (patch) | |
tree | 91b83cdc89f884513bacac06ee8f008f4e8276f8 /src/core/SkPictureRecorder.cpp | |
parent | 89ff0846fd9dacf5f081373746624d450a5f8c26 (diff) |
option to return drawable from recording
patch from issue 747033005 at patchset 80001 (http://crrev.com/747033005#ps80001)
BUG=skia:
Review URL: https://codereview.chromium.org/732653004
Diffstat (limited to 'src/core/SkPictureRecorder.cpp')
-rw-r--r-- | src/core/SkPictureRecorder.cpp | 104 |
1 files changed, 92 insertions, 12 deletions
diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index 3262938ed1..d64390c6ef 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))); } |