Skip to content

Commit 29eec60

Browse files
committed
Micro-optimize MaxRectsBinPack to avoid testing four of the newly added rectangles against each other. #21
1 parent d1496fe commit 29eec60

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

MaxRectsBinPack.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ bool MaxRectsBinPack::SplitFreeNode(const Rect &freeNode, const Rect &usedNode)
423423
usedNode.y >= freeNode.y + freeNode.height || usedNode.y + usedNode.height <= freeNode.y)
424424
return false;
425425

426+
// We add up to four new free rectangles to the free rectangles list below. None of these
427+
// four newly added free rectangles can overlap any other three, so keep a mark of them
428+
// to avoid testing them against each other.
429+
newFreeRectanglesLastSize = newFreeRectangles.size();
430+
426431
if (usedNode.x < freeNode.x + freeNode.width && usedNode.x + usedNode.width > freeNode.x)
427432
{
428433
// New node at the top side of the used node.
@@ -471,7 +476,7 @@ void MaxRectsBinPack::InsertNewFreeRectangle(const Rect &newFreeRect)
471476
assert(newFreeRect.width > 0);
472477
assert(newFreeRect.height > 0);
473478

474-
for(size_t i = 0; i < newFreeRectangles.size();)
479+
for(size_t i = 0; i < newFreeRectanglesLastSize;)
475480
{
476481
// This new free rectangle is already accounted for?
477482
if (IsContainedIn(newFreeRect, newFreeRectangles[i]))
@@ -480,7 +485,11 @@ void MaxRectsBinPack::InsertNewFreeRectangle(const Rect &newFreeRect)
480485
// Does this new free rectangle obsolete a previous new free rectangle?
481486
if (IsContainedIn(newFreeRectangles[i], newFreeRect))
482487
{
483-
newFreeRectangles[i] = newFreeRectangles.back();
488+
// Remove i'th new free rectangle, but do so by retaining the order
489+
// of the older vs newest free rectangles that we may still be placing
490+
// in calling function SplitFreeNode().
491+
newFreeRectangles[i] = newFreeRectangles[--newFreeRectanglesLastSize];
492+
newFreeRectangles[newFreeRectanglesLastSize] = newFreeRectangles.back();
484493
newFreeRectangles.pop_back();
485494
}
486495
else
@@ -514,6 +523,15 @@ void MaxRectsBinPack::PruneFreeList()
514523
// Merge new and old free rectangles to the group of old free rectangles.
515524
freeRectangles.insert(freeRectangles.end(), newFreeRectangles.begin(), newFreeRectangles.end());
516525
newFreeRectangles.clear();
526+
527+
#ifdef _DEBUG
528+
for(size_t i = 0; i < freeRectangles.size(); ++i)
529+
for(size_t j = i+1; j < freeRectangles.size(); ++j)
530+
{
531+
assert(!IsContainedIn(freeRectangles[i], freeRectangles[j]));
532+
assert(!IsContainedIn(freeRectangles[j], freeRectangles[i]));
533+
}
534+
#endif
517535
}
518536

519537
}

MaxRectsBinPack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class MaxRectsBinPack
5757

5858
bool binAllowFlip;
5959

60+
size_t newFreeRectanglesLastSize;
6061
std::vector<Rect> newFreeRectangles;
6162

6263
std::vector<Rect> usedRectangles;

0 commit comments

Comments
 (0)