Memory management for volumes.

This commit is contained in:
David Williams 2009-03-26 22:22:04 +00:00
parent fab64488ee
commit 50b3ff407e
4 changed files with 89 additions and 30 deletions

View File

@ -50,10 +50,11 @@ namespace PolyVox
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
void fill(VoxelType tValue);
bool isHomogeneous(void);
private:
uint16 m_uSideLength;
uint8 m_uSideLengthPower;
uint8 m_uSideLengthPower;
VoxelType* m_tData;
};
}

View File

@ -141,5 +141,23 @@ namespace PolyVox
{
memset(m_tData, tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
}
template <typename VoxelType>
bool BlockData<VoxelType>::isHomogeneous(void)
{
VoxelType currentVoxel = m_tData;
VoxelType firstVal = *currentVoxel;
uint32 uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
for(uint32 ct = 1; ct < uNoOfVoxels; ++ct)
{
++currentVoxel;
if(*currentVoxel != firstVoxel)
{
return false;
}
}
return true;
}
#pragma endregion
}

View File

@ -38,8 +38,18 @@ namespace PolyVox
public:
BlockData<VoxelType>* m_pBlockData;
VoxelType m_pHomogenousValue;
bool m_pIsShared;
bool m_pIsPotentiallySharable;
bool m_bIsShared;
bool m_bIsPotentiallySharable;
};
template <typename VoxelType>
class ReferenceCountedBlockData
{
public:
ReferenceCountedBlockData() : m_pBlockData(0), m_uReferenceCount(0) {}
BlockData<VoxelType>* m_pBlockData;
uint32 m_uReferenceCount;
};
template <typename VoxelType>
@ -69,14 +79,10 @@ namespace PolyVox
VolumeIterator<VoxelType> lastVoxel(void);
private:
BlockData<VoxelType>* getHomogenousBlock(VoxelType tHomogenousValue) const;
BlockData<VoxelType>* getHomogenousBlockData(VoxelType tHomogenousValue) const;
//Block<VoxelType>** m_pBlocks;
//bool* m_pIsShared;
//bool* m_pIsPotentiallySharable;
//VoxelType* m_pHomogenousValue;
Block<VoxelType>* m_pBlocks;
mutable std::map<VoxelType, BlockData<VoxelType>*> m_pHomogenousBlocks;
mutable std::map<VoxelType, ReferenceCountedBlockData<VoxelType> > m_pHomogenousBlockData;
uint32 m_uNoOfBlocksInVolume;
uint16 m_uSideLengthInBlocks;

View File

@ -71,23 +71,23 @@ namespace PolyVox
//Create the blocks
/*m_pBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume];
m_pIsShared = new bool[m_uNoOfBlocksInVolume];
m_pIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume];
m_bIsShared = new bool[m_uNoOfBlocksInVolume];
m_bIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume];
m_pHomogenousValue = new VoxelType[m_uNoOfBlocksInVolume];
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
{
m_pBlocks[i] = getHomogenousBlock(0);
m_pIsShared[i] = true;
m_pIsPotentiallySharable[i] = false;
m_bIsShared[i] = true;
m_bIsPotentiallySharable[i] = false;
m_pHomogenousValue[i] = 0;
}*/
m_pBlocks = new Block<VoxelType>[m_uNoOfBlocksInVolume];
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
{
m_pBlocks[i].m_pBlockData = getHomogenousBlock(0);
m_pBlocks[i].m_pIsShared = true;
m_pBlocks[i].m_pIsPotentiallySharable = false;
m_pBlocks[i].m_pBlockData = getHomogenousBlockData(0);
m_pBlocks[i].m_bIsShared = true;
m_pBlocks[i].m_bIsPotentiallySharable = false;
m_pBlocks[i].m_pHomogenousValue = 0;
}
}
@ -103,15 +103,15 @@ namespace PolyVox
{
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
{
if(m_pBlocks[i].m_pIsShared == false)
if(m_pBlocks[i].m_bIsShared == false)
{
delete m_pBlocks[i].m_pBlockData;
m_pBlocks[i].m_pBlockData = 0;
}
}
delete[] m_pBlocks;
/*delete[] m_pIsShared;
delete[] m_pIsPotentiallySharable;
/*delete[] m_bIsShared;
delete[] m_bIsPotentiallySharable;
delete[] m_pHomogenousValue;*/
}
#pragma endregion
@ -190,14 +190,14 @@ namespace PolyVox
blockY * m_uSideLengthInBlocks +
blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks;
const bool bIsShared = m_pBlocks[uBlockIndex].m_pIsShared;
const bool bIsShared = m_pBlocks[uBlockIndex].m_bIsShared;
if(bIsShared)
{
const VoxelType tHomogenousValue = m_pBlocks[uBlockIndex].m_pHomogenousValue;
if(tHomogenousValue != tValue)
{
m_pBlocks[uBlockIndex].m_pBlockData = new BlockData<VoxelType>(m_uBlockSideLength);
m_pBlocks[uBlockIndex].m_pIsShared = false;
m_pBlocks[uBlockIndex].m_bIsShared = false;
m_pBlocks[uBlockIndex].m_pBlockData->fill(tHomogenousValue);
m_pBlocks[uBlockIndex].m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue);
}
@ -207,7 +207,7 @@ namespace PolyVox
m_pBlocks[uBlockIndex].m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue);
//There is a chance that setting this voxel makes the block homogenous and therefore shareable. But checking
//this will take some time, so for now just set a flag.
m_pBlocks[uBlockIndex].m_pIsPotentiallySharable = true;
m_pBlocks[uBlockIndex].m_bIsPotentiallySharable = true;
}
}
@ -230,6 +230,34 @@ namespace PolyVox
template <typename VoxelType>
void Volume<VoxelType>::idle(uint32 uAmount)
{
//This function performs two roles. Firstly, it examines all of the blocks which are marked as
//'potentially sharable' to determine whether they really are sharable or not. For those which
//are sharable, it adjusts the pointer and deletes tho old data. Secondly, it determines which
//homogeneous regions are not actually being used (by thier reference count) and frees them.
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
{
Block block = m_pBlocks[i];
if(block.m_bIsPotentiallySharable)
{
bool isSharable = block.m_pBlockData->isHomogeneous();
if(isSharable)
{
VoxelType homogeneousValue = block.m_pBlockData->getVoxelAt(0,0,0);
delete block.m_pBlockData;
block.m_pBlockData = getHomogenousBlockData(homogeneousValue);
block.m_pHomogenousValue = homogeneousValue;
block.m_bIsShared = true;
}
//Either way, we have now determined whether the block was sharable. So it's not *potentially* sharable.
block.m_bIsPotentiallySharable = false;
}
}
//Note - this second step should probably happen immediatly, rather than in this function.
//Use of a shared pointer system would allow this.
}
template <typename VoxelType>
@ -265,17 +293,23 @@ namespace PolyVox
#pragma region Private Implementation
template <typename VoxelType>
BlockData<VoxelType>* Volume<VoxelType>::getHomogenousBlock(VoxelType tHomogenousValue) const
BlockData<VoxelType>* Volume<VoxelType>::getHomogenousBlockData(VoxelType tHomogenousValue) const
{
typename std::map<VoxelType, BlockData<VoxelType>*>::iterator iterResult = m_pHomogenousBlocks.find(tHomogenousValue);
if(iterResult == m_pHomogenousBlocks.end())
typename std::map<VoxelType, ReferenceCountedBlockData<VoxelType> >::iterator iterResult = m_pHomogenousBlockData.find(tHomogenousValue);
if(iterResult == m_pHomogenousBlockData.end())
{
BlockData<VoxelType>* pBlock = new BlockData<VoxelType>(m_uBlockSideLength);
pBlock->fill(tHomogenousValue);
m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock));
return pBlock;
ReferenceCountedBlockData<VoxelType> referenceCountedBlockData;
referenceCountedBlockData.m_pBlockData = new BlockData<VoxelType>(m_uBlockSideLength);
referenceCountedBlockData.m_uReferenceCount++;
referenceCountedBlockData.m_pBlockData->fill(tHomogenousValue);
m_pHomogenousBlockData.insert(std::make_pair(tHomogenousValue, referenceCountedBlockData));
return referenceCountedBlockData.m_pBlockData;
}
else
{
iterResult->second.m_uReferenceCount++;
return iterResult->second.m_pBlockData;
}
return iterResult->second;
}
#pragma endregion
}