Pulling compression out of SimpleVolume.

This commit is contained in:
David Williams
2011-04-29 23:04:33 +01:00
parent 032accd915
commit 26eb865897
3 changed files with 4 additions and 210 deletions

View File

@ -207,44 +207,6 @@ namespace PolyVox
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
}
////////////////////////////////////////////////////////////////////////////////
/// Enabling compression allows significantly more data to be stored in memory.
/// \param bCompressionEnabled Specifies whether compression is enabled.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void SimpleVolume<VoxelType>::setCompressionEnabled(bool bCompressionEnabled)
{
//Early out - nothing to do
if(m_bCompressionEnabled == bCompressionEnabled)
{
return;
}
m_bCompressionEnabled = bCompressionEnabled;
if(m_bCompressionEnabled)
{
//If compression has been enabled then we need to start honouring the max number of
//uncompressed blocks. Because compression has been disabled for a while we might have
//gone above that limit. Easiest solution is just to clear the cache and start again.
clearBlockCache();
}
}
////////////////////////////////////////////////////////////////////////////////
/// Increasing the size of the block cache will increase memory but may improve performance.
/// You may want to set this to a large value (e.g. 1024) when you are first loading your
/// volume data and then set it to a smaller value (e.g.64) for general processing.
/// \param uBlockCacheSize The number of blocks for which uncompressed data can be cached.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void SimpleVolume<VoxelType>::setMaxNumberOfUncompressedBlocks(uint16_t uMaxNumberOfUncompressedBlocks)
{
clearBlockCache();
m_uMaxNumberOfUncompressedBlocks = uMaxNumberOfUncompressedBlocks;
}
////////////////////////////////////////////////////////////////////////////////
/// \param tBorder The value to use for voxels outside the volume.
////////////////////////////////////////////////////////////////////////////////
@ -301,11 +263,6 @@ namespace PolyVox
template <typename VoxelType>
void SimpleVolume<VoxelType>::clearBlockCache(void)
{
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
{
m_vecUncompressedBlockCache[ct]->block.compress();
}
m_vecUncompressedBlockCache.clear();
}
////////////////////////////////////////////////////////////////////////////////
@ -328,20 +285,16 @@ namespace PolyVox
}
m_uTimestamper = 0;
m_uMaxNumberOfUncompressedBlocks = 16;
m_uBlockSideLength = uBlockSideLength;
m_pUncompressedBorderData = 0;
m_v3dLastAccessedBlockPos = Vector3DInt32(0,0,0); //There are no invalid positions, but initially the m_pLastAccessedBlock pointer will be null;
m_pLastAccessedBlock = 0;
m_bCompressionEnabled = true;
m_regValidRegion = regValidRegion;
m_regValidRegionInBlocks.setLowerCorner(m_regValidRegion.getLowerCorner() / static_cast<int32_t>(uBlockSideLength));
m_regValidRegionInBlocks.setUpperCorner(m_regValidRegion.getUpperCorner() / static_cast<int32_t>(uBlockSideLength));
setMaxNumberOfUncompressedBlocks(m_uMaxNumberOfUncompressedBlocks);
//Clear the previous data
m_pBlocks.clear();
@ -365,33 +318,6 @@ namespace PolyVox
template <typename VoxelType>
void SimpleVolume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, LoadedBlock >::iterator itBlock) const
{
/*if(m_funcDataOverflowHandler)
{
Vector3DInt32 v3dPos = itBlock->first;
Vector3DInt32 v3dLower(v3dPos.getX() << m_uBlockSideLengthPower, v3dPos.getY() << m_uBlockSideLengthPower, v3dPos.getZ() << m_uBlockSideLengthPower);
Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength-1, m_uBlockSideLength-1, m_uBlockSideLength-1);
Region reg(v3dLower, v3dUpper);
ConstVolumeProxy<VoxelType> ConstVolumeProxy(*this, reg);
m_funcDataOverflowHandler(ConstVolumeProxy, reg);
}*/
if(m_bCompressionEnabled) {
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
{
// find the block in the uncompressed cache
if(m_vecUncompressedBlockCache[ct] == &(itBlock->second))
{
// TODO: compression is unneccessary? or will not compressing this cause a memleak?
itBlock->second.block.compress();
// put last object in cache here
m_vecUncompressedBlockCache[ct] = m_vecUncompressedBlockCache.back();
// decrease cache size by one since last element is now in here twice
m_vecUncompressedBlockCache.resize(m_vecUncompressedBlockCache.size()-1);
break;
}
}
}
m_pBlocks.erase(itBlock);
}
@ -422,17 +348,7 @@ namespace PolyVox
template <typename VoxelType>
typename SimpleVolume<VoxelType>::Block* SimpleVolume<VoxelType>::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const
{
Vector3DInt32 v3dBlockPos(uBlockX, uBlockY, uBlockZ);
//Check if we have the same block as last time, if so there's no need to even update
//the time stamp. If we updated it everytime then that would be every time we touched
//a voxel, which would overflow a uint32_t and require us to use a uint64_t instead.
//This check should also provide a significant speed boost as usually it is true.
if((v3dBlockPos == m_v3dLastAccessedBlockPos) && (m_pLastAccessedBlock != 0))
{
assert(m_pLastAccessedBlock->m_tUncompressedData);
return m_pLastAccessedBlock;
}
Vector3DInt32 v3dBlockPos(uBlockX, uBlockY, uBlockZ);
typename std::map<Vector3DInt32, LoadedBlock >::iterator itBlock = m_pBlocks.find(v3dBlockPos);
// check whether the block is already loaded
@ -454,38 +370,8 @@ namespace PolyVox
assert(m_pLastAccessedBlock->m_tUncompressedData);
return m_pLastAccessedBlock;
}
//If we are allowed to compress then check whether we need to
if((m_bCompressionEnabled) && (m_vecUncompressedBlockCache.size() == m_uMaxNumberOfUncompressedBlocks))
{
int32_t leastRecentlyUsedBlockIndex = -1;
uint32_t uLeastRecentTimestamp = (std::numeric_limits<uint32_t>::max)();
//Currently we find the oldest block by iterating over the whole array. Of course we could store the blocks sorted by
//timestamp (set, priority_queue, etc) but then we'll need to move them around as the timestamp changes. Can come back
//to this if it proves to be a bottleneck (compraed to the cost of actually doing the compression/decompression).
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
{
if(m_vecUncompressedBlockCache[ct]->timestamp < uLeastRecentTimestamp)
{
uLeastRecentTimestamp = m_vecUncompressedBlockCache[ct]->timestamp;
leastRecentlyUsedBlockIndex = ct;
}
}
//Compress the least recently used block.
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress();
//We don't actually remove any elements from this vector, we
//simply change the pointer to point at the new uncompressed bloack.
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex] = &loadedBlock;
}
else
{
m_vecUncompressedBlockCache.push_back(&loadedBlock);
}
loadedBlock.block.uncompress();
//loadedBlock.block.uncompress();
m_pLastAccessedBlock = &(loadedBlock.block);
assert(m_pLastAccessedBlock->m_tUncompressedData);
@ -519,10 +405,6 @@ namespace PolyVox
uSizeInBytes += i->second.block.calculateSizeInBytes();
}
//Memory used by the block cache.
uSizeInBytes += m_vecUncompressedBlockCache.capacity() * sizeof(LoadedBlock);
uSizeInBytes += m_vecUncompressedBlockCache.size() * m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
//Memory used by border data.
if(m_pUncompressedBorderData)
{