diff --git a/Engine/source/T3D/decal/decalInstance.h b/Engine/source/T3D/decal/decalInstance.h index 9365f4a3a..c13fb6ad9 100644 --- a/Engine/source/T3D/decal/decalInstance.h +++ b/Engine/source/T3D/decal/decalInstance.h @@ -43,6 +43,13 @@ class DecalInstance { public: + typedef DWordDataBlob<256> SizeClass1; + typedef DWordDataBlob<512> SizeClass2; + typedef DWordDataBlob<1024> SizeClass3; + typedef ThreeTieredChunker DecalDataChunker; + + DecalDataChunker::Handle mAllocHandle; + DecalData *mDataBlock; Point3F mPosition; diff --git a/Engine/source/T3D/decal/decalManager.cpp b/Engine/source/T3D/decal/decalManager.cpp index bf1e7ad2a..39e90f159 100644 --- a/Engine/source/T3D/decal/decalManager.cpp +++ b/Engine/source/T3D/decal/decalManager.cpp @@ -200,17 +200,6 @@ S32 QSORT_CALLBACK cmpDecalRenderOrder( const void *p1, const void *p2 ) } // namespace {} -// These numbers should be tweaked to get as many dynamically placed decals -// as possible to allocate buffer arrays with the FreeListChunker. -enum -{ - SIZE_CLASS_0 = 256, - SIZE_CLASS_1 = 512, - SIZE_CLASS_2 = 1024, - - NUM_SIZE_CLASSES = 3 -}; - //------------------------------------------------------------------------- // DecalManager //------------------------------------------------------------------------- @@ -228,10 +217,6 @@ DecalManager::DecalManager() mDirty = false; - mChunkers[0] = new FreeListChunkerUntyped( SIZE_CLASS_0 * sizeof( U8 ) ); - mChunkers[1] = new FreeListChunkerUntyped( SIZE_CLASS_1 * sizeof( U8 ) ); - mChunkers[2] = new FreeListChunkerUntyped( SIZE_CLASS_2 * sizeof( U8 ) ); - GFXDevice::getDeviceEventSignal().notify(this, &DecalManager::_handleGFXEvent); } @@ -240,9 +225,6 @@ DecalManager::~DecalManager() GFXDevice::getDeviceEventSignal().remove(this, &DecalManager::_handleGFXEvent); clearData(); - - for( U32 i = 0; i < NUM_SIZE_CLASSES; ++ i ) - delete mChunkers[ i ]; } void DecalManager::consoleInit() @@ -913,14 +895,9 @@ void DecalManager::_generateWindingOrder( const Point3F &cornerPoint, VectormVertCount + sizeof( U16 ) * inst->mIndxCount ); - else - data = mChunkers[sizeClass]->alloc(); + inst->mAllocHandle = mChunkers.alloc(sizeof(DecalVertex) * inst->mVertCount + sizeof(U16) * inst->mIndxCount); + U8* data = (U8*)inst->mAllocHandle.ptr; inst->mVerts = reinterpret_cast< DecalVertex* >( data ); data = (U8*)data + sizeof( DecalVertex ) * inst->mVertCount; inst->mIndices = reinterpret_cast< U16* >( data ); @@ -930,15 +907,7 @@ void DecalManager::_freeBuffers( DecalInstance *inst ) { if ( inst->mVerts != NULL ) { - const S32 sizeClass = _getSizeClass( inst ); - - if ( sizeClass == -1 ) - dFree( inst->mVerts ); - else - { - // Use FreeListChunker - mChunkers[sizeClass]->free( inst->mVerts ); - } + mChunkers.free(inst->mAllocHandle); inst->mVerts = NULL; inst->mVertCount = 0; @@ -974,21 +943,6 @@ void DecalManager::_freePools() } } -S32 DecalManager::_getSizeClass( DecalInstance *inst ) const -{ - U32 bytes = inst->mVertCount * sizeof( DecalVertex ) + inst->mIndxCount * sizeof ( U16 ); - - if ( bytes <= SIZE_CLASS_0 ) - return 0; - if ( bytes <= SIZE_CLASS_1 ) - return 1; - if ( bytes <= SIZE_CLASS_2 ) - return 2; - - // Size is outside of the largest chunker. - return -1; -} - void DecalManager::prepRenderImage( SceneRenderState* state ) { PROFILE_SCOPE( DecalManager_RenderDecals ); diff --git a/Engine/source/T3D/decal/decalManager.h b/Engine/source/T3D/decal/decalManager.h index 4ab636f06..9dee7bd8a 100644 --- a/Engine/source/T3D/decal/decalManager.h +++ b/Engine/source/T3D/decal/decalManager.h @@ -110,7 +110,7 @@ class DecalManager : public SceneObject Vector< GFXVertexBufferHandle* > mVBPool; Vector< GFXPrimitiveBufferHandle* > mPBPool; - FreeListChunkerUntyped *mChunkers[3]; + DecalInstance::DecalDataChunker mChunkers; #ifdef DECALMANAGER_DEBUG Vector mDebugPlanes; @@ -167,10 +167,6 @@ class DecalManager : public SceneObject void _freeBuffers( DecalInstance *inst ); void _freePools(); - /// Returns index used to index into the correct sized FreeListChunker for - /// allocating vertex and index arrays. - S32 _getSizeClass( DecalInstance *inst ) const; - // Hide this from Doxygen /// @cond bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event); diff --git a/Engine/source/T3D/sfx/sfx3DWorld.cpp b/Engine/source/T3D/sfx/sfx3DWorld.cpp index 1246895d0..4fe3e64cc 100644 --- a/Engine/source/T3D/sfx/sfx3DWorld.cpp +++ b/Engine/source/T3D/sfx/sfx3DWorld.cpp @@ -62,6 +62,13 @@ SFX3DWorld* gSFX3DWorld; //----------------------------------------------------------------------------- +SFX3DObject::SFX3DObject() + : Parent(NULL, NULL) +{ +} + +//----------------------------------------------------------------------------- + SFX3DObject::SFX3DObject( SFX3DWorld* world, SceneObject* object ) : Parent( world, object ) { diff --git a/Engine/source/T3D/sfx/sfx3DWorld.h b/Engine/source/T3D/sfx/sfx3DWorld.h index 86f233b33..66b3e1dd1 100644 --- a/Engine/source/T3D/sfx/sfx3DWorld.h +++ b/Engine/source/T3D/sfx/sfx3DWorld.h @@ -46,6 +46,8 @@ class SFX3DObject : public SceneObjectLink, public SFXObject< 3 > public: typedef SceneObjectLink Parent; + + SFX3DObject(); /// SFX3DObject( SFX3DWorld* world, SceneObject* object ); diff --git a/Engine/source/T3D/sfx/sfxSpace.h b/Engine/source/T3D/sfx/sfxSpace.h index d43339c30..73f3a3bc2 100644 --- a/Engine/source/T3D/sfx/sfxSpace.h +++ b/Engine/source/T3D/sfx/sfxSpace.h @@ -27,6 +27,10 @@ #include "scene/sceneSpace.h" #endif +#ifndef _SFXSOURCE_H_ +#include "sfx/sfxSource.h" +#endif + #ifndef _SCENEAMBIENTSOUNDOBJECT_H_ #include "scene/mixin/sceneAmbientSoundObject.h" #endif diff --git a/Engine/source/core/dataChunker.cpp b/Engine/source/core/dataChunker.cpp index bd46c3a87..756133b98 100644 --- a/Engine/source/core/dataChunker.cpp +++ b/Engine/source/core/dataChunker.cpp @@ -22,85 +22,3 @@ #include "platform/platform.h" #include "core/dataChunker.h" - - -//---------------------------------------------------------------------------- - -DataChunker::DataChunker(S32 size) -{ - mChunkSize = size; - mCurBlock = NULL; -} - -DataChunker::~DataChunker() -{ - freeBlocks(); -} - -void *DataChunker::alloc(S32 size) -{ - if (size > mChunkSize) - { - DataBlock * temp = (DataBlock*)dMalloc(DataChunker::PaddDBSize + size); - AssertFatal(temp, "Malloc failed"); - constructInPlace(temp); - if (mCurBlock) - { - temp->next = mCurBlock->next; - mCurBlock->next = temp; - } - else - { - mCurBlock = temp; - temp->curIndex = mChunkSize; - } - return temp->getData(); - } - - if(!mCurBlock || size + mCurBlock->curIndex > mChunkSize) - { - const U32 paddDBSize = (sizeof(DataBlock) + 3) & ~3; - DataBlock *temp = (DataBlock*)dMalloc(paddDBSize+ mChunkSize); - AssertFatal(temp, "Malloc failed"); - constructInPlace(temp); - temp->next = mCurBlock; - mCurBlock = temp; - } - - void *ret = mCurBlock->getData() + mCurBlock->curIndex; - mCurBlock->curIndex += (size + 3) & ~3; // dword align - return ret; -} - -DataChunker::DataBlock::DataBlock() -{ - curIndex = 0; - next = NULL; -} - -DataChunker::DataBlock::~DataBlock() -{ -} - -void DataChunker::freeBlocks(bool keepOne) -{ - while (mCurBlock && mCurBlock->next) - { - DataBlock* temp = mCurBlock->next; - dFree(mCurBlock); - mCurBlock = temp; - } - - if (!keepOne) - { - if (mCurBlock) - dFree(mCurBlock); - - mCurBlock = NULL; - } - else if (mCurBlock) - { - mCurBlock->curIndex = 0; - mCurBlock->next = NULL; - } -} diff --git a/Engine/source/core/dataChunker.h b/Engine/source/core/dataChunker.h index 247793650..6e4dafefb 100644 --- a/Engine/source/core/dataChunker.h +++ b/Engine/source/core/dataChunker.h @@ -14,10 +14,13 @@ #ifndef _PLATFORMASSERT_H_ # include "platform/platformAssert.h" #endif +#ifndef _FRAMEALLOCATOR_H_ +#include "core/frameAllocator.h" +#endif #include #include -#include "core/frameAllocator.h" + //#include "math/mMathFn.h" // tgemit - needed here for the moment /// Implements a chunked data allocator. @@ -242,7 +245,7 @@ public: mFreeListHead.push(reinterpret_cast*>(item)); } - void freeBlocks(bool keepOne=false) + void freeBlocks(bool keepOne = false) { BaseDataChunker::freeBlocks(keepOne); } @@ -293,8 +296,106 @@ public: mFreeListHead.push(reinterpret_cast*>(item)); } - void freeBlocks(bool keepOne) + void freeBlocks(bool keepOne = false) { - BaseDataChunker::freeBlocks(keepOne); + mChunker->freeBlocks(keepOne); + } +}; + +template struct DWordDataBlob +{ + U32 data[(byteSize + 3)/ 4]; +}; + +/// Implements a three-tiered chunker +/// K1..3 should be ordered from low to high +template class ThreeTieredChunker +{ +public: + struct Handle + { + U32 tier; + void* ptr; + + Handle() : tier(0), ptr(NULL) { ; } + Handle(const Handle& other) : tier(other.tier), ptr(other.ptr) { ; } + Handle(U32 in_tier, void* in_ptr) : tier(in_tier), ptr(in_ptr) { ; } + + Handle& operator=(const Handle& other) { + tier = other.tier; + ptr = other.ptr; + return *this; + } + }; + +protected: + + ClassChunker mT1; + ClassChunker mT2; + ClassChunker mT3; + +public: + + Handle alloc(U32 byteSize) + { + Handle outH; + + if (byteSize > sizeof(K3)) + { + const U32 wordSize = (byteSize + 3) / 4; + outH = Handle(0, (void*)(new U32[wordSize])); + } + else + { + if (byteSize <= sizeof(K1)) + { + outH = Handle(1, (void*)mT1.alloc()); + } + else if (byteSize <= sizeof(K2)) + { + outH = Handle(2, (void*)mT2.alloc()); + } + else if (byteSize <= sizeof(K3)) + { + outH = Handle(3, (void*)mT3.alloc()); + } + else + { + outH = Handle(0, NULL); + } + } + + return outH; + } + + void free(Handle& item) + { + if (item.ptr == NULL) + return; + + switch (item.tier) + { + case 0: + delete[] ((U32*)item.ptr); + break; + case 1: + mT1.free((K1*)item.ptr); + break; + case 2: + mT2.free((K2*)item.ptr); + break; + case 3: + mT3.free((K3*)item.ptr); + break; + default: + break; + } + } + + void freeBlocks(bool keepOne = false) + { + mT1.freeBlocks(keepOne); + mT2.freeBlocks(keepOne); + mT3.freeBlocks(keepOne); } }; diff --git a/Engine/source/core/frameAllocator.h b/Engine/source/core/frameAllocator.h index 807359946..0b70528f6 100644 --- a/Engine/source/core/frameAllocator.h +++ b/Engine/source/core/frameAllocator.h @@ -330,22 +330,13 @@ public: } U32 getObjectCount(void) const { return mNumObjectsInMemory; } - - /// NOTE: This will return the memory, NOT perform a ones-complement - T* operator ~() { return mMemory; }; - /// NOTE: This will return the memory, NOT perform a ones-complement - const T* operator ~() const { return mMemory; }; - - /// NOTE: This will dereference the memory, NOT do standard unary plus behavior - T& operator +() { return *mMemory; }; - /// NOTE: This will dereference the memory, NOT do standard unary plus behavior - const T& operator +() const { return *mMemory; }; + U32 size(void) const { return mNumObjectsInMemory; } T& operator *() { return *mMemory; }; - const T& operator *() const { return *mMemory; }; + const T& operator *() const { return *mMemory; } - T** operator &() { return &mMemory; }; - const T** operator &() const { return &mMemory; }; + T** operator &() { return &mMemory; } + const T** operator &() const { return &mMemory; } operator T* () { return mMemory; } operator const T* () const { return mMemory; } @@ -354,7 +345,7 @@ public: operator const T& () const { return *mMemory; } operator T() { return *mMemory; } - operator const T() const { return *mMemory; + operator const T() const { return *mMemory; } inline T* address() const { return mMemory; } @@ -366,35 +357,6 @@ public: const T& operator[](const S32 idx) const { return mMemory[idx]; } }; -//----------------------------------------------------------------------------- -// FrameTemp specializations for types with no constructor/destructor -#define FRAME_TEMP_NC_SPEC(type) \ -template<> \ -inline FrameTemp::FrameTemp( const U32 count ) \ -{ \ -AssertFatal( count > 0, "Allocating a FrameTemp with less than one instance" ); \ -mWaterMark = FrameAllocator::getWaterMark(); \ -mMemory = reinterpret_cast( FrameAllocator::alloc( sizeof( type ) * count ) ); \ -} \ -template<>\ -inline FrameTemp::~FrameTemp() \ -{ \ -FrameAllocator::setWaterMark( mWaterMark ); \ -} \ - -FRAME_TEMP_NC_SPEC(char); -FRAME_TEMP_NC_SPEC(float); -FRAME_TEMP_NC_SPEC(double); -FRAME_TEMP_NC_SPEC(bool); -FRAME_TEMP_NC_SPEC(int); -FRAME_TEMP_NC_SPEC(short); - -FRAME_TEMP_NC_SPEC(unsigned char); -FRAME_TEMP_NC_SPEC(unsigned int); -FRAME_TEMP_NC_SPEC(unsigned short); - -#undef FRAME_TEMP_NC_SPEC - //----------------------------------------------------------------------------- #endif // _H_FRAMEALLOCATOR_ diff --git a/Engine/source/core/util/swizzle.h b/Engine/source/core/util/swizzle.h index 9185f7b53..f8038f624 100644 --- a/Engine/source/core/util/swizzle.h +++ b/Engine/source/core/util/swizzle.h @@ -144,8 +144,8 @@ inline void Swizzle::InPlace( void *memory, const dsize_t size ) c // FrameTemp should work because the PNG loading code uses the FrameAllocator, so // it should only get used on an image w/ that size as max -patw FrameTemp buffer( size ); - dMemcpy( ~buffer, memory, size ); - ToBuffer( memory, ~buffer, size ); + dMemcpy( buffer.address(), memory, size); + ToBuffer( memory, buffer.address(), size); } } diff --git a/Engine/source/sfx/sfxSoundscape.cpp b/Engine/source/sfx/sfxSoundscape.cpp index c90015ffc..b65c573d7 100644 --- a/Engine/source/sfx/sfxSoundscape.cpp +++ b/Engine/source/sfx/sfxSoundscape.cpp @@ -39,6 +39,13 @@ //----------------------------------------------------------------------------- +SFXSoundscape::SFXSoundscape() + : mAmbience( NULL ) +{ +} + +//----------------------------------------------------------------------------- + SFXSoundscape::SFXSoundscape( SFXAmbience* ambience ) : mAmbience( ambience ) { diff --git a/Engine/source/sfx/sfxSoundscape.h b/Engine/source/sfx/sfxSoundscape.h index 603a84917..586a4a2b3 100644 --- a/Engine/source/sfx/sfxSoundscape.h +++ b/Engine/source/sfx/sfxSoundscape.h @@ -106,6 +106,9 @@ class SFXSoundscape bool _isUnique() const { return mFlags.test( FlagUnique ); } public: + + /// Defaault constructor for allocator + SFXSoundscape(); /// Create a soundscape associated with the given ambient space. SFXSoundscape( SFXAmbience* ambience );