diff --git a/src/core/SkBBoxHierarchy.h b/src/core/SkBBoxHierarchy.h index f925a91940..1ea9e6bdb0 100644 --- a/src/core/SkBBoxHierarchy.h +++ b/src/core/SkBBoxHierarchy.h @@ -34,6 +34,9 @@ public: virtual size_t bytesUsed() const = 0; + // Get the root bound. + virtual SkRect getRootBound() const = 0; + SK_DECLARE_INST_COUNT(SkBBoxHierarchy) private: typedef SkRefCnt INHERITED; diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index 42f8732c79..1972ad3341 100644 --- a/src/core/SkPictureRecorder.cpp +++ b/src/core/SkPictureRecorder.cpp @@ -60,6 +60,10 @@ SkPicture* SkPictureRecorder::endRecordingAsPicture() { } else { SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); } + SkRect bbhBound = fBBH->getRootBound(); + SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound)) + || (bbhBound.isEmpty() && fCullRect.isEmpty())); + fCullRect = bbhBound; } SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullRect, fRecord, pictList, fBBH)); diff --git a/src/core/SkRTree.cpp b/src/core/SkRTree.cpp index ba5843e537..2fded6f72b 100644 --- a/src/core/SkRTree.cpp +++ b/src/core/SkRTree.cpp @@ -9,6 +9,14 @@ SkRTree::SkRTree(SkScalar aspectRatio) : fCount(0), fAspectRatio(aspectRatio) {} +SkRect SkRTree::getRootBound() const { + if (fCount) { + return fRoot.fBounds; + } else { + return SkRect::MakeEmpty(); + } +} + void SkRTree::insert(const SkRect boundsArray[], int N) { SkASSERT(0 == fCount); diff --git a/src/core/SkRTree.h b/src/core/SkRTree.h index 320b0bd438..9a118d4897 100644 --- a/src/core/SkRTree.h +++ b/src/core/SkRTree.h @@ -52,6 +52,9 @@ public: // Insertion count (not overall node count, which may be greater). int getCount() const { return fCount; } + // Get the root bound. + SkRect getRootBound() const SK_OVERRIDE; + // These values were empirically determined to produce reasonable performance in most cases. static const int kMinChildren = 6, kMaxChildren = 11; diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 9b08426670..b66c721aee 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -387,8 +387,12 @@ private: Bounds bounds(const DrawPaint&) const { return fCurrentClipBounds; } Bounds bounds(const NoOp&) const { return Bounds::MakeEmpty(); } // NoOps don't draw. - Bounds bounds(const DrawSprite& op) const { // Ignores the matrix. - return Bounds::MakeXYWH(op.left, op.top, op.bitmap.width(), op.bitmap.height()); + Bounds bounds(const DrawSprite& op) const { // Ignores the matrix, but respects the clip. + SkRect rect = Bounds::MakeXYWH(op.left, op.top, op.bitmap.width(), op.bitmap.height()); + if (!rect.intersect(fCurrentClipBounds)) { + return Bounds::MakeEmpty(); + } + return rect; } Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); } diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp index 33e058cc2e..ac750e9a85 100644 --- a/tests/PictureTest.cpp +++ b/tests/PictureTest.cpp @@ -1248,8 +1248,9 @@ DEF_TEST(DontOptimizeSaveLayerDrawDrawRestore, reporter) { struct CountingBBH : public SkBBoxHierarchy { mutable int searchCalls; + SkRect rootBound; - CountingBBH() : searchCalls(0) {} + CountingBBH(const SkRect& bound) : searchCalls(0), rootBound(bound) {} void search(const SkRect& query, SkTDArray* results) const SK_OVERRIDE { this->searchCalls++; @@ -1257,6 +1258,7 @@ struct CountingBBH : public SkBBoxHierarchy { void insert(const SkRect[], int) SK_OVERRIDE {} virtual size_t bytesUsed() const SK_OVERRIDE { return 0; } + SkRect getRootBound() const SK_OVERRIDE { return rootBound; } }; class SpoonFedBBHFactory : public SkBBHFactory { @@ -1271,11 +1273,12 @@ private: // When the canvas clip covers the full picture, we don't need to call the BBH. DEF_TEST(Picture_SkipBBH, r) { - CountingBBH bbh; + SkRect bound = SkRect::MakeWH(320, 240); + CountingBBH bbh(bound); SpoonFedBBHFactory factory(&bbh); SkPictureRecorder recorder; - recorder.beginRecording(320, 240, &factory); + recorder.beginRecording(bound, &factory); SkAutoTUnref picture(recorder.endRecording()); SkCanvas big(640, 480), small(300, 200); diff --git a/tests/RecordDrawTest.cpp b/tests/RecordDrawTest.cpp index cf138b8d4e..baee712b37 100644 --- a/tests/RecordDrawTest.cpp +++ b/tests/RecordDrawTest.cpp @@ -133,6 +133,7 @@ struct TestBBH : public SkBBoxHierarchy { void search(const SkRect& query, SkTDArray* results) const SK_OVERRIDE {} size_t bytesUsed() const SK_OVERRIDE { return 0; } + SkRect getRootBound() const SK_OVERRIDE { return SkRect::MakeEmpty(); } struct Entry { unsigned opIndex;