From 498f21f63fb89a39c17702a5bae230123a33ca34 Mon Sep 17 00:00:00 2001 From: Daviw Williams Date: Wed, 2 Oct 2013 16:48:30 +0200 Subject: [PATCH] Replaced arrays with std::vector. --- .../PolyVoxCore/MinizBlockCompressor.h | 5 +++ .../PolyVoxCore/MinizBlockCompressor.inl | 31 ++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h index 577cf782..04a7438f 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h @@ -44,12 +44,17 @@ namespace PolyVox void decompress(CompressedBlock* pSrcBlock, UncompressedBlock* pDstBlock); private: + uint32_t getExpectedCompressedSize(uint32_t uUncompressedInputSize); uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize); uint32_t compressWithMiniz(const void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength); uint32_t decompressWithMiniz(const void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength); unsigned int m_uCompressionFlags; + // Data gets compressed into this, then we check how big the result + // is and copy the required number of bytes to the destination block. + std::vector m_vecTempBuffer; + // tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k). tdefl_compressor* m_pDeflator; }; diff --git a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl index fbba8856..c820ec34 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl @@ -62,9 +62,11 @@ namespace PolyVox void* pSrcData = reinterpret_cast(pSrcBlock->getData()); size_t uSrcLength = pSrcBlock->getDataSizeInBytes(); - uint8_t tempBuffer[1000]; - uint8_t* pDstData = reinterpret_cast( tempBuffer ); - size_t uDstLength = 1000; + // This compressor is expected to be used many times to compress a large number of blocks, but they are all + // expected to have the same size. Therefore the resize() function below will only perform allocation once. + m_vecTempBuffer.resize(getExpectedCompressedSize(uSrcLength)); + uint8_t* pDstData = &(m_vecTempBuffer[0]); + size_t uDstLength = m_vecTempBuffer.size(); uint32_t uCompressedLength = 0; @@ -82,12 +84,13 @@ namespace PolyVox // 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, probabaly due to the buffer being too small."; - logWarning() << "The compression will be tried again with a larger buffer"; - uint32_t uMaxCompressedSize = getMaxCompressedSize(uSrcLength); - uint8_t* buffer = new uint8_t[ uMaxCompressedSize ]; + logWarning() << "The compression will be tried again with a larger buffer."; - pDstData = reinterpret_cast( buffer ); - uDstLength = uMaxCompressedSize; + std::vector vecExtraBigBuffer; + vecExtraBigBuffer.resize(getMaxCompressedSize(uSrcLength)); + + uint8_t* pDstData = &(vecExtraBigBuffer[0]); + size_t uDstLength = vecExtraBigBuffer.size(); try { @@ -101,11 +104,8 @@ namespace PolyVox { // 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; } } @@ -125,6 +125,15 @@ namespace PolyVox POLYVOX_THROW_IF(uUncompressedLength != pDstBlock->getDataSizeInBytes(), std::runtime_error, "Decompressed data does not have the expected length"); } + template + uint32_t MinizBlockCompressor::getExpectedCompressedSize(uint32_t uUncompressedInputSize) + { + // We expect this block compressor will be used for smoothly changing volume data such as density fields and so + // the compression rate might not be great. The value beloew is basically a guess based on previous experience. + uint32_t uExpectedCompressionRate = 4; + return uUncompressedInputSize / uExpectedCompressionRate; + } + template uint32_t MinizBlockCompressor::getMaxCompressedSize(uint32_t uUncompressedInputSize) {