diff options
author | mtklein <mtklein@chromium.org> | 2015-10-24 07:45:47 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-24 07:45:47 -0700 |
commit | 40732b34a1bf94eb44ee4b2327eece8d97735f11 (patch) | |
tree | c38580dad6fbf4a4abcf8885b53656b3d9757f14 /src | |
parent | 6df232d251cefe8f3498a1ae4dad449bafa9ebb3 (diff) |
SkRecord refactor: fill bounds array instead of BBH directly
This should be a strict refactor, just pulling out the bounds array.
(It's the rescued nice parts of a dead-end CL targeting skia:4492.)
BUG=skia:
Review URL: https://codereview.chromium.org/1424553002
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkPictureRecorder.cpp | 21 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 54 | ||||
-rw-r--r-- | src/core/SkRecordDraw.h | 12 |
3 files changed, 41 insertions, 46 deletions
diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index 6397ca00fa..62fa0e968f 100644 --- a/src/core/SkPictureRecorder.cpp +++ b/src/core/SkPictureRecorder.cpp @@ -72,11 +72,16 @@ SkPicture* SkPictureRecorder::endRecordingAsPicture() { drawableList ? drawableList->newDrawableSnapshot() : nullptr; if (fBBH.get()) { + SkAutoTMalloc<SkRect> bounds(fRecord->count()); if (saveLayerData) { - SkRecordComputeLayers(fCullRect, *fRecord, pictList, fBBH.get(), saveLayerData); + SkRecordComputeLayers(fCullRect, *fRecord, bounds, pictList, saveLayerData); } else { - SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); + SkRecordFillBounds(fCullRect, *fRecord, bounds); } + fBBH->insert(bounds, fRecord->count()); + + // Now that we've calculated content bounds, we can update fCullRect, often trimming it. + // TODO: get updated fCullRect from bounds instead of forcing the BBH to return it? SkRect bbhBound = fBBH->getRootBound(); SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound)) || (bbhBound.isEmpty() && fCullRect.isEmpty())); @@ -153,14 +158,12 @@ protected: } SkAutoTUnref<SkLayerInfo> saveLayerData; - if (fBBH && fDoSaveLayerInfo) { + // TODO: can we avoid work by not allocating / filling these bounds? + SkAutoTMalloc<SkRect> scratchBounds(fRecord->count()); saveLayerData.reset(new SkLayerInfo); - SkBBoxHierarchy* bbh = nullptr; // 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); + SkRecordComputeLayers(fBounds, *fRecord, scratchBounds, pictList, saveLayerData); } size_t subPictureBytes = 0; @@ -183,7 +186,9 @@ SkDrawable* SkPictureRecorder::endRecordingAsDrawable() { SkRecordOptimize(fRecord); if (fBBH.get()) { - SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); + SkAutoTMalloc<SkRect> bounds(fRecord->count()); + SkRecordFillBounds(fCullRect, *fRecord, bounds); + fBBH->insert(bounds, fRecord->count()); } SkDrawable* drawable = diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 12920da361..ab0cb71407 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -150,20 +150,15 @@ template <> void Draw::draw(const DrawDrawable& r) { // in for all the control ops we stashed away. class FillBounds : SkNoncopyable { public: - FillBounds(const SkRect& cullRect, const SkRecord& record) + FillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[]) : fNumRecords(record.count()) , fCullRect(cullRect) - , fBounds(record.count()) - { - // Calculate bounds for all ops. This won't go quite in order, so we'll need - // to store the bounds separately then feed them in to the BBH later in order. + , fBounds(bounds) { fCTM = &SkMatrix::I(); fCurrentClipBounds = fCullRect; } - void setCurrentOp(int currentOp) { fCurrentOp = currentOp; } - - void cleanUp(SkBBoxHierarchy* bbh) { + void cleanUp() { // If we have any lingering unpaired Saves, simulate restores to make // sure all ops in those Save blocks have their bounds calculated. while (!fSaveStack.isEmpty()) { @@ -174,13 +169,11 @@ public: while (!fControlIndices.isEmpty()) { this->popControl(fCullRect); } - - // Finally feed all stored bounds into the BBH. They'll be returned in this order. - if (bbh) { - bbh->insert(fBounds.get(), fNumRecords); - } } + void setCurrentOp(int currentOp) { fCurrentOp = currentOp; } + + template <typename T> void operator()(const T& op) { this->updateCTM(op); this->updateClipBounds(op); @@ -580,7 +573,7 @@ private: const SkRect fCullRect; // Conservative identity-space bounds for each op in the SkRecord. - SkAutoTMalloc<Bounds> fBounds; + Bounds* fBounds; // We walk fCurrentOp through the SkRecord, as we go using updateCTM() // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative @@ -597,27 +590,27 @@ private: // SkRecord visitor to gather saveLayer/restore information. class CollectLayers : SkNoncopyable { public: - CollectLayers(const SkRect& cullRect, const SkRecord& record, + CollectLayers(const SkRect& cullRect, const SkRecord& record, SkRect bounds[], const SkBigPicture::SnapshotArray* pictList, SkLayerInfo* accelData) : fSaveLayersInStack(0) , fAccelData(accelData) , fPictList(pictList) - , fFillBounds(cullRect, record) + , fFillBounds(cullRect, record, bounds) {} - void setCurrentOp(int currentOp) { fFillBounds.setCurrentOp(currentOp); } - - void cleanUp(SkBBoxHierarchy* bbh) { + void cleanUp() { // fFillBounds must perform its cleanUp first so that all the bounding // boxes associated with unbalanced restores are updated (prior to // fetching their bound in popSaveLayerInfo). - fFillBounds.cleanUp(bbh); - + fFillBounds.cleanUp(); while (!fSaveLayerStack.isEmpty()) { this->popSaveLayerInfo(); } } + void setCurrentOp(int currentOp) { fFillBounds.setCurrentOp(currentOp); } + + template <typename T> void operator()(const T& op) { fFillBounds(op); this->trackSaveLayers(op); @@ -792,27 +785,22 @@ private: } // namespace SkRecords -void SkRecordFillBounds(const SkRect& cullRect, const SkRecord& record, SkBBoxHierarchy* bbh) { - SkRecords::FillBounds visitor(cullRect, record); - +void SkRecordFillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[]) { + SkRecords::FillBounds visitor(cullRect, record, bounds); for (int curOp = 0; curOp < record.count(); curOp++) { visitor.setCurrentOp(curOp); record.visit<void>(curOp, visitor); } - - visitor.cleanUp(bbh); + visitor.cleanUp(); } -void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, - const SkBigPicture::SnapshotArray* pictList, SkBBoxHierarchy* bbh, - SkLayerInfo* data) { - SkRecords::CollectLayers visitor(cullRect, record, pictList, data); - +void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, SkRect bounds[], + const SkBigPicture::SnapshotArray* pictList, SkLayerInfo* data) { + SkRecords::CollectLayers visitor(cullRect, record, bounds, pictList, data); for (int curOp = 0; curOp < record.count(); curOp++) { visitor.setCurrentOp(curOp); record.visit<void>(curOp, visitor); } - - visitor.cleanUp(bbh); + visitor.cleanUp(); } diff --git a/src/core/SkRecordDraw.h b/src/core/SkRecordDraw.h index c2db37aebd..fdf98824ac 100644 --- a/src/core/SkRecordDraw.h +++ b/src/core/SkRecordDraw.h @@ -17,12 +17,14 @@ class SkDrawable; class SkLayerInfo; -// Fill a BBH to be used by SkRecordDraw to accelerate playback. -void SkRecordFillBounds(const SkRect& cullRect, const SkRecord&, SkBBoxHierarchy*); +// Calculate conservative identity space bounds for each op in the record. +void SkRecordFillBounds(const SkRect& cullRect, const SkRecord&, SkRect bounds[]); -void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord& record, - const SkBigPicture::SnapshotArray*, - SkBBoxHierarchy* bbh, SkLayerInfo* data); +// SkRecordFillBounds(), and gathers information about saveLayers and stores it for later +// use (e.g., layer hoisting). The gathered information is sufficient to determine +// where each saveLayer will land and which ops in the picture it represents. +void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord&, SkRect bounds[], + const SkBigPicture::SnapshotArray*, SkLayerInfo* data); // Draw an SkRecord into an SkCanvas. A convenience wrapper around SkRecords::Draw. void SkRecordDraw(const SkRecord&, SkCanvas*, SkPicture const* const drawablePicts[], |