Prechádzať zdrojové kódy

Add an alternate allocator for DecalManager; Also fix SFX weirdness.

James Urquhart 1 rok pred
rodič
commit
3781c7fae5

+ 7 - 0
Engine/source/T3D/decal/decalInstance.h

@@ -43,6 +43,13 @@ class DecalInstance
 {
 {
    public:
    public:
 
 
+      typedef DWordDataBlob<256> SizeClass1;
+      typedef DWordDataBlob<512> SizeClass2;
+      typedef DWordDataBlob<1024> SizeClass3;
+      typedef ThreeTieredChunker<SizeClass1, SizeClass2, SizeClass3> DecalDataChunker;
+
+      DecalDataChunker::Handle mAllocHandle;
+
       DecalData *mDataBlock;
       DecalData *mDataBlock;
 
 
       Point3F mPosition;
       Point3F mPosition;

+ 3 - 49
Engine/source/T3D/decal/decalManager.cpp

@@ -200,17 +200,6 @@ S32 QSORT_CALLBACK cmpDecalRenderOrder( const void *p1, const void *p2 )
 
 
 } // namespace {}
 } // 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
 // DecalManager
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------
@@ -228,10 +217,6 @@ DecalManager::DecalManager()
 
 
    mDirty = false;
    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);
    GFXDevice::getDeviceEventSignal().notify(this, &DecalManager::_handleGFXEvent);
 }
 }
 
 
@@ -240,9 +225,6 @@ DecalManager::~DecalManager()
    GFXDevice::getDeviceEventSignal().remove(this, &DecalManager::_handleGFXEvent);
    GFXDevice::getDeviceEventSignal().remove(this, &DecalManager::_handleGFXEvent);
 
 
    clearData();
    clearData();
-
-   for( U32 i = 0; i < NUM_SIZE_CLASSES; ++ i )
-      delete mChunkers[ i ];
 }
 }
 
 
 void DecalManager::consoleInit()
 void DecalManager::consoleInit()
@@ -913,14 +895,9 @@ void DecalManager::_generateWindingOrder( const Point3F &cornerPoint, Vector<Poi
 
 
 void DecalManager::_allocBuffers( DecalInstance *inst )
 void DecalManager::_allocBuffers( DecalInstance *inst )
 {
 {
-   const S32 sizeClass = _getSizeClass( inst );
-   
-   void* data;
-   if ( sizeClass == -1 )
-      data = dMalloc( sizeof( DecalVertex ) * inst->mVertCount + 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 );
    inst->mVerts = reinterpret_cast< DecalVertex* >( data );
    data = (U8*)data + sizeof( DecalVertex ) * inst->mVertCount;
    data = (U8*)data + sizeof( DecalVertex ) * inst->mVertCount;
    inst->mIndices = reinterpret_cast< U16* >( data );
    inst->mIndices = reinterpret_cast< U16* >( data );
@@ -930,15 +907,7 @@ void DecalManager::_freeBuffers( DecalInstance *inst )
 {
 {
    if ( inst->mVerts != NULL )
    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->mVerts = NULL;
       inst->mVertCount = 0;
       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 )
 void DecalManager::prepRenderImage( SceneRenderState* state )
 {
 {
    PROFILE_SCOPE( DecalManager_RenderDecals );
    PROFILE_SCOPE( DecalManager_RenderDecals );

+ 1 - 5
Engine/source/T3D/decal/decalManager.h

@@ -110,7 +110,7 @@ class DecalManager : public SceneObject
       Vector< GFXVertexBufferHandle<DecalVertex>* > mVBPool;
       Vector< GFXVertexBufferHandle<DecalVertex>* > mVBPool;
       Vector< GFXPrimitiveBufferHandle* > mPBPool;
       Vector< GFXPrimitiveBufferHandle* > mPBPool;
 
 
-      FreeListChunkerUntyped *mChunkers[3];
+      DecalInstance::DecalDataChunker mChunkers;
 
 
       #ifdef DECALMANAGER_DEBUG
       #ifdef DECALMANAGER_DEBUG
       Vector<PlaneF> mDebugPlanes;
       Vector<PlaneF> mDebugPlanes;
@@ -167,10 +167,6 @@ class DecalManager : public SceneObject
       void _freeBuffers( DecalInstance *inst );
       void _freeBuffers( DecalInstance *inst );
       void _freePools();
       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
       // Hide this from Doxygen
       /// @cond
       /// @cond
       bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event);
       bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event);

+ 7 - 0
Engine/source/T3D/sfx/sfx3DWorld.cpp

@@ -62,6 +62,13 @@ SFX3DWorld* gSFX3DWorld;
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+SFX3DObject::SFX3DObject()
+   : Parent(NULL, NULL)
+{
+}
+
+//-----------------------------------------------------------------------------
+
 SFX3DObject::SFX3DObject( SFX3DWorld* world, SceneObject* object )
 SFX3DObject::SFX3DObject( SFX3DWorld* world, SceneObject* object )
    : Parent( world, object )
    : Parent( world, object )
 {
 {

+ 2 - 0
Engine/source/T3D/sfx/sfx3DWorld.h

@@ -46,6 +46,8 @@ class SFX3DObject : public SceneObjectLink, public SFXObject< 3 >
    public:
    public:
    
    
       typedef SceneObjectLink Parent;
       typedef SceneObjectLink Parent;
+
+      SFX3DObject();
       
       
       ///
       ///
       SFX3DObject( SFX3DWorld* world, SceneObject* object );
       SFX3DObject( SFX3DWorld* world, SceneObject* object );

+ 4 - 0
Engine/source/T3D/sfx/sfxSpace.h

@@ -27,6 +27,10 @@
 #include "scene/sceneSpace.h"
 #include "scene/sceneSpace.h"
 #endif
 #endif
 
 
+#ifndef _SFXSOURCE_H_
+#include "sfx/sfxSource.h"
+#endif
+
 #ifndef _SCENEAMBIENTSOUNDOBJECT_H_
 #ifndef _SCENEAMBIENTSOUNDOBJECT_H_
 #include "scene/mixin/sceneAmbientSoundObject.h"
 #include "scene/mixin/sceneAmbientSoundObject.h"
 #endif
 #endif

+ 0 - 82
Engine/source/core/dataChunker.cpp

@@ -22,85 +22,3 @@
 
 
 #include "platform/platform.h"
 #include "platform/platform.h"
 #include "core/dataChunker.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;
-   }
-}

+ 105 - 4
Engine/source/core/dataChunker.h

@@ -14,10 +14,13 @@
 #ifndef _PLATFORMASSERT_H_
 #ifndef _PLATFORMASSERT_H_
 #  include "platform/platformAssert.h"
 #  include "platform/platformAssert.h"
 #endif
 #endif
+#ifndef _FRAMEALLOCATOR_H_
+#include "core/frameAllocator.h"
+#endif
 
 
 #include <algorithm>
 #include <algorithm>
 #include <stdint.h>
 #include <stdint.h>
-#include "core/frameAllocator.h"
+
 //#include "math/mMathFn.h" // tgemit - needed here for the moment
 //#include "math/mMathFn.h" // tgemit - needed here for the moment
 
 
 /// Implements a chunked data allocator.
 /// Implements a chunked data allocator.
@@ -242,7 +245,7 @@ public:
       mFreeListHead.push(reinterpret_cast<ChunkerFreeClassList<T>*>(item));
       mFreeListHead.push(reinterpret_cast<ChunkerFreeClassList<T>*>(item));
    }
    }
 
 
-   void freeBlocks(bool keepOne=false)
+   void freeBlocks(bool keepOne = false)
    {
    {
       BaseDataChunker<T>::freeBlocks(keepOne);
       BaseDataChunker<T>::freeBlocks(keepOne);
    }
    }
@@ -293,8 +296,106 @@ public:
       mFreeListHead.push(reinterpret_cast<ChunkerFreeClassList<T>*>(item));
       mFreeListHead.push(reinterpret_cast<ChunkerFreeClassList<T>*>(item));
    }
    }
 
 
-   void freeBlocks(bool keepOne)
+   void freeBlocks(bool keepOne = false)
    {
    {
-      BaseDataChunker<T>::freeBlocks(keepOne);
+      mChunker->freeBlocks(keepOne);
+   }
+};
+
+template<const U32 byteSize> struct DWordDataBlob
+{
+   U32 data[(byteSize + 3)/ 4];
+};
+
+/// Implements a three-tiered chunker
+/// K1..3 should be ordered from low to high
+template<class K1, class K2, class K3> 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<K1> mT1;
+   ClassChunker<K2> mT2;
+   ClassChunker<K3> 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);
    }
    }
 };
 };

+ 5 - 43
Engine/source/core/frameAllocator.h

@@ -330,22 +330,13 @@ public:
    }
    }
 
 
    U32 getObjectCount(void) const { return mNumObjectsInMemory; }
    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; };
    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 T* () { return mMemory; }
    operator const T* () const { return mMemory; }
    operator const T* () const { return mMemory; }
@@ -354,7 +345,7 @@ public:
    operator const T& () const { return *mMemory; }
    operator const T& () const { return *mMemory; }
 
 
    operator T() { return *mMemory; }
    operator T() { return *mMemory; }
-   operator const T() const { return *mMemory;
+   operator const T() const { return *mMemory; }
 
 
    inline T* address() const { return mMemory; }
    inline T* address() const { return mMemory; }
 
 
@@ -366,35 +357,6 @@ public:
    const T& operator[](const S32 idx) const { return mMemory[idx]; }
    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<type>::FrameTemp( const U32 count ) \
-{ \
-AssertFatal( count > 0, "Allocating a FrameTemp with less than one instance" ); \
-mWaterMark = FrameAllocator::getWaterMark(); \
-mMemory = reinterpret_cast<type *>( FrameAllocator::alloc( sizeof( type ) * count ) ); \
-} \
-template<>\
-inline FrameTemp<type>::~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_
 #endif  // _H_FRAMEALLOCATOR_

+ 2 - 2
Engine/source/core/util/swizzle.h

@@ -144,8 +144,8 @@ inline void Swizzle<T, mapLength>::InPlace( void *memory, const dsize_t size ) c
       // FrameTemp should work because the PNG loading code uses the FrameAllocator, so
       // 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
       // it should only get used on an image w/ that size as max -patw
       FrameTemp<U8> buffer( size );
       FrameTemp<U8> buffer( size );
-      dMemcpy( ~buffer, memory, size );
-      ToBuffer( memory, ~buffer, size );
+      dMemcpy( buffer.address(), memory, size);
+      ToBuffer( memory, buffer.address(), size);
    }
    }
 }
 }
 
 

+ 7 - 0
Engine/source/sfx/sfxSoundscape.cpp

@@ -39,6 +39,13 @@
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+SFXSoundscape::SFXSoundscape()
+   : mAmbience( NULL )
+{
+}
+
+//-----------------------------------------------------------------------------
+
 SFXSoundscape::SFXSoundscape( SFXAmbience* ambience )
 SFXSoundscape::SFXSoundscape( SFXAmbience* ambience )
    : mAmbience( ambience )
    : mAmbience( ambience )
 {
 {

+ 3 - 0
Engine/source/sfx/sfxSoundscape.h

@@ -106,6 +106,9 @@ class SFXSoundscape
       bool _isUnique() const { return mFlags.test( FlagUnique ); }
       bool _isUnique() const { return mFlags.test( FlagUnique ); }
 
 
    public:
    public:
+
+      /// Defaault constructor for allocator
+      SFXSoundscape();
    
    
       /// Create a soundscape associated with the given ambient space.
       /// Create a soundscape associated with the given ambient space.
       SFXSoundscape( SFXAmbience* ambience );
       SFXSoundscape( SFXAmbience* ambience );