diff --git a/libs/render/ContinuousBuffer.h b/libs/render/ContinuousBuffer.h index 40727e0fb5..4be2882d6a 100644 --- a/libs/render/ContinuousBuffer.h +++ b/libs/render/ContinuousBuffer.h @@ -167,10 +167,11 @@ class ContinuousBuffer Handle getNextFreeSlotForSize(std::size_t requiredSize) { auto numSlots = _slots.size(); - Handle rightmostFreeSlotIndex = 0; + Handle rightmostFreeSlotIndex = static_cast(numSlots); std::size_t rightmostFreeOffset = 0; + Handle slotIndex = 0; - for (Handle slotIndex = 0; slotIndex < numSlots; ++slotIndex) + for (slotIndex = 0; slotIndex < numSlots; ++slotIndex) { auto& slot = _slots[slotIndex]; @@ -200,6 +201,16 @@ class ContinuousBuffer } // No space wherever, we need to expand the buffer + + // Check if we have any free slots, otherwise allocate a new one + if (rightmostFreeSlotIndex == numSlots) + { + // Create a free slot with 0 size, + // rightMostFreeSlotIndex is now within the valid range + _slots.emplace_back(_buffer.size(), 0, false); + } + + // Allocate more memory auto additionalSize = std::max(_buffer.size() * GrowthRate, requiredSize); _buffer.resize(_buffer.size() + additionalSize); diff --git a/test/ContinuousBuffer.cpp b/test/ContinuousBuffer.cpp index 553a6d6bbd..8271c75fd9 100644 --- a/test/ContinuousBuffer.cpp +++ b/test/ContinuousBuffer.cpp @@ -245,4 +245,27 @@ TEST(ContinuousBufferTest, GapMerging) EXPECT_TRUE(checkContinuousData(buffer, handle7, { sixteen })); } +// Buffer will be tightly filled with no space left, allocation must succeed in this case +TEST(ContinuousBufferTest, ExpandFullBuffer) +{ + auto eight = std::vector({ 0,1,2,3,4,5,6,7 }); + auto four = std::vector({ 10,11,12,13 }); + + render::ContinuousBuffer buffer(eight.size() + four.size()); // Allocate a buffer that matches exactly + + auto handle1 = buffer.allocate(eight.size()); + auto handle2 = buffer.allocate(four.size()); + + buffer.setData(handle1, eight); + buffer.setData(handle2, four); + + EXPECT_TRUE(checkContinuousData(buffer, handle1, { eight, four})); + + // Allocate another piece of memory + auto handle3 = buffer.allocate(eight.size()); + buffer.setData(handle3, eight); + + EXPECT_TRUE(checkContinuousData(buffer, handle1, { eight, four, eight })); +} + }