Memory management for volumes.
This commit is contained in:
parent
fab64488ee
commit
50b3ff407e
@ -50,10 +50,11 @@ namespace PolyVox
|
|||||||
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||||
|
|
||||||
void fill(VoxelType tValue);
|
void fill(VoxelType tValue);
|
||||||
|
bool isHomogeneous(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16 m_uSideLength;
|
uint16 m_uSideLength;
|
||||||
uint8 m_uSideLengthPower;
|
uint8 m_uSideLengthPower;
|
||||||
VoxelType* m_tData;
|
VoxelType* m_tData;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -141,5 +141,23 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
memset(m_tData, tValue, m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType));
|
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
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,18 @@ namespace PolyVox
|
|||||||
public:
|
public:
|
||||||
BlockData<VoxelType>* m_pBlockData;
|
BlockData<VoxelType>* m_pBlockData;
|
||||||
VoxelType m_pHomogenousValue;
|
VoxelType m_pHomogenousValue;
|
||||||
bool m_pIsShared;
|
bool m_bIsShared;
|
||||||
bool m_pIsPotentiallySharable;
|
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>
|
template <typename VoxelType>
|
||||||
@ -69,14 +79,10 @@ namespace PolyVox
|
|||||||
VolumeIterator<VoxelType> lastVoxel(void);
|
VolumeIterator<VoxelType> lastVoxel(void);
|
||||||
|
|
||||||
private:
|
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;
|
Block<VoxelType>* m_pBlocks;
|
||||||
mutable std::map<VoxelType, BlockData<VoxelType>*> m_pHomogenousBlocks;
|
mutable std::map<VoxelType, ReferenceCountedBlockData<VoxelType> > m_pHomogenousBlockData;
|
||||||
|
|
||||||
uint32 m_uNoOfBlocksInVolume;
|
uint32 m_uNoOfBlocksInVolume;
|
||||||
uint16 m_uSideLengthInBlocks;
|
uint16 m_uSideLengthInBlocks;
|
||||||
|
@ -71,23 +71,23 @@ namespace PolyVox
|
|||||||
|
|
||||||
//Create the blocks
|
//Create the blocks
|
||||||
/*m_pBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume];
|
/*m_pBlocks = new Block<VoxelType>*[m_uNoOfBlocksInVolume];
|
||||||
m_pIsShared = new bool[m_uNoOfBlocksInVolume];
|
m_bIsShared = new bool[m_uNoOfBlocksInVolume];
|
||||||
m_pIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume];
|
m_bIsPotentiallySharable = new bool[m_uNoOfBlocksInVolume];
|
||||||
m_pHomogenousValue = new VoxelType[m_uNoOfBlocksInVolume];
|
m_pHomogenousValue = new VoxelType[m_uNoOfBlocksInVolume];
|
||||||
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
||||||
{
|
{
|
||||||
m_pBlocks[i] = getHomogenousBlock(0);
|
m_pBlocks[i] = getHomogenousBlock(0);
|
||||||
m_pIsShared[i] = true;
|
m_bIsShared[i] = true;
|
||||||
m_pIsPotentiallySharable[i] = false;
|
m_bIsPotentiallySharable[i] = false;
|
||||||
m_pHomogenousValue[i] = 0;
|
m_pHomogenousValue[i] = 0;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
m_pBlocks = new Block<VoxelType>[m_uNoOfBlocksInVolume];
|
m_pBlocks = new Block<VoxelType>[m_uNoOfBlocksInVolume];
|
||||||
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
||||||
{
|
{
|
||||||
m_pBlocks[i].m_pBlockData = getHomogenousBlock(0);
|
m_pBlocks[i].m_pBlockData = getHomogenousBlockData(0);
|
||||||
m_pBlocks[i].m_pIsShared = true;
|
m_pBlocks[i].m_bIsShared = true;
|
||||||
m_pBlocks[i].m_pIsPotentiallySharable = false;
|
m_pBlocks[i].m_bIsPotentiallySharable = false;
|
||||||
m_pBlocks[i].m_pHomogenousValue = 0;
|
m_pBlocks[i].m_pHomogenousValue = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,15 +103,15 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
for(uint32 i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
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;
|
delete m_pBlocks[i].m_pBlockData;
|
||||||
m_pBlocks[i].m_pBlockData = 0;
|
m_pBlocks[i].m_pBlockData = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] m_pBlocks;
|
delete[] m_pBlocks;
|
||||||
/*delete[] m_pIsShared;
|
/*delete[] m_bIsShared;
|
||||||
delete[] m_pIsPotentiallySharable;
|
delete[] m_bIsPotentiallySharable;
|
||||||
delete[] m_pHomogenousValue;*/
|
delete[] m_pHomogenousValue;*/
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
@ -190,14 +190,14 @@ namespace PolyVox
|
|||||||
blockY * m_uSideLengthInBlocks +
|
blockY * m_uSideLengthInBlocks +
|
||||||
blockZ * m_uSideLengthInBlocks * 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)
|
if(bIsShared)
|
||||||
{
|
{
|
||||||
const VoxelType tHomogenousValue = m_pBlocks[uBlockIndex].m_pHomogenousValue;
|
const VoxelType tHomogenousValue = m_pBlocks[uBlockIndex].m_pHomogenousValue;
|
||||||
if(tHomogenousValue != tValue)
|
if(tHomogenousValue != tValue)
|
||||||
{
|
{
|
||||||
m_pBlocks[uBlockIndex].m_pBlockData = new BlockData<VoxelType>(m_uBlockSideLength);
|
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->fill(tHomogenousValue);
|
||||||
m_pBlocks[uBlockIndex].m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
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);
|
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
|
//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.
|
//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>
|
template <typename VoxelType>
|
||||||
void Volume<VoxelType>::idle(uint32 uAmount)
|
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>
|
template <typename VoxelType>
|
||||||
@ -265,17 +293,23 @@ namespace PolyVox
|
|||||||
|
|
||||||
#pragma region Private Implementation
|
#pragma region Private Implementation
|
||||||
template <typename VoxelType>
|
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);
|
typename std::map<VoxelType, ReferenceCountedBlockData<VoxelType> >::iterator iterResult = m_pHomogenousBlockData.find(tHomogenousValue);
|
||||||
if(iterResult == m_pHomogenousBlocks.end())
|
if(iterResult == m_pHomogenousBlockData.end())
|
||||||
{
|
{
|
||||||
BlockData<VoxelType>* pBlock = new BlockData<VoxelType>(m_uBlockSideLength);
|
ReferenceCountedBlockData<VoxelType> referenceCountedBlockData;
|
||||||
pBlock->fill(tHomogenousValue);
|
referenceCountedBlockData.m_pBlockData = new BlockData<VoxelType>(m_uBlockSideLength);
|
||||||
m_pHomogenousBlocks.insert(std::make_pair(tHomogenousValue, pBlock));
|
referenceCountedBlockData.m_uReferenceCount++;
|
||||||
return pBlock;
|
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
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user