Fix AreaAllocator end iterator bug when going through a grow cycle. If growing the allocator before first allocation, simply expand the existing free area.

This commit is contained in:
Lasse Öörni 2014-10-08 13:41:47 +03:00
Родитель 744b7a8e24
Коммит b0598282d9
1 изменённых файлов: 22 добавлений и 6 удалений

Просмотреть файл

@ -65,11 +65,13 @@ bool AreaAllocator::Allocate(int width, int height, int& x, int& y)
if (height < 0)
height = 0;
PODVector<IntRect>::Iterator best = freeAreas_.End();
int bestFreeArea = M_MAX_INT;
PODVector<IntRect>::Iterator best;
int bestFreeArea;
for(;;)
{
best = freeAreas_.End();
bestFreeArea = M_MAX_INT;
for (PODVector<IntRect>::Iterator i = freeAreas_.Begin(); i != freeAreas_.End(); ++i)
{
int freeWidth = i->Width();
@ -94,15 +96,29 @@ bool AreaAllocator::Allocate(int width, int height, int& x, int& y)
{
int oldWidth = size_.x_;
size_.x_ <<= 1;
IntRect newArea(oldWidth, 0, size_.x_, size_.y_);
freeAreas_.Push(newArea);
// If no allocations yet, simply expand the single free area
IntRect& first = freeAreas_.Front();
if (freeAreas_.Size() == 1 && first.left_ == 0 && first.top_ == 0 && first.right_ == oldWidth && first.bottom_ == size_.y_)
first.right_ = size_.x_;
else
{
IntRect newArea(oldWidth, 0, size_.x_, size_.y_);
freeAreas_.Push(newArea);
}
}
else if (!doubleWidth_ && size_.y_ < maxSize_.y_)
{
int oldHeight = size_.y_;
size_.y_ <<= 1;
IntRect newArea(0, oldHeight, size_.x_, size_.y_);
freeAreas_.Push(newArea);
// If no allocations yet, simply expand the single free area
IntRect& first = freeAreas_.Front();
if (freeAreas_.Size() == 1 && first.left_ == 0 && first.top_ == 0 && first.right_ == size_.x_ && first.bottom_ == oldHeight)
first.bottom_ = size_.y_;
else
{
IntRect newArea(0, oldHeight, size_.x_, size_.y_);
freeAreas_.Push(newArea);
}
}
else
return false;