From 5eb538e9250c04d6cefd778fedfcf61e5d42c087 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sat, 17 Oct 2009 20:39:38 +0000 Subject: [PATCH] Added code to determine how much memory a volume is using. Also map of homogenous regions is no longer static. --- .../PolyVoxCore/include/PolyVoxImpl/Block.h | 1 + .../PolyVoxCore/include/PolyVoxImpl/Block.inl | 14 ++++++ library/PolyVoxCore/include/Volume.h | 15 +++---- library/PolyVoxCore/include/Volume.inl | 43 ++++++++++++++++++- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.h b/library/PolyVoxCore/include/PolyVoxImpl/Block.h index a9c9a474..a303cb58 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.h +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.h @@ -51,6 +51,7 @@ namespace PolyVox void fill(VoxelType tValue); bool isHomogeneous(void); + uint32_t sizeInChars(void); private: uint16_t m_uSideLength; diff --git a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl index 3082be6a..770a48b5 100644 --- a/library/PolyVoxCore/include/PolyVoxImpl/Block.inl +++ b/library/PolyVoxCore/include/PolyVoxImpl/Block.inl @@ -169,5 +169,19 @@ namespace PolyVox } return true; } + + template + uint32_t Block::sizeInChars(void) + { + uint32_t uSizeInChars = sizeof(Block); + + if(m_tData != 0) + { + const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; + uSizeInChars += uNoOfVoxels * sizeof(VoxelType); + } + + return uSizeInChars; + } #pragma endregion } diff --git a/library/PolyVoxCore/include/Volume.h b/library/PolyVoxCore/include/Volume.h index 131502d2..19949046 100644 --- a/library/PolyVoxCore/include/Volume.h +++ b/library/PolyVoxCore/include/Volume.h @@ -72,7 +72,7 @@ namespace PolyVox /// to check for and remove duplicate homogeneous regions whenever you have spare /// processing time. /// - /// -# Copying a volume naturally means that all the voxels in the second voluem are + /// -# Copying a volume naturally means that all the voxels in the second volume are /// the same as the first. Therefore volume copying is a relatively fast operation in /// which all the blocks in the second volume simply reference the first volume. Future /// modifications to either volume will, of course, cause the blocks to become unshared. @@ -111,7 +111,7 @@ namespace PolyVox public: ///Constructor - Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 64); + Volume(uint16_t uWidth, uint16_t uHeight, uint16_t uDepth, uint16_t uBlockSideLength = 32); ///Destructor ~Volume(); @@ -136,9 +136,11 @@ namespace PolyVox void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue); void tidyUpMemory(uint32_t uNoOfBlocksToProcess = (std::numeric_limits::max)()); + ///Calculates roughly how much memory is used by the volume. + uint32_t calculateSizeInChars(void); private: - POLYVOX_SHARED_PTR< Block > getHomogenousBlock(VoxelType tHomogenousValue) const; + POLYVOX_SHARED_PTR< Block > getHomogenousBlock(VoxelType tHomogenousValue); std::vector< POLYVOX_SHARED_PTR< Block > > m_pBlocks; std::vector m_vecBlockIsPotentiallyHomogenous; @@ -148,8 +150,7 @@ namespace PolyVox //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. - //FIXME - How do we handle sharing between two volumes with different block sizes?! - static std::map > > m_pHomogenousBlock; + std::map > > m_pHomogenousBlock; uint32_t m_uNoOfBlocksInVolume; @@ -177,10 +178,6 @@ namespace PolyVox uint32_t m_uCurrentBlockForTidying; }; - //Required for the static member - template std::map > > Volume::m_pHomogenousBlock; - - //Some handy typedefs typedef Volume FloatVolume; typedef Volume UInt8Volume; diff --git a/library/PolyVoxCore/include/Volume.inl b/library/PolyVoxCore/include/Volume.inl index 2fe961ff..ad94df4c 100644 --- a/library/PolyVoxCore/include/Volume.inl +++ b/library/PolyVoxCore/include/Volume.inl @@ -353,11 +353,52 @@ namespace PolyVox } } } + + //////////////////////////////////////////////////////////////////////////////// + /// The returned value is not precise because it is hard to say how much memory + /// STL vectors and maps take iternally, but it accounts for all the block data + /// which is by far the most significant contributer. The returned value is in + /// multiples of the basic type 'char', which is equal to a byte on most systems. + /// Important Note: The value returned by this function is only correct if there + /// is only one volume in memory. This is because blocks are shared between volumes + /// without any one volume being the real owner. + /// \return The amount of memory used by the volume. + //////////////////////////////////////////////////////////////////////////////// + template + uint32_t Volume::calculateSizeInChars(void) + { + //The easy part + uint32_t uSize = sizeof(Volume); + + //Now determine the size of the non homogenous data. + for(uint32_t ct = 0; ct < m_pBlocks.size(); ct++) + { + if(m_pBlocks[ct].unique()) //Check for non-homogenity + { + uSize += sizeof(POLYVOX_SHARED_PTR< Block >); //The pointer + uSize += m_pBlocks[ct]->sizeInChars(); //The data it points to. + } + } + + //The size of the m_vecBlockIsPotentiallyHomogenous vector + uSize += m_vecBlockIsPotentiallyHomogenous.size() * sizeof(bool); + + //Now determine the size of the homogenous data. + //We could just get the number of blocks in the map and multiply + //by the block size, but it feels safer to do it 'properly'. + for(std::map > >::const_iterator iter = m_pHomogenousBlock.begin(); iter != m_pHomogenousBlock.end(); iter++) + { + uSize += sizeof(POLYVOX_SHARED_PTR< Block >); //The pointer + uSize += iter->second->sizeInChars(); //The data it points to. + } + + return uSize; + } #pragma endregion #pragma region Private Implementation template - POLYVOX_SHARED_PTR< Block > Volume::getHomogenousBlock(VoxelType tHomogenousValue) const + POLYVOX_SHARED_PTR< Block > Volume::getHomogenousBlock(VoxelType tHomogenousValue) { typename std::map > >::iterator iterResult = m_pHomogenousBlock.find(tHomogenousValue); if(iterResult == m_pHomogenousBlock.end())