Browse Source

Preparing for some major allocation changes

Marko Pintera 12 năm trước cách đây
mục cha
commit
1bd1a032b7

+ 1 - 1
CamelotCore/Include/CmMaterial.h

@@ -45,7 +45,7 @@ namespace CamelotFramework
 			StructData(void* _data, UINT32 _size)
 				:size(_size)
 			{
-				data = std::shared_ptr<void>(CM_NEW_BYTES(_size, ScratchAlloc), &MemAllocBytesDeleter<ScratchAlloc>::deleter);
+				data = std::shared_ptr<void>(CM_NEW_BYTES(_size, ScratchAlloc), &cm_free<ScratchAlloc>);
 				memcpy(data.get(), _data, size);
 			}
 

+ 1 - 1
CamelotCore/Include/CmTextureRTTI.h

@@ -119,7 +119,7 @@ namespace CamelotFramework
 
 			gMainSyncedRC().submitToGpu(true); // TODO - Possibly we can avoid this. I don't see a reason we need to wait for the update to complete.
 
-			CM_DELETE(pixelData, vector<PixelDataPtr BOOST_PP_COMMA() StdGenAlloc<PixelDataPtr>>, PoolAlloc);
+			CM_DELETE(pixelData, vector<PixelDataPtr BOOST_PP_COMMA() StdAlloc<PixelDataPtr>>, PoolAlloc);
 			texture->mRTTIData = nullptr;	
 		}
 

+ 2 - 2
CamelotD3D11RenderSystem/Source/CmD3D11InputLayoutManager.cpp

@@ -57,7 +57,7 @@ namespace CamelotFramework
 		{
 			auto firstElem = mInputLayoutMap.begin();
 
-			CM_DELETE(firstElem->first.bufferDeclElements, list<VertexElement BOOST_PP_COMMA() StdGenAlloc<VertexElement>>, PoolAlloc);
+			CM_DELETE(firstElem->first.bufferDeclElements, list<VertexElement BOOST_PP_COMMA() StdAlloc<VertexElement>>, PoolAlloc);
 			SAFE_RELEASE(firstElem->second->inputLayout);
 			CM_DELETE(firstElem->second, InputLayoutEntry, PoolAlloc);
 
@@ -168,7 +168,7 @@ namespace CamelotFramework
 		{
 			auto inputLayoutIter = mInputLayoutMap.find(iter->second);
 
-			CM_DELETE(inputLayoutIter->first.bufferDeclElements, list<VertexElement BOOST_PP_COMMA() StdGenAlloc<VertexElement>>, PoolAlloc);
+			CM_DELETE(inputLayoutIter->first.bufferDeclElements, list<VertexElement BOOST_PP_COMMA() StdAlloc<VertexElement>>, PoolAlloc);
 			SAFE_RELEASE(inputLayoutIter->second->inputLayout);
 			CM_DELETE(inputLayoutIter->second, InputLayoutEntry, PoolAlloc);
 

+ 70 - 23
CamelotUtility/Include/CmMemoryAllocator.h

@@ -3,6 +3,8 @@
 #undef min
 #undef max
 
+#include <boost/preprocessor.hpp>
+
 namespace CamelotFramework
 {
 	/**
@@ -40,7 +42,7 @@ namespace CamelotFramework
 	public:
 		static void deleter(T* ptr)
 		{
-			__cm_destruct<T, category>(ptr);
+			cm_delete<category, T>(ptr);
 		}
 	};
 
@@ -66,18 +68,64 @@ namespace CamelotFramework
 	}
 
 	template<class T, class category> 
-	inline void __cm_destruct(T* ptr)
+	inline void __cm_destruct_array(T* ptr, UINT32 count)
+	{
+		// This might seem a bit weird if T is a built-in type or a pointer, but
+		// standard allows us to call destructor on such types (they don't do anything)
+		for(unsigned int i = 0; i < count; i++)
+			ptr[i].~T();
+
+		MemoryAllocator<category>::freeArray(ptr, count);
+	}
+
+	template<class category> 
+	inline void* cm_alloc(UINT32 count)
+	{
+		return MemoryAllocator<category>::allocate(count);
+	}
+
+	template<class T, class category> 
+	inline T* cm_new(UINT32 count)
+	{
+		return new (cm_alloc<category>(count)) T();
+	}
+
+	template<class T, class category> 
+	inline T* cm_newN(UINT32 count)
+	{
+		T* ptr = (T*)MemoryAllocator<category>::allocateArray(sizeof(T), count);
+
+		for(unsigned int i = 0; i < count; i++)
+			new ((void*)&ptr[i]) T;
+
+		return ptr;
+	}
+
+#define MAKE_CM_NEW(z, n, unused)                                     \
+	template<class Type, class category BOOST_PP_ENUM_TRAILING_PARAMS(n, class T)>     \
+	Type* cm_new(BOOST_PP_ENUM_BINARY_PARAMS(n, T, t) ) { \
+		return new (cm_alloc<category>(sizeof(Type))) Type(BOOST_PP_ENUM_PARAMS (n, t));     \
+	}
+
+	BOOST_PP_REPEAT(9, MAKE_CM_NEW, ~)
+
+	template<class category> 
+	inline void cm_free(void* ptr)
+	{
+		MemoryAllocator<category>::free(ptr);
+	}
+
+	template<class category, class T> 
+	inline void cm_delete(T* ptr)
 	{
 		(ptr)->~T();
 
 		MemoryAllocator<category>::free(ptr);
 	}
 
-	template<class T, class category> 
-	inline void __cm_destruct_array(T* ptr, UINT32 count)
+	template<class category, class T> 
+	inline void cm_deleteN(T* ptr, UINT32 count)
 	{
-		// This might seem a bit weird if T is a built-in type or a pointer, but
-		// standard allows us to call destructor on such types (they don't do anything)
 		for(unsigned int i = 0; i < count; i++)
 			ptr[i].~T();
 
@@ -111,14 +159,13 @@ namespace CamelotFramework
 #define CM_NEW_ARRAY(T, count, category) CamelotFramework::__cm_construct_array<T, category>(count)
 #define CM_DELETE(ptr, T, category) {(ptr)->~T(); CamelotFramework::MemoryAllocator<category>::free(ptr);}
 #define CM_DELETE_BYTES(ptr, category) CamelotFramework::MemoryAllocator<category>::free(ptr)
-#define CM_DELETE_ARRAY(ptr, T, count, category) CamelotFramework::__cm_destruct_array<T, category>(ptr, count)
+#define CM_DELETE_ARRAY(ptr, T, count, category) CamelotFramework::cm_deleteN<category>(ptr, count)
 
 namespace CamelotFramework
 {
 	// Allocators we can use in the standard library
-	
-	template <class T>
-	class StdGenAlloc 
+    template <class T, class Category = GenAlloc>
+	class StdAlloc 
 	{
 		public:
 		// type definitions
@@ -134,7 +181,7 @@ namespace CamelotFramework
 		template <class U>
 		struct rebind 
 		{
-			typedef StdGenAlloc<U> other;
+			typedef StdAlloc<U, Category> other;
 		};
 
 		// return address of values
@@ -150,17 +197,17 @@ namespace CamelotFramework
 		/* constructors and destructor
 		* - nothing to do because the allocator has no state
 		*/
-		StdGenAlloc() throw() 
+		StdAlloc() throw() 
 		{ }
 
-		StdGenAlloc(const StdGenAlloc&) throw() 
+		StdAlloc(const StdAlloc&) throw() 
 		{ }
 
 		template <class U>
-		StdGenAlloc (const StdGenAlloc<U>&) throw() 
+		StdAlloc (const StdAlloc<U, Category>&) throw() 
 		{ }
 
-		~StdGenAlloc() throw() 
+		~StdAlloc() throw() 
 		{ }
 
 		// return maximum number of elements that can be allocated
@@ -172,7 +219,7 @@ namespace CamelotFramework
 		// allocate but don't initialize num elements of type T
 		pointer allocate (size_type num, const void* = 0) 
 		{
-			pointer ret = (pointer)(CM_NEW_BYTES((UINT32)num*sizeof(T), GenAlloc));
+			pointer ret = (pointer)(CM_NEW_BYTES((UINT32)num*sizeof(T), Category));
 			return ret;
 		}
 
@@ -194,19 +241,19 @@ namespace CamelotFramework
 		void deallocate (pointer p, size_type num) 
 		{
 			// print message and deallocate memory with global delete
-			CM_DELETE_BYTES((void*)p, GenAlloc);
+			CM_DELETE_BYTES((void*)p, Category);
 		}
 	};
 
    // return that all specializations of this allocator are interchangeable
-   template <class T1, class T2>
-   bool operator== (const StdGenAlloc<T1>&,
-                    const StdGenAlloc<T2>&) throw() {
+   template <class T1, class T2, class Category>
+   bool operator== (const StdAlloc<T1, Category>&,
+                    const StdAlloc<T2, Category>&) throw() {
        return true;
    }
-   template <class T1, class T2>
-   bool operator!= (const StdGenAlloc<T1>&,
-                    const StdGenAlloc<T2>&) throw() {
+   template <class T1, class T2, class Category>
+   bool operator!= (const StdAlloc<T1, Category>&,
+                    const StdAlloc<T2, Category>&) throw() {
        return false;
    }
 }

+ 8 - 8
CamelotUtility/Include/CmRTTIPrerequisites.h

@@ -89,11 +89,11 @@ namespace CamelotFramework
 	}; 
 
 	// RTTI types for some standard classes
-	template<class T> struct RTTIPlainType<std::vector<T, StdGenAlloc<T>>>
+	template<class T> struct RTTIPlainType<std::vector<T, StdAlloc<T>>>
 	{	
 		enum { id = TID_STDVECTOR }; enum { hasDynamicSize = 1 };
 
-		static void toMemory(const std::vector<T, StdGenAlloc<T>>& data, char* memory)
+		static void toMemory(const std::vector<T, StdAlloc<T>>& data, char* memory)
 		{ 
 			UINT32 size = (UINT32)data.size();
 
@@ -109,7 +109,7 @@ namespace CamelotFramework
 			}
 		}
 
-		static UINT32 fromMemory(std::vector<T, StdGenAlloc<T>>& data, char* memory)
+		static UINT32 fromMemory(std::vector<T, StdAlloc<T>>& data, char* memory)
 		{ 
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
@@ -127,7 +127,7 @@ namespace CamelotFramework
 			return size;
 		}
 
-		static UINT32 getDynamicSize(const std::vector<T, StdGenAlloc<T>>& data)	
+		static UINT32 getDynamicSize(const std::vector<T, StdAlloc<T>>& data)	
 		{ 
 			UINT64 dataSize = sizeof(UINT32);
 
@@ -140,11 +140,11 @@ namespace CamelotFramework
 		}	
 	}; 
 
-	template<class Key, class Value> struct RTTIPlainType<std::map<Key, Value, std::less<Key>, StdGenAlloc<std::pair<const Key, Value>>>>
+	template<class Key, class Value> struct RTTIPlainType<std::map<Key, Value, std::less<Key>, StdAlloc<std::pair<const Key, Value>>>>
 	{	
 		enum { id = TID_STDMAP }; enum { hasDynamicSize = 1 };
 
-		static void toMemory(const std::map<Key, Value, std::less<Key>, StdGenAlloc<std::pair<const Key, Value>>>& data, char* memory)
+		static void toMemory(const std::map<Key, Value, std::less<Key>, StdAlloc<std::pair<const Key, Value>>>& data, char* memory)
 		{ 
 			UINT32 size = (UINT32)data.size();
 
@@ -165,7 +165,7 @@ namespace CamelotFramework
 			}
 		}
 
-		static UINT32 fromMemory(std::map<Key, Value, std::less<Key>, StdGenAlloc<std::pair<const Key, Value>>>& data, char* memory)
+		static UINT32 fromMemory(std::map<Key, Value, std::less<Key>, StdAlloc<std::pair<const Key, Value>>>& data, char* memory)
 		{ 
 			UINT32 size;
 			memcpy(&size, memory, sizeof(UINT32)); 
@@ -187,7 +187,7 @@ namespace CamelotFramework
 			return size;
 		}
 
-		static UINT32 getDynamicSize(const std::map<Key, Value, std::less<Key>, StdGenAlloc<std::pair<const Key, Value>>>& data)	
+		static UINT32 getDynamicSize(const std::map<Key, Value, std::less<Key>, StdAlloc<std::pair<const Key, Value>>>& data)	
 		{ 
 			UINT64 dataSize = sizeof(UINT32);
 

+ 18 - 10
CamelotUtility/Include/CmStdHeaders.h

@@ -146,66 +146,74 @@ namespace CamelotFramework
 #endif
 
 	// Standard containers, for easier access in my own namespace
-	template <typename T, typename A = StdGenAlloc<T>> 
+	template <typename T, typename A = StdAlloc<T>> 
 	struct deque 
 	{ 
 		typedef typename std::deque<T, A> type;    
 	}; 
 
-	template <typename T, typename A = StdGenAlloc<T>> 
+	template <typename T, typename A = StdAlloc<T>> 
 	struct vector 
 	{ 
 		typedef typename std::vector<T, A> type;    
 	}; 
 
-	template <typename T, typename A = StdGenAlloc<T>> 
+	template <typename T, typename A = StdAlloc<T>> 
 	struct list 
 	{ 
 		typedef typename std::list<T, A> type;    
 	}; 
 
-	template <typename T, typename A = StdGenAlloc<T>> 
+	template <typename T, typename A = StdAlloc<T>> 
 	struct stack 
 	{ 
 		typedef typename std::stack<T, std::deque<T, A>> type;    
 	}; 
 
-	template <typename T, typename P = std::less<T>, typename A = StdGenAlloc<T>> 
+	template <typename T, typename P = std::less<T>, typename A = StdAlloc<T>> 
 	struct set 
 	{ 
 		typedef typename std::set<T, P, A> type;    
 	}; 
 
-	template <typename K, typename V, typename P = std::less<K>, typename A = StdGenAlloc<std::pair<const K, V>>> 
+	template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>>> 
 	struct map 
 	{ 
 		typedef typename std::map<K, V, P, A> type; 
 	}; 
 
-	template <typename K, typename V, typename P = std::less<K>, typename A = StdGenAlloc<std::pair<const K, V>>> 
+	template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>>> 
 	struct multimap 
 	{ 
 		typedef typename std::multimap<K, V, P, A> type; 
 	}; 
 
-	template <typename T, typename H = std::hash<T>, typename C = std::equal_to<T>, typename A = StdGenAlloc<T>> 
+	template <typename T, typename H = std::hash<T>, typename C = std::equal_to<T>, typename A = StdAlloc<T>> 
 	struct unordered_set 
 	{ 
 		typedef typename std::unordered_set<T, H, C, A> type;    
 	}; 
 
-	template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdGenAlloc<std::pair<const K, V>>> 
+	template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>>> 
 	struct unordered_map 
 	{ 
 		typedef typename std::unordered_map<K, V, H, C, A> type; 
 	}; 
 
-	template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdGenAlloc<std::pair<const K, V>>> 
+	template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>>> 
 	struct unordered_multimap 
 	{ 
 		typedef typename std::unordered_multimap<K, V, H, C, A> type; 
 	}; 
 
+//#define MAKE_CM_MAKE_SHARED(z, n, unused)                                     \
+//	template<class Type, class category BOOST_PP_ENUM_TRAILING_PARAMS(n, class T)>     \
+//	Type* cm_make_shared(BOOST_PP_ENUM_BINARY_PARAMS(n, T, t) ) { \
+//	return std::allocate_shared<Type>(StdAlloc<category> BOOST_PP_ENUM_TRAILING_PARAMS (n, t));     \
+//	}
+//
+//	BOOST_PP_REPEAT(9, MAKE_CM_MAKE_SHARED, ~)
+
 	// TODO - Once VC2012 grows up and adds proper C++11 support, uncomment this
 	//template <typename T, typename A = char> 
 	//using deque = std::deque<T, A>;    

+ 1 - 1
CamelotUtility/Include/CmThreadDefines.h

@@ -66,7 +66,7 @@ THE SOFTWARE
 // Thread objects and related functions
 #define CM_THREAD_TYPE boost::thread
 #define CM_THREAD_CREATE(name, worker) boost::thread* name = new (CamelotFramework::MemoryAllocator<CamelotFramework::GenAlloc>::allocate(sizeof(boost::thread))) boost::thread(worker);
-#define CM_THREAD_DESTROY(name) CamelotFramework::__cm_destruct<boost::thread, CamelotFramework::GenAlloc>(name);
+#define CM_THREAD_DESTROY(name) CamelotFramework::cm_delete<CamelotFramework::GenAlloc, boost::thread>(name);
 #define CM_THREAD_HARDWARE_CONCURRENCY boost::thread::hardware_concurrency()
 #define CM_THREAD_CURRENT_ID boost::this_thread::get_id()
 #define CM_THREAD_ID_TYPE boost::thread::id

+ 3 - 0
CamelotUtility/Source/CmTexAtlasGenerator.cpp

@@ -18,6 +18,9 @@ namespace CamelotFramework
 		{
 			if(children != nullptr)
 				CM_DELETE_ARRAY(children, TexAtlasNode, 2, ScratchAlloc);
+
+			int myVal = *cm_new<int, GenAlloc>();
+			float myVal2 = *cm_new<float, GenAlloc>();
 		}
 
 		UINT32 x, y, width, height;