mirror of https://github.com/OpenRCT2/OpenRCT2.git
Try merging free image lists if failed to allocate one
This commit is contained in:
parent
ff34967e9b
commit
305e6184f8
|
@ -72,21 +72,57 @@ static bool AllocatedListRemove(uint32 baseImageId, uint32 count)
|
|||
}
|
||||
#endif
|
||||
|
||||
static uint32 AllocateImageList(uint32 count)
|
||||
static uint32 GetNumFreeImagesRemaining()
|
||||
{
|
||||
Guard::Assert(count != 0, GUARD_LINE);
|
||||
return MAX_IMAGES - _allocatedImageCount;
|
||||
}
|
||||
|
||||
if (!_initialised)
|
||||
{
|
||||
_initialised = true;
|
||||
_freeLists.clear();
|
||||
_freeLists.push_back({ BASE_IMAGE_ID, MAX_IMAGES });
|
||||
static void InitialiseImageList()
|
||||
{
|
||||
Guard::Assert(!_initialised, GUARD_LINE);
|
||||
|
||||
_freeLists.clear();
|
||||
_freeLists.push_back({ BASE_IMAGE_ID, MAX_IMAGES });
|
||||
#ifdef DEBUG
|
||||
_allocatedLists.clear();
|
||||
_allocatedLists.clear();
|
||||
#endif
|
||||
_allocatedImageCount = 0;
|
||||
}
|
||||
_allocatedImageCount = 0;
|
||||
_initialised = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all the free lists into one, a process of defragmentation.
|
||||
*/
|
||||
static void MergeFreeLists()
|
||||
{
|
||||
_freeLists.sort(
|
||||
[](const ImageList &a, const ImageList &b) -> bool
|
||||
{
|
||||
return a.BaseId < b.BaseId;
|
||||
});
|
||||
for (auto it = _freeLists.begin(); it != _freeLists.end(); it++)
|
||||
{
|
||||
bool mergeHappened;
|
||||
do
|
||||
{
|
||||
mergeHappened = false;
|
||||
auto nextIt = std::next(it);
|
||||
if (nextIt != _freeLists.end())
|
||||
{
|
||||
if (it->BaseId + it->Count == nextIt->BaseId)
|
||||
{
|
||||
// Merge next list into this list
|
||||
it->Count += nextIt->Count;
|
||||
_freeLists.erase(nextIt);
|
||||
mergeHappened = true;
|
||||
}
|
||||
}
|
||||
} while (mergeHappened);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 TryAllocateImageList(uint32 count)
|
||||
{
|
||||
for (auto it = _freeLists.begin(); it != _freeLists.end(); it++)
|
||||
{
|
||||
ImageList imageList = *it;
|
||||
|
@ -110,6 +146,30 @@ static uint32 AllocateImageList(uint32 count)
|
|||
return INVALID_IMAGE_ID;
|
||||
}
|
||||
|
||||
static uint32 AllocateImageList(uint32 count)
|
||||
{
|
||||
Guard::Assert(count != 0, GUARD_LINE);
|
||||
|
||||
if (!_initialised)
|
||||
{
|
||||
InitialiseImageList();
|
||||
}
|
||||
|
||||
uint32 baseImageId = INVALID_IMAGE_ID;
|
||||
uint32 freeImagesRemaining = GetNumFreeImagesRemaining();
|
||||
if (freeImagesRemaining >= count)
|
||||
{
|
||||
baseImageId = TryAllocateImageList(count);
|
||||
if (baseImageId == INVALID_IMAGE_ID)
|
||||
{
|
||||
// Defragment and try again
|
||||
MergeFreeLists();
|
||||
baseImageId = TryAllocateImageList(count);
|
||||
}
|
||||
}
|
||||
return baseImageId;
|
||||
}
|
||||
|
||||
static void FreeImageList(uint32 baseImageId, uint32 count)
|
||||
{
|
||||
Guard::Assert(_initialised, GUARD_LINE);
|
||||
|
|
Loading…
Reference in New Issue