From ec16329bc5357f4c78712564592466fcb2cc4d63 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 3 Dec 2020 19:15:33 -0800 Subject: DynamicAtlasManager: fixed issue with regions not being merged when splitting free space during allocation --- .../interface/DynamicAtlasManager.hpp | 2 +- .../src/DynamicAtlasManager.cpp | 54 +++++++++++++++------- 2 files changed, 38 insertions(+), 18 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsAccessories/interface/DynamicAtlasManager.hpp b/Graphics/GraphicsAccessories/interface/DynamicAtlasManager.hpp index ab3eb04b..bab1a12b 100644 --- a/Graphics/GraphicsAccessories/interface/DynamicAtlasManager.hpp +++ b/Graphics/GraphicsAccessories/interface/DynamicAtlasManager.hpp @@ -150,7 +150,7 @@ public: private: void InitRegion(const Region& R, bool IsAllocated); - void AddFreeRegion(const Region& R); + void AddFreeRegion(Region R); void RemoveFreeRegion(const Region R); Region& GetRegion(Uint32 x, Uint32 y) diff --git a/Graphics/GraphicsAccessories/src/DynamicAtlasManager.cpp b/Graphics/GraphicsAccessories/src/DynamicAtlasManager.cpp index aa1acd13..307c3a21 100644 --- a/Graphics/GraphicsAccessories/src/DynamicAtlasManager.cpp +++ b/Graphics/GraphicsAccessories/src/DynamicAtlasManager.cpp @@ -40,6 +40,15 @@ DynamicAtlasManager::DynamicAtlasManager(Uint32 Width, Uint32 Height) : m_Height{Height}, m_RegionMap{new Region[Width * Height]} { +#ifdef DILIGENT_DEBUG + for (Uint32 y = 0; y < m_Height; ++y) + { + for (Uint32 x = 0; x < m_Width; ++x) + { + GetRegion(x, y) = InvalidRegion; + } + } +#endif AddFreeRegion(Region{0, 0, m_Width, m_Height}); } @@ -169,6 +178,28 @@ void DynamicAtlasManager::Free(Region&& R) } #endif + AddFreeRegion(R); + +#if DILIGENT_DEBUG + DbgVerifyConsistency(); +#endif + + R = InvalidRegion; +} + +void DynamicAtlasManager::AddFreeRegion(Region R) +{ +#ifdef DILIGENT_DEBUG + for (Uint32 y = R.y; y < R.y + R.height; ++y) + { + for (Uint32 x = R.x; x < R.x + R.width; ++x) + { + const auto& R1 = GetRegion(x, y); + VERIFY_EXPR(R1 == AllocatedRegion || R1 == InvalidRegion); + } + } +#endif + bool Merged = false; do { @@ -177,7 +208,7 @@ void DynamicAtlasManager::Free(Region&& R) if (R.x > 0) { const auto& lftR = GetRegion(R.x - 1, R.y); - if (lftR != AllocatedRegion) + if (lftR != AllocatedRegion && lftR != InvalidRegion) { VERIFY_EXPR(lftR.x + lftR.width == R.x); if (lftR.y == R.y && lftR.height == R.height) @@ -198,7 +229,7 @@ void DynamicAtlasManager::Free(Region&& R) if (R.x + R.width < m_Width) { const auto& rgtR = GetRegion(R.x + R.width, R.y); - if (rgtR != AllocatedRegion) + if (rgtR != AllocatedRegion && rgtR != InvalidRegion) { VERIFY_EXPR(R.x + R.width == rgtR.x); if (rgtR.y == R.y && rgtR.height == R.height) @@ -223,7 +254,7 @@ void DynamicAtlasManager::Free(Region&& R) if (R.y > 0) { const auto& btmR = GetRegion(R.x, R.y - 1); - if (btmR != AllocatedRegion) + if (btmR != AllocatedRegion && btmR != InvalidRegion) { VERIFY_EXPR(btmR.y + btmR.height == R.y); if (btmR.x == R.x && btmR.width == R.width) @@ -247,7 +278,7 @@ void DynamicAtlasManager::Free(Region&& R) if (R.y + R.height < m_Height) { const auto& tpR = GetRegion(R.x, R.y + R.height); - if (tpR != AllocatedRegion) + if (tpR != AllocatedRegion && tpR != InvalidRegion) { VERIFY_EXPR(R.y + R.height == tpR.y); if (tpR.x == R.x && tpR.width == R.width) @@ -280,17 +311,6 @@ void DynamicAtlasManager::Free(Region&& R) } } while (Merged); - AddFreeRegion(R); - -#if DILIGENT_DEBUG - DbgVerifyConsistency(); -#endif - - R = InvalidRegion; -} - -void DynamicAtlasManager::AddFreeRegion(const Region& R) -{ InitRegion(R, false); { @@ -328,15 +348,15 @@ void DynamicAtlasManager::RemoveFreeRegion(const Region R) m_FreeRegionsByWidth.erase(R); m_FreeRegionsByHeight.erase(R); -#if DILIGENT_DEBUG for (Uint32 y = R.y; y < R.y + R.height; ++y) { for (Uint32 x = R.x; x < R.x + R.width; ++x) { + // Use InvalidRegion to indicate that the region is + // neither allocated nor free. GetRegion(x, y) = InvalidRegion; } } -#endif } void DynamicAtlasManager::InitRegion(const Region& R, bool IsAllocated) -- cgit v1.2.3