summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-12-04 03:15:33 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-12-04 03:15:33 +0000
commitec16329bc5357f4c78712564592466fcb2cc4d63 (patch)
treefe823b4ca70c75c2cab4066eacca90c83acfad0c /Graphics
parentFixed clang warning (diff)
downloadDiligentCore-ec16329bc5357f4c78712564592466fcb2cc4d63.tar.gz
DiligentCore-ec16329bc5357f4c78712564592466fcb2cc4d63.zip
DynamicAtlasManager: fixed issue with regions not being merged when splitting free space during allocation
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsAccessories/interface/DynamicAtlasManager.hpp2
-rw-r--r--Graphics/GraphicsAccessories/src/DynamicAtlasManager.cpp54
2 files changed, 38 insertions, 18 deletions
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)