aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkRTree.cpp
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2014-10-27 10:27:10 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-27 10:27:10 -0700
commit4477c3c0e6eb064772aefe8737425cd1c2ce557f (patch)
treee841aeb0174e7ddc621f0b5dca88592e8c37d975 /src/core/SkRTree.cpp
parent5e44b00392e791088b693a0b462b107b0b5a91ba (diff)
Cut down SkBBH API more.
- The expected case is now a single bulk-load insert() call instead of N; - reserve() and flushDeferredInserts() can fold into insert() now; - SkBBH subclasses may take ownership of the bounds This appears to be a performance no-op on both my Mac and N5. I guess even the simplest indirect branch predictor ("same as last time") can predict the repeated virtual calls to SkBBH::insert() perfectly. BUG=skia: Review URL: https://codereview.chromium.org/670213002
Diffstat (limited to 'src/core/SkRTree.cpp')
-rw-r--r--src/core/SkRTree.cpp77
1 files changed, 23 insertions, 54 deletions
diff --git a/src/core/SkRTree.cpp b/src/core/SkRTree.cpp
index 4a081db26d..93f914276f 100644
--- a/src/core/SkRTree.cpp
+++ b/src/core/SkRTree.cpp
@@ -44,68 +44,39 @@ SkRTree::~SkRTree() {
this->clear();
}
-void SkRTree::insert(unsigned opIndex, const SkRect& fbounds, bool defer) {
- SkIRect bounds;
- if (fbounds.isLargest()) {
- bounds.setLargest();
- } else {
- fbounds.roundOut(&bounds);
- }
-
+void SkRTree::insert(SkAutoTMalloc<SkRect>* boundsArray, int N) {
+ SkASSERT(this->isEmpty());
this->validate();
- if (bounds.isEmpty()) {
- SkASSERT(false);
- return;
- }
- Branch newBranch;
- newBranch.fBounds = bounds;
- newBranch.fChild.opIndex = opIndex;
- if (this->isEmpty()) {
- // since a bulk-load into an existing tree is as of yet unimplemented (and arguably not
- // of vital importance right now), we only batch up inserts if the tree is empty.
- if (defer) {
- fDeferredInserts.push(newBranch);
- return;
- } else {
- fRoot.fChild.subtree = allocateNode(0);
- fRoot.fChild.subtree->fNumChildren = 0;
+
+ SkTDArray<Branch> deferred;
+ deferred.setReserve(N);
+
+ for (int i = 0; i < N; i++) {
+ SkIRect bounds;
+ (*boundsArray)[i].roundOut(&bounds);
+ if (bounds.isEmpty()) {
+ continue;
}
- }
- Branch* newSibling = insert(fRoot.fChild.subtree, &newBranch);
- fRoot.fBounds = this->computeBounds(fRoot.fChild.subtree);
-
- if (newSibling) {
- Node* oldRoot = fRoot.fChild.subtree;
- Node* newRoot = this->allocateNode(oldRoot->fLevel + 1);
- newRoot->fNumChildren = 2;
- *newRoot->child(0) = fRoot;
- *newRoot->child(1) = *newSibling;
- fRoot.fChild.subtree = newRoot;
- fRoot.fBounds = this->computeBounds(fRoot.fChild.subtree);
- }
+ Branch newBranch;
+ newBranch.fBounds = bounds;
+ newBranch.fChild.opIndex = i;
- ++fCount;
- this->validate();
-}
+ deferred.push(newBranch);
+ }
-void SkRTree::flushDeferredInserts() {
- this->validate();
- if (this->isEmpty() && fDeferredInserts.count() > 0) {
- fCount = fDeferredInserts.count();
+ fCount = deferred.count();
+ if (fCount) {
if (1 == fCount) {
- fRoot.fChild.subtree = allocateNode(0);
+ fRoot.fChild.subtree = this->allocateNode(0);
fRoot.fChild.subtree->fNumChildren = 0;
- this->insert(fRoot.fChild.subtree, &fDeferredInserts[0]);
- fRoot.fBounds = fDeferredInserts[0].fBounds;
+ this->insert(fRoot.fChild.subtree, &deferred[0]);
+ fRoot.fBounds = deferred[0].fBounds;
} else {
- fRoot = this->bulkLoad(&fDeferredInserts);
+ fRoot = this->bulkLoad(&deferred);
}
- } else {
- // TODO: some algorithm for bulk loading into an already populated tree
- SkASSERT(0 == fDeferredInserts.count());
}
- fDeferredInserts.rewind();
+
this->validate();
}
@@ -113,7 +84,6 @@ void SkRTree::search(const SkRect& fquery, SkTDArray<unsigned>* results) const {
SkIRect query;
fquery.roundOut(&query);
this->validate();
- SkASSERT(0 == fDeferredInserts.count()); // If this fails, you should have flushed.
if (!this->isEmpty() && SkIRect::IntersectsNoEmptyCheck(fRoot.fBounds, query)) {
this->search(fRoot.fChild.subtree, query, results);
}
@@ -123,7 +93,6 @@ void SkRTree::search(const SkRect& fquery, SkTDArray<unsigned>* results) const {
void SkRTree::clear() {
this->validate();
fNodes.reset();
- fDeferredInserts.rewind();
fCount = 0;
this->validate();
}