Applied ker's patch for prefetch and flush.
This commit is contained in:
@ -186,6 +186,17 @@ namespace PolyVox
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at a 3D vector position
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
/// makes sure all the voxels in the given region are loaded
|
||||
/// if MaxNumberOfBlocksInMemory is not large enough to support the region
|
||||
/// this function will return false and the volume is unchanged
|
||||
/// if all the voxels in the given region are already loaded, this function will not do anything but still return true.
|
||||
/// other blocks might be unloaded to make space for the new blocks
|
||||
bool prefetchRegion(Region regPrefetch);
|
||||
/// attempts to unload all the voxels in the given region.
|
||||
/// there is no guarantee that any voxels are unloaded
|
||||
/// try unloading a region whose sidelengths are multiples of BlockSideLength
|
||||
/// returns the number of voxels that were actually unloaded
|
||||
uint32_t flushRegion(Region regFlush);
|
||||
|
||||
void clearBlockCache(void);
|
||||
float calculateCompressionRatio(void);
|
||||
|
@ -375,6 +375,63 @@ namespace PolyVox
|
||||
return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
bool Volume<VoxelType>::prefetchRegion(Region regPrefetch)
|
||||
{
|
||||
Vector3DInt32 start;
|
||||
for(int i = 0; i < 3; i++) start.setElement(i, regPrefetch.getLowerCorner().getElement(i) >> m_uBlockSideLengthPower);
|
||||
Vector3DInt32 end;
|
||||
for(int i = 0; i < 3; i++) end.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower);
|
||||
Vector3DInt32 size = end-start + Vector3DInt32(1,1,1);
|
||||
int32_t numblocks = size.getX() * size.getY() * size.getZ();
|
||||
if(numblocks > m_uMaxNumberOfBlocksInMemory) {
|
||||
return false;
|
||||
}
|
||||
if(numblocks > (m_uMaxNumberOfBlocksInMemory - m_pBlocks.size())) {
|
||||
// TODO: unload enough blocks to support the blocks that will be loaded.
|
||||
}
|
||||
for(int32_t x = start.getX(); x <= end.getX(); x++) {
|
||||
for(int32_t y = start.getY(); y <= end.getY(); y++) {
|
||||
for(int32_t z = start.getZ(); z <= end.getZ(); z++) {
|
||||
Block<VoxelType>* block = getUncompressedBlock(x,y,z);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
uint32_t Volume<VoxelType>::flushRegion(Region regFlush)
|
||||
{
|
||||
Vector3DInt32 start;
|
||||
for(int i = 0; i < 3; i++) start.setElement(i, regFlush.getLowerCorner().getElement(i) >> m_uBlockSideLengthPower);
|
||||
Vector3DInt32 end;
|
||||
for(int i = 0; i < 3; i++) end.setElement(i, regFlush.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower);
|
||||
uint32_t count = 0;
|
||||
for(int32_t x = start.getX(); x <= end.getX(); x++) {
|
||||
for(int32_t y = start.getY(); y <= end.getY(); y++) {
|
||||
for(int32_t z = start.getZ(); z <= end.getZ(); z++) {
|
||||
Vector3DInt32 pos(x,y,z);
|
||||
if(m_v3dLastAccessedBlockPos == pos) {
|
||||
m_pLastAccessedBlock = NULL;
|
||||
}
|
||||
typename std::map<Vector3DInt32, LoadedBlock>::iterator itBlock = m_pBlocks.find(pos);
|
||||
if(itBlock == m_pBlocks.end()) {
|
||||
// not loaded, not unloading
|
||||
continue;
|
||||
}
|
||||
eraseBlock(itBlock);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count > ((std::numeric_limits<uint32_t>::max)() >> (m_uBlockSideLengthPower*3))) {
|
||||
// eh, this will overflow... I have no idea what to do here
|
||||
return (std::numeric_limits<uint32_t>::max)();
|
||||
}
|
||||
return count << (m_uBlockSideLengthPower*3);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Volume<VoxelType>::clearBlockCache(void)
|
||||
{
|
||||
@ -463,6 +520,22 @@ namespace PolyVox
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user