Work on volume memory management.
This commit is contained in:
parent
19ed8246ff
commit
df68b1fe7a
@ -66,6 +66,8 @@ int main(int argc, char *argv[])
|
|||||||
createCubeInVolume(volData, Vector3DUint16(midPos+1, minPos, midPos+1), Vector3DUint16(maxPos, midPos-1, maxPos), 0);
|
createCubeInVolume(volData, Vector3DUint16(midPos+1, minPos, midPos+1), Vector3DUint16(maxPos, midPos-1, maxPos), 0);
|
||||||
createCubeInVolume(volData, Vector3DUint16(minPos, midPos+1, midPos+1), Vector3DUint16(midPos-1, maxPos, maxPos), 0);
|
createCubeInVolume(volData, Vector3DUint16(minPos, midPos+1, midPos+1), Vector3DUint16(midPos-1, maxPos, maxPos), 0);
|
||||||
|
|
||||||
|
volData.idle(0);
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
OpenGLWidget openGLWidget(0);
|
OpenGLWidget openGLWidget(0);
|
||||||
|
@ -34,7 +34,6 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
POLYVOX_SHARED_PTR< BlockData<VoxelType> > m_pBlockData;
|
POLYVOX_SHARED_PTR< BlockData<VoxelType> > m_pBlockData;
|
||||||
bool m_bIsPotentiallySharable;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,14 +152,12 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
bool BlockData<VoxelType>::isHomogeneous(void)
|
bool BlockData<VoxelType>::isHomogeneous(void)
|
||||||
{
|
{
|
||||||
VoxelType currentVoxel = m_tData;
|
const VoxelType tFirstVoxel = m_tData[0];
|
||||||
VoxelType firstVal = *currentVoxel;
|
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||||
|
|
||||||
uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
|
||||||
for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct)
|
for(uint32_t ct = 1; ct < uNoOfVoxels; ++ct)
|
||||||
{
|
{
|
||||||
++currentVoxel;
|
if(m_tData[ct] != tFirstVoxel)
|
||||||
if(*currentVoxel != firstVal)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "PolyVoxImpl/CPlusPlusZeroXSupport.h"
|
#include "PolyVoxImpl/CPlusPlusZeroXSupport.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
namespace PolyVox
|
namespace PolyVox
|
||||||
@ -60,8 +62,15 @@ namespace PolyVox
|
|||||||
private:
|
private:
|
||||||
POLYVOX_SHARED_PTR< BlockData<VoxelType> > getHomogenousBlockData(VoxelType tHomogenousValue) const;
|
POLYVOX_SHARED_PTR< BlockData<VoxelType> > getHomogenousBlockData(VoxelType tHomogenousValue) const;
|
||||||
|
|
||||||
Block<VoxelType>* m_pBlocks;
|
std::vector< Block<VoxelType> > m_pBlocks;
|
||||||
static std::map<VoxelType, POLYVOX_WEAK_PTR< BlockData<VoxelType> > > m_pHomogenousBlockData;
|
std::vector<bool> m_vecBlockIsPotentiallyHomogenous;
|
||||||
|
|
||||||
|
//Note: We were once storing weak_ptr's in this map, so that the blocks would be deleted once they
|
||||||
|
//were not being referenced by anyone else. However, this made it difficult to know when a block was
|
||||||
|
//shared. A call to shared_ptr::unique() from within setVoxel was not sufficient as weak_ptr's did
|
||||||
|
//not contribute to the reference count. Instead we store shared_ptr's here, and check if they
|
||||||
|
//are used by anyone else (i.e are non-unique) when we tidy the volume.
|
||||||
|
static std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > > m_pHomogenousBlockData;
|
||||||
|
|
||||||
uint32_t m_uNoOfBlocksInVolume;
|
uint32_t m_uNoOfBlocksInVolume;
|
||||||
uint16_t m_uSideLengthInBlocks;
|
uint16_t m_uSideLengthInBlocks;
|
||||||
@ -74,7 +83,7 @@ namespace PolyVox
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Required for the static member
|
//Required for the static member
|
||||||
template <class VoxelType> std::map<VoxelType, POLYVOX_WEAK_PTR< BlockData<VoxelType> > > Volume<VoxelType>::m_pHomogenousBlockData;
|
template <class VoxelType> std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > > Volume<VoxelType>::m_pHomogenousBlockData;
|
||||||
|
|
||||||
|
|
||||||
//Some handy typedefs
|
//Some handy typedefs
|
||||||
|
@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring> //For memcpy
|
#include <cstring> //For memcpy
|
||||||
|
#include <list>
|
||||||
#include <stdexcept> //For invalid_argument
|
#include <stdexcept> //For invalid_argument
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@ -72,11 +73,12 @@ namespace PolyVox
|
|||||||
m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks;
|
m_uNoOfBlocksInVolume = m_uSideLengthInBlocks * m_uSideLengthInBlocks * m_uSideLengthInBlocks;
|
||||||
|
|
||||||
//Create the blocks
|
//Create the blocks
|
||||||
m_pBlocks = new Block<VoxelType>[m_uNoOfBlocksInVolume];
|
m_pBlocks.resize(m_uNoOfBlocksInVolume);
|
||||||
|
m_vecBlockIsPotentiallyHomogenous.resize(m_uNoOfBlocksInVolume);
|
||||||
for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
||||||
{
|
{
|
||||||
m_pBlocks[i].m_pBlockData = getHomogenousBlockData(0);
|
m_pBlocks[i].m_pBlockData = getHomogenousBlockData(0);
|
||||||
m_pBlocks[i].m_bIsPotentiallySharable = false;
|
m_vecBlockIsPotentiallyHomogenous[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +91,6 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
Volume<VoxelType>::~Volume()
|
Volume<VoxelType>::~Volume()
|
||||||
{
|
{
|
||||||
delete[] m_pBlocks;
|
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@ -162,12 +163,12 @@ namespace PolyVox
|
|||||||
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
|
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
|
||||||
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
|
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
|
||||||
|
|
||||||
Block<VoxelType>& block = m_pBlocks
|
uint32_t uBlockIndex =
|
||||||
[
|
blockX +
|
||||||
blockX +
|
blockY * m_uSideLengthInBlocks +
|
||||||
blockY * m_uSideLengthInBlocks +
|
blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks;
|
||||||
blockZ * m_uSideLengthInBlocks * m_uSideLengthInBlocks
|
|
||||||
];
|
Block<VoxelType>& block = m_pBlocks[uBlockIndex];
|
||||||
|
|
||||||
//It's quite possible that the user might attempt to set a voxel to it's current value.
|
//It's quite possible that the user might attempt to set a voxel to it's current value.
|
||||||
//We test for this case firstly because it could help performance, but more importantly
|
//We test for this case firstly because it could help performance, but more importantly
|
||||||
@ -177,15 +178,15 @@ namespace PolyVox
|
|||||||
if(block.m_pBlockData.unique())
|
if(block.m_pBlockData.unique())
|
||||||
{
|
{
|
||||||
block.m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
block.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.
|
||||||
//this will take some time, so for now just set a flag.
|
//But checking this will take some time, so for now just set a flag.
|
||||||
block.m_bIsPotentiallySharable = true;
|
m_vecBlockIsPotentiallyHomogenous[uBlockIndex] = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
POLYVOX_SHARED_PTR< BlockData<VoxelType> > pNewBlockData(new BlockData<VoxelType>(*(block.m_pBlockData)));
|
POLYVOX_SHARED_PTR< BlockData<VoxelType> > pNewBlockData(new BlockData<VoxelType>(*(block.m_pBlockData)));
|
||||||
block.m_pBlockData = pNewBlockData;
|
block.m_pBlockData = pNewBlockData;
|
||||||
block.m_bIsPotentiallySharable = false;
|
m_vecBlockIsPotentiallyHomogenous[uBlockIndex] = false;
|
||||||
block.m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
block.m_pBlockData->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,32 +203,36 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void Volume<VoxelType>::idle(uint32_t uAmount)
|
void Volume<VoxelType>::idle(uint32_t 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_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
|
||||||
{
|
{
|
||||||
Block<VoxelType> block = m_pBlocks[i];
|
if(m_vecBlockIsPotentiallyHomogenous[i])
|
||||||
if(block.m_bIsPotentiallySharable)
|
|
||||||
{
|
{
|
||||||
bool isSharable = block.m_pBlockData->isHomogeneous();
|
if(m_pBlocks[i].m_pBlockData->isHomogeneous())
|
||||||
if(isSharable)
|
|
||||||
{
|
{
|
||||||
VoxelType homogeneousValue = block.m_pBlockData->getVoxelAt(0,0,0);
|
VoxelType homogeneousValue = m_pBlocks[i].m_pBlockData->getVoxelAt(0,0,0);
|
||||||
delete block.m_pBlockData;
|
|
||||||
|
|
||||||
block.m_pBlockData = getHomogenousBlockData(homogeneousValue);
|
m_pBlocks[i].m_pBlockData = getHomogenousBlockData(homogeneousValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Either way, we have now determined whether the block was sharable. So it's not *potentially* sharable.
|
//Either way, we have now determined whether the block was sharable. So it's not *potentially* sharable.
|
||||||
block.m_bIsPotentiallySharable = false;
|
m_vecBlockIsPotentiallyHomogenous[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note - this second step should probably happen immediatly, rather than in this function.
|
//FIXME - Better way to do this? Maybe using for_each()?
|
||||||
//Use of a shared pointer system would allow this.
|
std::list< std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator > itersToDelete;
|
||||||
|
for(std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator iter = m_pHomogenousBlockData.begin(); iter != m_pHomogenousBlockData.end(); ++iter)
|
||||||
|
{
|
||||||
|
if(iter->second.unique())
|
||||||
|
{
|
||||||
|
itersToDelete.push_back(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(std::list< std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator >::iterator listIter = itersToDelete.begin(); listIter != itersToDelete.end(); ++listIter)
|
||||||
|
{
|
||||||
|
m_pHomogenousBlockData.erase(*listIter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -257,7 +262,7 @@ namespace PolyVox
|
|||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
POLYVOX_SHARED_PTR< BlockData<VoxelType> > Volume<VoxelType>::getHomogenousBlockData(VoxelType tHomogenousValue) const
|
POLYVOX_SHARED_PTR< BlockData<VoxelType> > Volume<VoxelType>::getHomogenousBlockData(VoxelType tHomogenousValue) const
|
||||||
{
|
{
|
||||||
typename std::map<VoxelType, POLYVOX_WEAK_PTR< BlockData<VoxelType> > >::iterator iterResult = m_pHomogenousBlockData.find(tHomogenousValue);
|
std::map<VoxelType, POLYVOX_SHARED_PTR< BlockData<VoxelType> > >::iterator iterResult = m_pHomogenousBlockData.find(tHomogenousValue);
|
||||||
if(iterResult == m_pHomogenousBlockData.end())
|
if(iterResult == m_pHomogenousBlockData.end())
|
||||||
{
|
{
|
||||||
Block<VoxelType> block;
|
Block<VoxelType> block;
|
||||||
@ -271,8 +276,8 @@ namespace PolyVox
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//iterResult->second.m_uReferenceCount++;
|
//iterResult->second.m_uReferenceCount++;
|
||||||
POLYVOX_SHARED_PTR< BlockData<VoxelType> > result(iterResult->second);
|
//POLYVOX_SHARED_PTR< BlockData<VoxelType> > result(iterResult->second);
|
||||||
return result;
|
return iterResult->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
Loading…
x
Reference in New Issue
Block a user