Starting to split Block class into CompressedBlock and UncompressedBlock.
This commit is contained in:
parent
9ff95f7061
commit
0d92bc6c8c
@ -93,7 +93,7 @@ public:
|
||||
|
||||
virtual void pageIn(const PolyVox::Region& region, Block<MaterialDensityPair44>* pBlockData)
|
||||
{
|
||||
pBlockData->createUncompressedData();
|
||||
/*pBlockData->createUncompressedData();
|
||||
|
||||
Perlin perlin(2,2,1,234);
|
||||
|
||||
@ -134,7 +134,7 @@ public:
|
||||
pBlockData->setVoxelAt(x - region.getLowerX(), y - region.getLowerY(), z - region.getLowerZ(), voxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
virtual void pageOut(const PolyVox::Region& region, Block<MaterialDensityPair44>* /*pBlockData*/)
|
||||
|
@ -52,9 +52,6 @@ namespace PolyVox
|
||||
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
||||
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||
|
||||
void createUncompressedData(void);
|
||||
void destroyUncompressedData(void);
|
||||
|
||||
uint32_t calculateSizeInBytes(void);
|
||||
|
||||
public:
|
||||
|
@ -66,12 +66,12 @@ namespace PolyVox
|
||||
|
||||
//Temporarily create the block data. This is just so we can compress it an discard it.
|
||||
// FIXME - this is a temporary solution.
|
||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||
/*const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||
m_tUncompressedData = new VoxelType[uNoOfVoxels];
|
||||
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, VoxelType());
|
||||
m_bIsUncompressedDataModified = true;
|
||||
|
||||
destroyUncompressedData();
|
||||
destroyUncompressedData();*/
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -127,7 +127,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::setCompressedData(const uint8_t* const data, uint32_t dataLength)
|
||||
{
|
||||
POLYVOX_ASSERT(m_pCompressedData, "Compressed data is NULL");
|
||||
//POLYVOX_ASSERT(m_pCompressedData, "Compressed data is NULL");
|
||||
POLYVOX_ASSERT(m_pCompressedData != data, "Attempting to copy data onto itself");
|
||||
|
||||
delete[] m_pCompressedData;
|
||||
@ -163,109 +163,6 @@ namespace PolyVox
|
||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::destroyUncompressedData()
|
||||
{
|
||||
if(!hasUncompressedData())
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "No uncompressed data to compress.");
|
||||
}
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
|
||||
|
||||
//If the uncompressed data hasn't actually been
|
||||
//modified then we don't need to redo the compression.
|
||||
if(m_bIsUncompressedDataModified)
|
||||
{
|
||||
// Delete the old compressed data as we'll create a new one
|
||||
delete[] m_pCompressedData;
|
||||
m_pCompressedData = 0;
|
||||
|
||||
void* pSrcData = reinterpret_cast<void*>(m_tUncompressedData);
|
||||
uint32_t uSrcLength = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
||||
|
||||
uint8_t tempBuffer[10000];
|
||||
void* pDstData = reinterpret_cast<void*>( tempBuffer );
|
||||
uint32_t uDstLength = 10000;
|
||||
|
||||
uint32_t uCompressedLength = 0;
|
||||
|
||||
try
|
||||
{
|
||||
uCompressedLength = m_pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
|
||||
// Create new compressed data and copy across
|
||||
m_pCompressedData = new uint8_t[uCompressedLength];
|
||||
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
||||
m_uCompressedDataLength = uCompressedLength;
|
||||
}
|
||||
catch(std::exception&)
|
||||
{
|
||||
// It is possible for the compression to fail. A common cause for this would be if the destination
|
||||
// buffer is not big enough. So now we try again using a buffer that is definitely big enough.
|
||||
// Note that ideally we will choose our earlier buffer size so that this almost never happens.
|
||||
logWarning() << "The compressor failed to compress the block, proabaly due to the buffer being too small.";
|
||||
logWarning() << "The compression will be tried again with a larger buffer";
|
||||
uint32_t uMaxCompressedSize = m_pCompressor->getMaxCompressedSize(uSrcLength);
|
||||
uint8_t* buffer = new uint8_t[ uMaxCompressedSize ];
|
||||
|
||||
pDstData = reinterpret_cast<void*>( buffer );
|
||||
uDstLength = uMaxCompressedSize;
|
||||
|
||||
try
|
||||
{
|
||||
uCompressedLength = m_pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
|
||||
// Create new compressed data and copy across
|
||||
m_pCompressedData = new uint8_t[uCompressedLength];
|
||||
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
||||
m_uCompressedDataLength = uCompressedLength;
|
||||
}
|
||||
catch(std::exception&)
|
||||
{
|
||||
// At this point it didn't work even with a bigger buffer.
|
||||
// Not much more we can do so just rethrow the exception.
|
||||
delete[] buffer;
|
||||
POLYVOX_THROW(std::runtime_error, "Failed to compress block data");
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
//Flag the uncompressed data as no longer being used.
|
||||
delete[] m_tUncompressedData;
|
||||
m_tUncompressedData = 0;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::createUncompressedData()
|
||||
{
|
||||
if(hasUncompressedData())
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "Uncompressed data already exists.");
|
||||
}
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
|
||||
|
||||
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||
|
||||
void* pSrcData = reinterpret_cast<void*>(m_pCompressedData);
|
||||
void* pDstData = reinterpret_cast<void*>(m_tUncompressedData);
|
||||
uint32_t uSrcLength = m_uCompressedDataLength;
|
||||
uint32_t uDstLength = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
||||
|
||||
//MinizCompressor compressor;
|
||||
//RLECompressor<VoxelType, uint16_t> compressor;
|
||||
uint32_t uUncompressedLength = m_pCompressor->decompress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
|
||||
POLYVOX_ASSERT(uUncompressedLength == m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType), "Destination length has changed.");
|
||||
|
||||
//m_tUncompressedData = reinterpret_cast<VoxelType*>(uncompressedResult.ptr);
|
||||
|
||||
m_bIsUncompressedDataModified = false;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
uint32_t Block<VoxelType>::calculateSizeInBytes(void)
|
||||
{
|
||||
|
@ -337,11 +337,6 @@ namespace PolyVox
|
||||
mutable std::map<Vector3DInt32, VoxelType*, BlockPositionCompare> m_pUncompressedBlockCache;
|
||||
mutable std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare> m_pBlocks;
|
||||
|
||||
// The cache of uncompressed blocks. The uncompressed block data and the timestamps are stored here rather
|
||||
// than in the Block class. This is so that in the future each VolumeIterator might to maintain its own cache
|
||||
// of blocks. However, this could mean the same block data is uncompressed and modified in more than one
|
||||
// location in memory... could be messy with threading.
|
||||
mutable std::vector< Block<VoxelType>* > m_vecBlocksWithUncompressedData;
|
||||
mutable uint32_t m_uTimestamper;
|
||||
mutable Vector3DInt32 m_v3dLastAccessedBlockPos;
|
||||
mutable VoxelType* m_pLastAccessedBlock;
|
||||
|
@ -102,7 +102,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
LargeVolume<VoxelType>::~LargeVolume()
|
||||
{
|
||||
flushAll();
|
||||
//flushAll();
|
||||
|
||||
// Only delete the compressor if it was created by us (in the constructor), not by the user.
|
||||
if(m_bIsOurCompressor)
|
||||
@ -509,11 +509,6 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::clearBlockCache(void)
|
||||
{
|
||||
for(uint32_t ct = 0; ct < m_vecBlocksWithUncompressedData.size(); ct++)
|
||||
{
|
||||
m_vecBlocksWithUncompressedData[ct]->destroyUncompressedData();
|
||||
}
|
||||
m_vecBlocksWithUncompressedData.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -571,7 +566,9 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itBlock) const
|
||||
{
|
||||
if(itBlock->second.hasUncompressedData())
|
||||
POLYVOX_ASSERT(false, "This function has not been implemented properly");
|
||||
|
||||
/*if(itBlock->second.hasUncompressedData())
|
||||
{
|
||||
itBlock->second.destroyUncompressedData();
|
||||
}
|
||||
@ -585,9 +582,11 @@ namespace PolyVox
|
||||
Region reg(v3dLower, v3dUpper);
|
||||
|
||||
m_pPager->pageOut(reg, &(itBlock->second));
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
for(uint32_t ct = 0; ct < m_vecBlocksWithUncompressedData.size(); ct++)
|
||||
// FIXME - the code below used to make sure the uncompressed version of the data was removed. Reinstate something similar.
|
||||
/*for(uint32_t ct = 0; ct < m_vecBlocksWithUncompressedData.size(); ct++)
|
||||
{
|
||||
// find the block in the uncompressed cache
|
||||
if(m_vecBlocksWithUncompressedData[ct] == &(itBlock->second))
|
||||
@ -598,7 +597,7 @@ namespace PolyVox
|
||||
m_vecBlocksWithUncompressedData.resize(m_vecBlocksWithUncompressedData.size()-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
m_pBlocks.erase(itBlock);
|
||||
}
|
||||
@ -676,47 +675,6 @@ namespace PolyVox
|
||||
m_v3dLastAccessedBlockPos = v3dBlockPos;
|
||||
|
||||
return m_pLastAccessedBlock;
|
||||
|
||||
if(block->hasUncompressedData())
|
||||
{
|
||||
return block->m_tUncompressedData;
|
||||
}
|
||||
|
||||
//If we are allowed to compress then check whether we need to
|
||||
if(m_vecBlocksWithUncompressedData.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_vecBlocksWithUncompressedData.size(); ct++)
|
||||
{
|
||||
if(m_vecBlocksWithUncompressedData[ct]->timestamp < uLeastRecentTimestamp)
|
||||
{
|
||||
uLeastRecentTimestamp = m_vecBlocksWithUncompressedData[ct]->timestamp;
|
||||
leastRecentlyUsedBlockIndex = ct;
|
||||
}
|
||||
}
|
||||
|
||||
//Compress the least recently used block.
|
||||
m_vecBlocksWithUncompressedData[leastRecentlyUsedBlockIndex]->destroyUncompressedData();
|
||||
|
||||
//We don't actually remove any elements from this vector, we
|
||||
//simply change the pointer to point at the new uncompressed bloack.
|
||||
m_vecBlocksWithUncompressedData[leastRecentlyUsedBlockIndex] = block;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vecBlocksWithUncompressedData.push_back(block);
|
||||
}
|
||||
|
||||
block->createUncompressedData();
|
||||
|
||||
m_pLastAccessedBlock = block->m_tUncompressedData;
|
||||
POLYVOX_ASSERT(m_pLastAccessedBlock, "Block has no uncompressed data");
|
||||
return m_pLastAccessedBlock;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -747,8 +705,8 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
//Memory used by the block cache.
|
||||
uSizeInBytes += m_vecBlocksWithUncompressedData.capacity() * sizeof(Block<VoxelType>);
|
||||
uSizeInBytes += m_vecBlocksWithUncompressedData.size() * m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
|
||||
//uSizeInBytes += m_vecBlocksWithUncompressedData.capacity() * sizeof(Block<VoxelType>);
|
||||
//uSizeInBytes += m_vecBlocksWithUncompressedData.size() * m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
|
||||
|
||||
return uSizeInBytes;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user