Răsfoiți Sursa

Refactor: Cleaned up custom allocators
- Static allocator can now use an arbitrary secondary allocator for when static allocation fails

BearishSun 8 ani în urmă
părinte
comite
24a1f44cd8
40 a modificat fișierele cu 774 adăugiri și 709 ștergeri
  1. 2 3
      Source/BansheeCore/CoreThread/BsCoreObjectManager.cpp
  2. 0 1
      Source/BansheeCore/CoreThread/BsCoreThread.cpp
  3. 0 1
      Source/BansheeCore/Material/BsMaterial.cpp
  4. 1 1
      Source/BansheeCore/Material/BsMaterialParams.h
  5. 0 1
      Source/BansheeCore/Material/BsPass.cpp
  6. 0 1
      Source/BansheeCore/Material/BsShader.cpp
  7. 0 1
      Source/BansheeCore/Material/BsTechnique.cpp
  8. 0 1
      Source/BansheeCore/Mesh/BsMeshBase.cpp
  9. 0 1
      Source/BansheeCore/Mesh/BsTransientMesh.cpp
  10. 5 5
      Source/BansheeCore/Profiling/BsProfilerCPU.cpp
  11. 0 1
      Source/BansheeCore/Profiling/BsProfilerCPU.h
  12. 0 1
      Source/BansheeCore/RenderAPI/BsGpuParamBlockBuffer.cpp
  13. 0 1
      Source/BansheeCore/RenderAPI/BsGpuParams.cpp
  14. 0 1
      Source/BansheeCore/RenderAPI/BsRenderTarget.cpp
  15. 0 1
      Source/BansheeCore/RenderAPI/BsRenderTexture.cpp
  16. 0 1
      Source/BansheeCore/RenderAPI/BsRenderWindow.cpp
  17. 0 1
      Source/BansheeCore/RenderAPI/BsViewport.cpp
  18. 0 1
      Source/BansheeCore/Renderer/BsCamera.cpp
  19. 0 1
      Source/BansheeCore/Renderer/BsLight.cpp
  20. 2 1
      Source/BansheeCore/Renderer/BsLightProbeVolume.cpp
  21. 0 1
      Source/BansheeCore/Renderer/BsReflectionProbe.cpp
  22. 0 1
      Source/BansheeCore/Renderer/BsRenderable.cpp
  23. 0 1
      Source/BansheeCore/Renderer/BsSkybox.cpp
  24. 13 14
      Source/BansheeEditor/Testing/BsEditorTestSuite.cpp
  25. 1 1
      Source/BansheeEngine/2D/BsTextSprite.h
  26. 66 13
      Source/BansheeUtility/Allocators/BsFrameAlloc.cpp
  27. 250 6
      Source/BansheeUtility/Allocators/BsFrameAlloc.h
  28. 43 0
      Source/BansheeUtility/Allocators/BsFreeAlloc.h
  29. 0 52
      Source/BansheeUtility/Allocators/BsGlobalFrameAlloc.cpp
  30. 0 240
      Source/BansheeUtility/Allocators/BsGlobalFrameAlloc.h
  31. 6 4
      Source/BansheeUtility/Allocators/BsMemoryAllocator.h
  32. 1 1
      Source/BansheeUtility/Allocators/BsStackAlloc.cpp
  33. 0 0
      Source/BansheeUtility/Allocators/BsStackAlloc.h
  34. 138 100
      Source/BansheeUtility/Allocators/BsStaticAlloc.h
  35. 3 4
      Source/BansheeUtility/CMakeSources.cmake
  36. 2 3
      Source/BansheeUtility/Math/BsDegree.h
  37. 15 15
      Source/BansheeUtility/Math/BsMath.h
  38. 3 4
      Source/BansheeUtility/Math/BsRadian.h
  39. 210 210
      Source/BansheeUtility/Math/BsVector4.h
  40. 13 13
      Source/MBansheeEngine/Math/AABox.cs

+ 2 - 3
Source/BansheeCore/CoreThread/BsCoreObjectManager.cpp

@@ -5,7 +5,6 @@
 #include "CoreThread/BsCoreObjectCore.h"
 #include "CoreThread/BsCoreObjectCore.h"
 #include "Error/BsException.h"
 #include "Error/BsException.h"
 #include "Math/BsMath.h"
 #include "Math/BsMath.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "CoreThread/BsCoreThread.h"
 #include "CoreThread/BsCoreThread.h"
 
 
 namespace bs
 namespace bs
@@ -282,7 +281,7 @@ namespace bs
 				UINT8* dataPtr = entry.syncData.getBuffer();
 				UINT8* dataPtr = entry.syncData.getBuffer();
 
 
 				if (dataPtr != nullptr)
 				if (dataPtr != nullptr)
-					entry.allocator->dealloc(dataPtr);
+					entry.allocator->free(dataPtr);
 			}
 			}
 		};
 		};
 
 
@@ -400,7 +399,7 @@ namespace bs
 			UINT8* data = objSyncData.syncData.getBuffer();
 			UINT8* data = objSyncData.syncData.getBuffer();
 
 
 			if (data != nullptr)
 			if (data != nullptr)
-				syncData.alloc->dealloc(data);
+				syncData.alloc->free(data);
 		}
 		}
 
 
 		syncData.entries.clear();
 		syncData.entries.clear();

+ 0 - 1
Source/BansheeCore/CoreThread/BsCoreThread.cpp

@@ -3,7 +3,6 @@
 #include "CoreThread/BsCoreThread.h"
 #include "CoreThread/BsCoreThread.h"
 #include "Threading/BsThreadPool.h"
 #include "Threading/BsThreadPool.h"
 #include "Threading/BsTaskScheduler.h"
 #include "Threading/BsTaskScheduler.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "BsCoreApplication.h"
 #include "BsCoreApplication.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;

+ 0 - 1
Source/BansheeCore/Material/BsMaterial.cpp

@@ -8,7 +8,6 @@
 #include "RTTI/BsMaterialRTTI.h"
 #include "RTTI/BsMaterialRTTI.h"
 #include "Material/BsMaterialManager.h"
 #include "Material/BsMaterialManager.h"
 #include "Resources/BsResources.h"
 #include "Resources/BsResources.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Math/BsMatrixNxM.h"
 #include "Math/BsMatrixNxM.h"
 #include "Math/BsVector3I.h"
 #include "Math/BsVector3I.h"
 #include "Math/BsVector4I.h"
 #include "Math/BsVector4I.h"

+ 1 - 1
Source/BansheeCore/Material/BsMaterialParams.h

@@ -233,7 +233,7 @@ namespace bs
 		UINT32 mNumSamplerParams = 0;
 		UINT32 mNumSamplerParams = 0;
 
 
 		mutable UINT64 mParamVersion = 1;
 		mutable UINT64 mParamVersion = 1;
-		mutable StaticAlloc<STATIC_BUFFER_SIZE, STATIC_BUFFER_SIZE> mAlloc;
+		mutable StaticAlloc<STATIC_BUFFER_SIZE> mAlloc;
 	};
 	};
 
 
 	/** Raw data for a single structure parameter. */
 	/** Raw data for a single structure parameter. */

+ 0 - 1
Source/BansheeCore/Material/BsPass.cpp

@@ -7,7 +7,6 @@
 #include "RTTI/BsPassRTTI.h"
 #include "RTTI/BsPassRTTI.h"
 #include "Material/BsMaterial.h"
 #include "Material/BsMaterial.h"
 #include "RenderAPI/BsGpuParams.h"
 #include "RenderAPI/BsGpuParams.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "RenderAPI/BsGpuProgram.h"
 #include "RenderAPI/BsGpuProgram.h"
 #include "RenderAPI/BsGpuPipelineState.h"
 #include "RenderAPI/BsGpuPipelineState.h"
 
 

+ 0 - 1
Source/BansheeCore/Material/BsShader.cpp

@@ -7,7 +7,6 @@
 #include "RTTI/BsShaderRTTI.h"
 #include "RTTI/BsShaderRTTI.h"
 #include "Resources/BsResources.h"
 #include "Resources/BsResources.h"
 #include "RenderAPI/BsGpuParams.h"
 #include "RenderAPI/BsGpuParams.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Material/BsPass.h"
 #include "Material/BsPass.h"
 #include "RenderAPI/BsSamplerState.h"
 #include "RenderAPI/BsSamplerState.h"
 #include "Image/BsTexture.h"
 #include "Image/BsTexture.h"

+ 0 - 1
Source/BansheeCore/Material/BsTechnique.cpp

@@ -6,7 +6,6 @@
 #include "Renderer/BsRendererManager.h"
 #include "Renderer/BsRendererManager.h"
 #include "Material/BsPass.h"
 #include "Material/BsPass.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "RTTI/BsTechniqueRTTI.h"
 #include "RTTI/BsTechniqueRTTI.h"
 
 
 namespace bs
 namespace bs

+ 0 - 1
Source/BansheeCore/Mesh/BsMeshBase.cpp

@@ -3,7 +3,6 @@
 #include "Mesh/BsMeshBase.h"
 #include "Mesh/BsMeshBase.h"
 #include "RTTI/BsMeshBaseRTTI.h"
 #include "RTTI/BsMeshBaseRTTI.h"
 #include "CoreThread/BsCoreThread.h"
 #include "CoreThread/BsCoreThread.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 0 - 1
Source/BansheeCore/Mesh/BsTransientMesh.cpp

@@ -4,7 +4,6 @@
 #include "RenderAPI/BsVertexData.h"
 #include "RenderAPI/BsVertexData.h"
 #include "Math/BsBounds.h"
 #include "Math/BsBounds.h"
 #include "Mesh/BsMeshHeap.h"
 #include "Mesh/BsMeshHeap.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 5 - 5
Source/BansheeCore/Profiling/BsProfilerCPU.cpp

@@ -179,7 +179,7 @@ namespace bs
 
 
 		activeBlock = ActiveBlock(ActiveSamplingType::Basic, rootBlock);
 		activeBlock = ActiveBlock(ActiveSamplingType::Basic, rootBlock);
 		if (activeBlocks == nullptr)
 		if (activeBlocks == nullptr)
-			activeBlocks = frameAlloc.alloc<Stack<ActiveBlock, StdFrameAlloc<ActiveBlock>>>
+			activeBlocks = frameAlloc.construct<Stack<ActiveBlock, StdFrameAlloc<ActiveBlock>>>
 					(StdFrameAlloc<ActiveBlock>(&frameAlloc));
 					(StdFrameAlloc<ActiveBlock>(&frameAlloc));
 
 
 		activeBlocks->push(activeBlock);
 		activeBlocks->push(activeBlock);
@@ -219,7 +219,7 @@ namespace bs
 		isActive = false;
 		isActive = false;
 		activeBlock = ActiveBlock();
 		activeBlock = ActiveBlock();
 
 
-		frameAlloc.dealloc(activeBlocks);
+		frameAlloc.free(activeBlocks);
 		activeBlocks = nullptr;
 		activeBlocks = nullptr;
 	}
 	}
 
 
@@ -237,7 +237,7 @@ namespace bs
 
 
 	ProfilerCPU::ProfiledBlock* ProfilerCPU::ThreadInfo::getBlock(const char* name)
 	ProfilerCPU::ProfiledBlock* ProfilerCPU::ThreadInfo::getBlock(const char* name)
 	{
 	{
-		ProfiledBlock* block = frameAlloc.alloc<ProfiledBlock>(&frameAlloc);
+		ProfiledBlock* block = frameAlloc.construct<ProfiledBlock>(&frameAlloc);
 		block->name = (char*)frameAlloc.alloc(((UINT32)strlen(name) + 1) * sizeof(char));
 		block->name = (char*)frameAlloc.alloc(((UINT32)strlen(name) + 1) * sizeof(char));
 		strcpy(block->name, name);
 		strcpy(block->name, name);
 
 
@@ -246,8 +246,8 @@ namespace bs
 
 
 	void ProfilerCPU::ThreadInfo::releaseBlock(ProfiledBlock* block)
 	void ProfilerCPU::ThreadInfo::releaseBlock(ProfiledBlock* block)
 	{
 	{
-		frameAlloc.dealloc((UINT8*)block->name);
-		frameAlloc.dealloc(block);
+		frameAlloc.free((UINT8*)block->name);
+		frameAlloc.free(block);
 	}
 	}
 
 
 	ProfilerCPU::ProfiledBlock::ProfiledBlock(FrameAlloc* alloc)
 	ProfilerCPU::ProfiledBlock::ProfiledBlock(FrameAlloc* alloc)

+ 0 - 1
Source/BansheeCore/Profiling/BsProfilerCPU.h

@@ -4,7 +4,6 @@
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "Utility/BsModule.h"
 #include "Utility/BsModule.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 0 - 1
Source/BansheeCore/RenderAPI/BsGpuParamBlockBuffer.cpp

@@ -2,7 +2,6 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "RenderAPI/BsGpuParamBlockBuffer.h"
 #include "RenderAPI/BsGpuParamBlockBuffer.h"
 #include "Managers/BsHardwareBufferManager.h"
 #include "Managers/BsHardwareBufferManager.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 0 - 1
Source/BansheeCore/RenderAPI/BsGpuParams.cpp

@@ -9,7 +9,6 @@
 #include "Image/BsTexture.h"
 #include "Image/BsTexture.h"
 #include "RenderAPI/BsGpuBuffer.h"
 #include "RenderAPI/BsGpuBuffer.h"
 #include "RenderAPI/BsSamplerState.h"
 #include "RenderAPI/BsSamplerState.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Debug/BsDebug.h"
 #include "Debug/BsDebug.h"
 #include "Error/BsException.h"
 #include "Error/BsException.h"
 #include "Math/BsVector3I.h"
 #include "Math/BsVector3I.h"

+ 0 - 1
Source/BansheeCore/RenderAPI/BsRenderTarget.cpp

@@ -5,7 +5,6 @@
 #include "Error/BsException.h"
 #include "Error/BsException.h"
 #include "RenderAPI/BsRenderAPI.h"
 #include "RenderAPI/BsRenderAPI.h"
 #include "CoreThread/BsCoreThread.h"
 #include "CoreThread/BsCoreThread.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 0 - 1
Source/BansheeCore/RenderAPI/BsRenderTexture.cpp

@@ -6,7 +6,6 @@
 #include "Managers/BsTextureManager.h"
 #include "Managers/BsTextureManager.h"
 #include "Resources/BsResources.h"
 #include "Resources/BsResources.h"
 #include "CoreThread/BsCoreThread.h"
 #include "CoreThread/BsCoreThread.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 0 - 1
Source/BansheeCore/RenderAPI/BsRenderWindow.cpp

@@ -5,7 +5,6 @@
 #include "Managers/BsRenderWindowManager.h"
 #include "Managers/BsRenderWindowManager.h"
 #include "RenderAPI/BsViewport.h"
 #include "RenderAPI/BsViewport.h"
 #include "Platform/BsPlatform.h"
 #include "Platform/BsPlatform.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs 
 namespace bs 
 {
 {

+ 0 - 1
Source/BansheeCore/RenderAPI/BsViewport.cpp

@@ -6,7 +6,6 @@
 #include "RenderAPI/BsRenderTarget.h"
 #include "RenderAPI/BsRenderTarget.h"
 #include "Math/BsMath.h"
 #include "Math/BsMath.h"
 #include "RenderAPI/BsRenderAPI.h"
 #include "RenderAPI/BsRenderAPI.h"
-#include "Allocators/BsFrameAlloc.h"
 
 
 namespace bs 
 namespace bs 
 {
 {

+ 0 - 1
Source/BansheeCore/Renderer/BsCamera.cpp

@@ -12,7 +12,6 @@
 #include "Scene/BsSceneObject.h"
 #include "Scene/BsSceneObject.h"
 #include "Renderer/BsRendererManager.h"
 #include "Renderer/BsRendererManager.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Scene/BsSceneManager.h"
 #include "Scene/BsSceneManager.h"
 
 
 namespace bs
 namespace bs

+ 0 - 1
Source/BansheeCore/Renderer/BsLight.cpp

@@ -3,7 +3,6 @@
 #include "Renderer/BsLight.h"
 #include "Renderer/BsLight.h"
 #include "RTTI/BsLightRTTI.h"
 #include "RTTI/BsLightRTTI.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Scene/BsSceneObject.h"
 #include "Scene/BsSceneObject.h"
 #include "Mesh/BsMesh.h"
 #include "Mesh/BsMesh.h"
 
 

+ 2 - 1
Source/BansheeCore/Renderer/BsLightProbeVolume.cpp

@@ -2,7 +2,6 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "Renderer/BsLightProbeVolume.h"
 #include "Renderer/BsLightProbeVolume.h"
 #include "RTTI/BsLightProbeVolumeRTTI.h"
 #include "RTTI/BsLightProbeVolumeRTTI.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsLight.h"
 #include "Renderer/BsLight.h"
 #include "Image/BsTexture.h"
 #include "Image/BsTexture.h"
@@ -665,6 +664,8 @@ namespace bs
 		desc.format = PF_RGBA32F;
 		desc.format = PF_RGBA32F;
 
 
 		SPtr<Texture> newTexture = Texture::create(desc);
 		SPtr<Texture> newTexture = Texture::create(desc);
+		newTexture->clear(Color::ZERO);
+
 		if (mCoefficients)
 		if (mCoefficients)
 			mCoefficients->copy(newTexture);
 			mCoefficients->copy(newTexture);
 
 

+ 0 - 1
Source/BansheeCore/Renderer/BsReflectionProbe.cpp

@@ -3,7 +3,6 @@
 #include "Renderer/BsReflectionProbe.h"
 #include "Renderer/BsReflectionProbe.h"
 #include "RTTI/BsReflectionProbeRTTI.h"
 #include "RTTI/BsReflectionProbeRTTI.h"
 #include "Scene/BsSceneObject.h"
 #include "Scene/BsSceneObject.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Image/BsTexture.h"
 #include "Image/BsTexture.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
 #include "Utility/BsUUID.h"
 #include "Utility/BsUUID.h"

+ 0 - 1
Source/BansheeCore/Renderer/BsRenderable.cpp

@@ -8,7 +8,6 @@
 #include "Math/BsBounds.h"
 #include "Math/BsBounds.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
 #include "Animation/BsAnimation.h"
 #include "Animation/BsAnimation.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Animation/BsMorphShapes.h"
 #include "Animation/BsMorphShapes.h"
 #include "RenderAPI/BsGpuBuffer.h"
 #include "RenderAPI/BsGpuBuffer.h"
 #include "Animation/BsAnimationManager.h"
 #include "Animation/BsAnimationManager.h"

+ 0 - 1
Source/BansheeCore/Renderer/BsSkybox.cpp

@@ -3,7 +3,6 @@
 #include "Renderer/BsSkybox.h"
 #include "Renderer/BsSkybox.h"
 #include "RTTI/BsSkyboxRTTI.h"
 #include "RTTI/BsSkyboxRTTI.h"
 #include "Scene/BsSceneObject.h"
 #include "Scene/BsSceneObject.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "Image/BsTexture.h"
 #include "Image/BsTexture.h"
 #include "Renderer/BsRenderer.h"
 #include "Renderer/BsRenderer.h"
 #include "Utility/BsUUID.h"
 #include "Utility/BsUUID.h"

+ 13 - 14
Source/BansheeEditor/Testing/BsEditorTestSuite.cpp

@@ -13,7 +13,6 @@
 #include "Scene/BsPrefab.h"
 #include "Scene/BsPrefab.h"
 #include "Resources/BsResources.h"
 #include "Resources/BsResources.h"
 #include "Scene/BsPrefabDiff.h"
 #include "Scene/BsPrefabDiff.h"
-#include "Allocators/BsFrameAlloc.h"
 #include "FileSystem/BsFileSystem.h"
 #include "FileSystem/BsFileSystem.h"
 #include "Scene/BsSceneManager.h"
 #include "Scene/BsSceneManager.h"
 
 
@@ -772,10 +771,10 @@ namespace bs
 		UINT8* a3 = alloc.alloc(130);
 		UINT8* a3 = alloc.alloc(130);
 		UINT8* a4 = alloc.alloc(5);
 		UINT8* a4 = alloc.alloc(5);
 
 
-		alloc.dealloc(a1);
-		alloc.dealloc(a2);
-		alloc.dealloc(a3);
-		alloc.dealloc(a4);
+		alloc.free(a1);
+		alloc.free(a2);
+		alloc.free(a3);
+		alloc.free(a4);
 
 
 		alloc.clear();
 		alloc.clear();
 
 
@@ -785,10 +784,10 @@ namespace bs
 		UINT8* a7 = alloc.alloc(130);
 		UINT8* a7 = alloc.alloc(130);
 		UINT8* a8 = alloc.alloc(5);
 		UINT8* a8 = alloc.alloc(5);
 
 
-		alloc.dealloc(a5);
-		alloc.dealloc(a6);
-		alloc.dealloc(a7);
-		alloc.dealloc(a8);
+		alloc.free(a5);
+		alloc.free(a6);
+		alloc.free(a7);
+		alloc.free(a8);
 
 
 		alloc.markFrame();
 		alloc.markFrame();
 		UINT8* a9 = alloc.alloc(5);
 		UINT8* a9 = alloc.alloc(5);
@@ -796,16 +795,16 @@ namespace bs
 		UINT8* a11 = alloc.alloc(130);
 		UINT8* a11 = alloc.alloc(130);
 		UINT8* a12 = alloc.alloc(5);
 		UINT8* a12 = alloc.alloc(5);
 
 
-		alloc.dealloc(a9);
-		alloc.dealloc(a10);
-		alloc.dealloc(a11);
-		alloc.dealloc(a12);
+		alloc.free(a9);
+		alloc.free(a10);
+		alloc.free(a11);
+		alloc.free(a12);
 
 
 		alloc.clear();
 		alloc.clear();
 		alloc.clear();
 		alloc.clear();
 
 
 		UINT8* a13 = alloc.alloc(5);
 		UINT8* a13 = alloc.alloc(5);
-		alloc.dealloc(a13);
+		alloc.free(a13);
 		alloc.clear();
 		alloc.clear();
 	}
 	}
 }
 }

+ 1 - 1
Source/BansheeEngine/2D/BsTextSprite.h

@@ -133,7 +133,7 @@ namespace bs
 		/**	Clears internal geometry buffers. */
 		/**	Clears internal geometry buffers. */
 		void clearMesh();
 		void clearMesh();
 
 
-		mutable StaticAlloc<STATIC_BUFFER_SIZE, STATIC_BUFFER_SIZE> mAlloc;
+		mutable StaticAlloc<STATIC_BUFFER_SIZE> mAlloc;
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 66 - 13
Source/BansheeUtility/Allocators/BsFrameAlloc.cpp

@@ -1,5 +1,6 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Prerequisites/BsPrerequisitesUtil.h"
 #include "Allocators/BsFrameAlloc.h"
 #include "Allocators/BsFrameAlloc.h"
 #include "Error/BsException.h"
 #include "Error/BsException.h"
 
 
@@ -30,13 +31,11 @@ namespace bs
 		:mBlockSize(blockSize), mFreeBlock(nullptr), mNextBlockIdx(0), mTotalAllocBytes(0),
 		:mBlockSize(blockSize), mFreeBlock(nullptr), mNextBlockIdx(0), mTotalAllocBytes(0),
 		mLastFrame(nullptr), mOwnerThread(BS_THREAD_CURRENT_ID)
 		mLastFrame(nullptr), mOwnerThread(BS_THREAD_CURRENT_ID)
 	{
 	{
-		allocBlock(mBlockSize);
 	}
 	}
 #else
 #else
 	FrameAlloc::FrameAlloc(UINT32 blockSize)
 	FrameAlloc::FrameAlloc(UINT32 blockSize)
 		: mBlockSize(blockSize), mFreeBlock(nullptr), mNextBlockIdx(0), mTotalAllocBytes(0), mLastFrame(nullptr)
 		: mBlockSize(blockSize), mFreeBlock(nullptr), mNextBlockIdx(0), mTotalAllocBytes(0), mLastFrame(nullptr)
 	{
 	{
-		allocBlock(mBlockSize);
 	}
 	}
 #endif
 #endif
 
 
@@ -53,8 +52,10 @@ namespace bs
 
 
 		amount += sizeof(UINT32);
 		amount += sizeof(UINT32);
 #endif
 #endif
+		UINT32 freeMem = 0;
+		if(mFreeBlock != nullptr)
+			freeMem = mFreeBlock->mSize - mFreeBlock->mFreePtr;
 
 
-		UINT32 freeMem = mFreeBlock->mSize - mFreeBlock->mFreePtr;
 		if(amount > freeMem)
 		if(amount > freeMem)
 			allocBlock(amount);
 			allocBlock(amount);
 
 
@@ -78,21 +79,29 @@ namespace bs
 		assert(mOwnerThread == BS_THREAD_CURRENT_ID && "Frame allocator called from invalid thread.");
 		assert(mOwnerThread == BS_THREAD_CURRENT_ID && "Frame allocator called from invalid thread.");
 
 
 		amount += sizeof(UINT32);
 		amount += sizeof(UINT32);
-		UINT32 freePtr = mFreeBlock->mFreePtr + sizeof(UINT32);
-#else
-		UINT32 freePtr = mFreeBlock->mFreePtr;
 #endif
 #endif
 
 
-		UINT32 alignOffset = alignment - (freePtr & (alignment - 1));
+		UINT32 freeMem = 0;
+		UINT32 freePtr = 0;
+		if(mFreeBlock != nullptr)
+		{
+			freeMem = mFreeBlock->mSize - mFreeBlock->mFreePtr;
 
 
-		UINT32 freeMem = mFreeBlock->mSize - mFreeBlock->mFreePtr;
+#if BS_DEBUG_MODE
+			freePtr = mFreeBlock->mFreePtr + sizeof(UINT32);
+#else
+			freePtr = mFreeBlock->mFreePtr;
+#endif
+		}
+
+		UINT32 alignOffset = (alignment - (freePtr & (alignment - 1))) & (alignment - 1);
 		if ((amount + alignOffset) > freeMem)
 		if ((amount + alignOffset) > freeMem)
 		{
 		{
-			// New blocks are allocated on a 16 byte boundary, ensure we enough space is allocated taking into account
+			// New blocks are allocated on a 16 byte boundary, ensure enough space is allocated taking into account
 			// the requested alignment
 			// the requested alignment
 
 
 #if BS_DEBUG_MODE
 #if BS_DEBUG_MODE
-			alignOffset = alignment - (sizeof(UINT32) & (alignment - 1));
+			alignOffset = (alignment - (sizeof(UINT32) & (alignment - 1))) & (alignment - 1);
 #else
 #else
 			if (alignment > 16)
 			if (alignment > 16)
 				alignOffset = alignment - 16;
 				alignOffset = alignment - 16;
@@ -118,7 +127,7 @@ namespace bs
 #endif
 #endif
 	}
 	}
 
 
-	void FrameAlloc::dealloc(UINT8* data)
+	void FrameAlloc::free(UINT8* data)
 	{
 	{
 		// Dealloc is only used for debug and can be removed if needed. All the actual deallocation
 		// Dealloc is only used for debug and can be removed if needed. All the actual deallocation
 		// happens in clear()
 		// happens in clear()
@@ -147,7 +156,7 @@ namespace bs
 		{
 		{
 			assert(mBlocks.size() > 0 && mNextBlockIdx > 0);
 			assert(mBlocks.size() > 0 && mNextBlockIdx > 0);
 
 
-			dealloc((UINT8*)mLastFrame);
+			free((UINT8*)mLastFrame);
 
 
 			UINT8* framePtr = (UINT8*)mLastFrame;
 			UINT8* framePtr = (UINT8*)mLastFrame;
 			mLastFrame = *(void**)mLastFrame;
 			mLastFrame = *(void**)mLastFrame;
@@ -234,7 +243,7 @@ namespace bs
 
 
 				allocBlock(totalBytes);
 				allocBlock(totalBytes);
 			}
 			}
-			else
+			else if(mBlocks.size() > 0)
 				mBlocks[0]->mFreePtr = 0;
 				mBlocks[0]->mFreePtr = 0;
 		}
 		}
 	}
 	}
@@ -293,4 +302,48 @@ namespace bs
 		mOwnerThread = thread;
 		mOwnerThread = thread;
 #endif
 #endif
 	}
 	}
+
+	BS_THREADLOCAL FrameAlloc* _GlobalFrameAlloc = nullptr;
+
+	BS_UTILITY_EXPORT FrameAlloc& gFrameAlloc()
+	{
+		if (_GlobalFrameAlloc == nullptr)
+		{
+			// Note: This will leak memory but since it should exist throughout the entirety 
+			// of runtime it should only leak on shutdown when the OS will free it anyway.
+			_GlobalFrameAlloc = new FrameAlloc();
+		}
+
+		return *_GlobalFrameAlloc;
+	}
+
+	BS_UTILITY_EXPORT UINT8* bs_frame_alloc(UINT32 numBytes)
+	{
+		return gFrameAlloc().alloc(numBytes);
+	}
+
+	BS_UTILITY_EXPORT UINT8* bs_frame_alloc_aligned(UINT32 count, UINT32 align)
+	{
+		return gFrameAlloc().allocAligned(count, align);
+	}
+
+	BS_UTILITY_EXPORT void bs_frame_free(void* data)
+	{
+		gFrameAlloc().free((UINT8*)data);
+	}
+
+	BS_UTILITY_EXPORT void bs_frame_free_aligned(void* data)
+	{
+		gFrameAlloc().free((UINT8*)data);
+	}
+
+	BS_UTILITY_EXPORT void bs_frame_mark()
+	{
+		gFrameAlloc().markFrame();
+	}
+
+	BS_UTILITY_EXPORT void bs_frame_clear()
+	{
+		gFrameAlloc().clear();
+	}
 }
 }

+ 250 - 6
Source/BansheeUtility/Allocators/BsFrameAlloc.h

@@ -5,7 +5,10 @@
 #include <limits>
 #include <limits>
 #include <new>                  /* For 'placement new' */
 #include <new>                  /* For 'placement new' */
 
 
-#include "Prerequisites/BsPrerequisitesUtil.h"
+#include "Prerequisites/BsPlatformDefines.h"
+#include "Prerequisites/BsTypes.h"
+#include "Prerequisites/BsStdHeaders.h"
+#include "Threading/BsThreadDefines.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -75,7 +78,7 @@ namespace bs
 		 * @note	Not thread safe.
 		 * @note	Not thread safe.
 		 */
 		 */
 		template<class T, class... Args>
 		template<class T, class... Args>
-		T* alloc(Args &&...args)
+		T* construct(Args &&...args)
 		{
 		{
 			return new ((T*)alloc(sizeof(T))) T(std::forward<Args>(args)...);
 			return new ((T*)alloc(sizeof(T))) T(std::forward<Args>(args)...);
 		}
 		}
@@ -89,7 +92,7 @@ namespace bs
 		 * @note
 		 * @note
 		 * Thread safe.
 		 * Thread safe.
 		 */
 		 */
-		void dealloc(UINT8* data);
+		void free(UINT8* data);
 
 
 		/**
 		/**
 		 * Deallocates and destructs a previously allocated object.
 		 * Deallocates and destructs a previously allocated object.
@@ -101,12 +104,12 @@ namespace bs
 		 * Thread safe.
 		 * Thread safe.
 		 */
 		 */
 		template<class T>
 		template<class T>
-		void dealloc(T* obj)
+		void free(T* obj)
 		{
 		{
 			if (obj != nullptr)
 			if (obj != nullptr)
 				obj->~T();
 				obj->~T();
 
 
-			dealloc((UINT8*)obj);
+			free((UINT8*)obj);
 		}
 		}
 
 
 		/** Starts a new frame. Next call to clear() will only clear memory allocated past this point. */
 		/** Starts a new frame. Next call to clear() will only clear memory allocated past this point. */
@@ -148,6 +151,18 @@ namespace bs
 		void deallocBlock(MemBlock* block);
 		void deallocBlock(MemBlock* block);
 	};
 	};
 
 
+	/** 
+	 * Version of FrameAlloc that allows blocks size to be provided through the template argument instead of the 
+	 * constructor. */
+	template<int BlockSize>
+	class TFrameAlloc : public FrameAlloc
+	{
+	public:
+		TFrameAlloc()
+			:FrameAlloc(BlockSize)
+		{ }
+	};
+
 	/** Allocator for the standard library that internally uses a frame allocator. */
 	/** Allocator for the standard library that internally uses a frame allocator. */
 	template <class T>
 	template <class T>
 	class StdFrameAlloc
 	class StdFrameAlloc
@@ -196,7 +211,7 @@ namespace bs
 		/** Deallocate storage p of deleted elements. */
 		/** Deallocate storage p of deleted elements. */
 		void deallocate(T* p, size_t num) const noexcept
 		void deallocate(T* p, size_t num) const noexcept
 		{
 		{
-			mFrameAlloc->dealloc((UINT8*)p);
+			mFrameAlloc->free((UINT8*)p);
 		}
 		}
 
 
 		FrameAlloc* mFrameAlloc;
 		FrameAlloc* mFrameAlloc;
@@ -225,4 +240,233 @@ namespace bs
 
 
 	/** @} */
 	/** @} */
 	/** @} */
 	/** @} */
+
+	/** @addtogroup Memory
+	 *  @{
+	 */
+
+	/**
+	 * Returns a global, application wide FrameAlloc. Each thread gets its own frame allocator.
+	 *
+	 * @note	Thread safe.
+	 */
+	BS_UTILITY_EXPORT FrameAlloc& gFrameAlloc();
+
+	/**
+	 * Allocates some memory using the global frame allocator.
+	 *
+	 * @param[in]	numBytes	Number of bytes to allocate.
+	 */
+	BS_UTILITY_EXPORT UINT8* bs_frame_alloc(UINT32 numBytes);
+
+	/** 
+	 * Allocates the specified number of bytes aligned to the provided boundary, using the global frame allocator. Boundary
+	 * is in bytes and must be a power of two.
+	 */
+	BS_UTILITY_EXPORT UINT8* bs_frame_alloc_aligned(UINT32 count, UINT32 align);
+
+	/**
+	 * Deallocates memory allocated with the global frame allocator.
+	 *
+	 * @note	Must be called on the same thread the memory was allocated on.
+	 */
+	BS_UTILITY_EXPORT void bs_frame_free(void* data);
+
+	/** 
+	 * Frees memory previously allocated with bs_frame_alloc_aligned(). 
+	 *
+	 * @note	Must be called on the same thread the memory was allocated on.
+	 */
+	BS_UTILITY_EXPORT void bs_frame_free_aligned(void* data);
+
+	/**
+	 * Allocates enough memory to hold the object of specified type using the global frame allocator, but does not 
+	 * construct the object. 
+	 */
+	template<class T>
+	T* bs_frame_alloc()
+	{
+		return (T*)bs_frame_alloc(sizeof(T));
+	}
+
+	/**
+	 * Allocates enough memory to hold N objects of specified type using the global frame allocator, but does not 
+	 * construct the object. 
+	 */
+	template<class T>
+	T* bs_frame_alloc(UINT32 count)
+	{
+		return (T*)bs_frame_alloc(sizeof(T) * count);
+	}
+
+	/**
+	 * Allocates enough memory to hold the object(s) of specified type using the global frame allocator, 
+	 * and constructs them.
+	 */
+	template<class T>
+	T* bs_frame_new(UINT32 count = 0)
+	{
+		T* data = bs_frame_alloc<T>(count);
+
+		for(unsigned int i = 0; i < count; i++)
+			new ((void*)&data[i]) T;
+
+		return data;
+	}
+
+	/**
+	 * Allocates enough memory to hold the object(s) of specified type using the global frame allocator, and constructs them.
+	 */
+	template<class T, class... Args>
+	T* bs_frame_new(Args &&...args, UINT32 count = 0)
+	{
+		T* data = bs_frame_alloc<T>(count);
+
+		for(unsigned int i = 0; i < count; i++)
+			new ((void*)&data[i]) T(std::forward<Args>(args)...);
+
+		return data;
+	}
+
+	/**
+	 * Destructs and deallocates an object allocated with the global frame allocator.
+	 *
+	 * @note	Must be called on the same thread the memory was allocated on.
+	 */
+	template<class T>
+	void bs_frame_delete(T* data)
+	{
+		data->~T();
+
+		bs_frame_free((UINT8*)data);
+	}
+
+	/**
+	 * Destructs and deallocates an array of objects allocated with the global frame allocator.
+	 *
+	 * @note	Must be called on the same thread the memory was allocated on.
+	 */
+	template<class T>
+	void bs_frame_delete(T* data, UINT32 count)
+	{
+		for(unsigned int i = 0; i < count; i++)
+			data[i].~T();
+
+		bs_frame_free((UINT8*)data);
+	}
+
+	/** @copydoc FrameAlloc::markFrame */
+	BS_UTILITY_EXPORT void bs_frame_mark();
+
+	/** @copydoc FrameAlloc::clear */
+	BS_UTILITY_EXPORT void bs_frame_clear();
+
+	/** String allocated with a frame allocator. */
+	typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, FrameAlloc>> FrameString;
+
+	/** WString allocated with a frame allocator. */
+	typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, StdAlloc<wchar_t, FrameAlloc>> FrameWString;
+
+	/** Vector allocated with a frame allocator. */
+	template <typename T, typename A = StdAlloc<T, FrameAlloc>>
+	using FrameVector = std::vector < T, A > ;
+
+	/** Stack allocated with a frame allocator. */
+	template <typename T, typename A = StdAlloc<T, FrameAlloc>>
+	using FrameStack = std::stack < T, std::deque<T, A> > ;
+
+	/** Queue allocated with a frame allocator. */
+	template <typename T, typename A = StdAlloc<T, FrameAlloc>>
+	using FrameQueue = std::queue<T, std::deque<T, A>>;
+
+	/** Set allocated with a frame allocator. */
+	template <typename T, typename P = std::less<T>, typename A = StdAlloc<T, FrameAlloc>>
+	using FrameSet = std::set < T, P, A > ;
+
+	/** Map allocated with a frame allocator. */
+	template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>, FrameAlloc>>
+	using FrameMap = std::map < K, V, P, A >;
+
+	/** UnorderedSet allocated with a frame allocator. */
+	template <typename T, typename H = std::hash<T>, typename C = std::equal_to<T>, typename A = StdAlloc<T, FrameAlloc>>
+	using FrameUnorderedSet = std::unordered_set < T, H, C, A >;
+
+	/** UnorderedMap allocated with a frame allocator. */
+	template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>, FrameAlloc>>
+	using FrameUnorderedMap = std::unordered_map < K, V, H, C, A >;
+
+	/** @} */
+	/** @addtogroup Internal-Utility
+	 *  @{
+	 */
+
+	/** @addtogroup Memory-Internal
+	 *  @{
+	 */
+
+	extern BS_THREADLOCAL FrameAlloc* _GlobalFrameAlloc;
+
+	/**
+	 * Specialized memory allocator implementations that allows use of a global frame allocator in normal 
+	 * new/delete/free/dealloc operators.
+	 */
+	template<>
+	class MemoryAllocator<FrameAlloc> : public MemoryAllocatorBase
+	{
+	public:
+		/** @copydoc MemoryAllocator::allocate */
+		static void* allocate(size_t bytes)
+		{
+			return bs_frame_alloc((UINT32)bytes);
+		}
+
+		/** @copydoc MemoryAllocator::allocateAligned */
+		static void* allocateAligned(size_t bytes, size_t alignment)
+		{
+#if BS_PROFILING_ENABLED
+			incAllocCount();
+#endif
+
+			return bs_frame_alloc_aligned((UINT32)bytes, (UINT32)alignment);
+		}
+
+		/** @copydoc MemoryAllocator::allocateAligned16 */
+		static void* allocateAligned16(size_t bytes)
+		{
+#if BS_PROFILING_ENABLED
+			incAllocCount();
+#endif
+
+			return bs_frame_alloc_aligned((UINT32)bytes, 16);
+		}
+
+		/** @copydoc MemoryAllocator::free */
+		static void free(void* ptr)
+		{
+			bs_frame_free(ptr);
+		}
+
+		/** @copydoc MemoryAllocator::freeAligned */
+		static void freeAligned(void* ptr)
+		{
+#if BS_PROFILING_ENABLED
+			incFreeCount();
+#endif
+
+			bs_frame_free_aligned(ptr);
+		}
+
+		/** @copydoc MemoryAllocator::freeAligned16 */
+		static void freeAligned16(void* ptr)
+		{
+#if BS_PROFILING_ENABLED
+			incFreeCount();
+#endif
+
+			bs_frame_free_aligned(ptr);
+		}
+	};
+
+	/** @} */
+	/** @} */
 }
 }

+ 43 - 0
Source/BansheeUtility/Allocators/BsFreeAlloc.h

@@ -0,0 +1,43 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2017 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "Prerequisites/BsPrerequisitesUtil.h"
+
+namespace bs
+{
+	/** @addtogroup Internal-Utility
+	 *  @{
+	 */
+
+	/** @addtogroup Memory-Internal
+	 *  @{
+	 */
+
+	/**
+	 * Free allocator with no limitations, using traditional malloc/free under the hood. */
+	class FreeAlloc
+	{
+	public:
+		/** Allocates memory. */
+		UINT8* alloc(UINT32 amount)
+		{
+			return (UINT8*)malloc(amount);
+		}
+
+		/** Deallocates a previously allocated piece of memory. */
+		void free(void* data)
+		{
+			::free(data);
+		}
+
+		/** Unused */
+		void clear()
+		{
+			// Do nothing
+		}
+	};
+
+	/** @} */
+	/** @} */
+}

+ 0 - 52
Source/BansheeUtility/Allocators/BsGlobalFrameAlloc.cpp

@@ -1,52 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "Prerequisites/BsPrerequisitesUtil.h"
-#include "Allocators/BsGlobalFrameAlloc.h"
-#include "Allocators/BsFrameAlloc.h"
-
-namespace bs
-{
-	BS_THREADLOCAL FrameAlloc* _GlobalFrameAlloc = nullptr;
-
-	BS_UTILITY_EXPORT FrameAlloc& gFrameAlloc()
-	{
-		if (_GlobalFrameAlloc == nullptr)
-		{
-			// Note: This will leak memory but since it should exist throughout the entirety 
-			// of runtime it should only leak on shutdown when the OS will free it anyway.
-			_GlobalFrameAlloc = new FrameAlloc();
-		}
-
-		return *_GlobalFrameAlloc;
-	}
-
-	BS_UTILITY_EXPORT UINT8* bs_frame_alloc(UINT32 numBytes)
-	{
-		return gFrameAlloc().alloc(numBytes);
-	}
-
-	BS_UTILITY_EXPORT UINT8* bs_frame_alloc_aligned(UINT32 count, UINT32 align)
-	{
-		return gFrameAlloc().allocAligned(count, align);
-	}
-
-	BS_UTILITY_EXPORT void bs_frame_free(void* data)
-	{
-		gFrameAlloc().dealloc((UINT8*)data);
-	}
-
-	BS_UTILITY_EXPORT void bs_frame_free_aligned(void* data)
-	{
-		gFrameAlloc().dealloc((UINT8*)data);
-	}
-
-	BS_UTILITY_EXPORT void bs_frame_mark()
-	{
-		gFrameAlloc().markFrame();
-	}
-
-	BS_UTILITY_EXPORT void bs_frame_clear()
-	{
-		gFrameAlloc().clear();
-	}
-}

+ 0 - 240
Source/BansheeUtility/Allocators/BsGlobalFrameAlloc.h

@@ -1,240 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "Prerequisites/BsStdHeaders.h"
-#include "Threading/BsThreadDefines.h"
-
-namespace bs
-{
-	/** @addtogroup Memory
-	 *  @{
-	 */
-
-	class FrameAlloc;
-
-	/**
-	 * Returns a global, application wide FrameAlloc. Each thread gets its own frame allocator.
-	 *
-	 * @note	Thread safe.
-	 */
-	BS_UTILITY_EXPORT FrameAlloc& gFrameAlloc();
-
-	/**
-	 * Allocates some memory using the global frame allocator.
-	 *
-	 * @param[in]	numBytes	Number of bytes to allocate.
-	 */
-	BS_UTILITY_EXPORT UINT8* bs_frame_alloc(UINT32 numBytes);
-
-	/** 
-	 * Allocates the specified number of bytes aligned to the provided boundary, using the global frame allocator. Boundary
-	 * is in bytes and must be a power of two.
-	 */
-	BS_UTILITY_EXPORT UINT8* bs_frame_alloc_aligned(UINT32 count, UINT32 align);
-
-	/**
-	 * Deallocates memory allocated with the global frame allocator.
-	 *
-	 * @note	Must be called on the same thread the memory was allocated on.
-	 */
-	BS_UTILITY_EXPORT void bs_frame_free(void* data);
-
-	/** 
-	 * Frees memory previously allocated with bs_frame_alloc_aligned(). 
-	 *
-	 * @note	Must be called on the same thread the memory was allocated on.
-	 */
-	BS_UTILITY_EXPORT void bs_frame_free_aligned(void* data);
-
-	/**
-	 * Allocates enough memory to hold the object of specified type using the global frame allocator, but does not 
-	 * construct the object. 
-	 */
-	template<class T>
-	T* bs_frame_alloc()
-	{
-		return (T*)bs_frame_alloc(sizeof(T));
-	}
-
-	/**
-	 * Allocates enough memory to hold N objects of specified type using the global frame allocator, but does not 
-	 * construct the object. 
-	 */
-	template<class T>
-	T* bs_frame_alloc(UINT32 count)
-	{
-		return (T*)bs_frame_alloc(sizeof(T) * count);
-	}
-
-	/**
-	 * Allocates enough memory to hold the object(s) of specified type using the global frame allocator, 
-	 * and constructs them.
-	 */
-	template<class T>
-	T* bs_frame_new(UINT32 count = 0)
-	{
-		T* data = bs_frame_alloc<T>(count);
-
-		for(unsigned int i = 0; i < count; i++)
-			new ((void*)&data[i]) T;
-
-		return data;
-	}
-
-	/**
-	 * Allocates enough memory to hold the object(s) of specified type using the global frame allocator, and constructs them.
-	 */
-	template<class T, class... Args>
-	T* bs_frame_new(Args &&...args, UINT32 count = 0)
-	{
-		T* data = bs_frame_alloc<T>(count);
-
-		for(unsigned int i = 0; i < count; i++)
-			new ((void*)&data[i]) T(std::forward<Args>(args)...);
-
-		return data;
-	}
-
-	/**
-	 * Destructs and deallocates an object allocated with the global frame allocator.
-	 *
-	 * @note	Must be called on the same thread the memory was allocated on.
-	 */
-	template<class T>
-	void bs_frame_delete(T* data)
-	{
-		data->~T();
-
-		bs_frame_free((UINT8*)data);
-	}
-
-	/**
-	 * Destructs and deallocates an array of objects allocated with the global frame allocator.
-	 *
-	 * @note	Must be called on the same thread the memory was allocated on.
-	 */
-	template<class T>
-	void bs_frame_delete(T* data, UINT32 count)
-	{
-		for(unsigned int i = 0; i < count; i++)
-			data[i].~T();
-
-		bs_frame_free((UINT8*)data);
-	}
-
-	/** @copydoc FrameAlloc::markFrame */
-	BS_UTILITY_EXPORT void bs_frame_mark();
-
-	/** @copydoc FrameAlloc::clear */
-	BS_UTILITY_EXPORT void bs_frame_clear();
-
-	/** String allocated with a frame allocator. */
-	typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, FrameAlloc>> FrameString;
-
-	/** WString allocated with a frame allocator. */
-	typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, StdAlloc<wchar_t, FrameAlloc>> FrameWString;
-
-	/** Vector allocated with a frame allocator. */
-	template <typename T, typename A = StdAlloc<T, FrameAlloc>>
-	using FrameVector = std::vector < T, A > ;
-
-	/** Stack allocated with a frame allocator. */
-	template <typename T, typename A = StdAlloc<T, FrameAlloc>>
-	using FrameStack = std::stack < T, std::deque<T, A> > ;
-
-	/** Queue allocated with a frame allocator. */
-	template <typename T, typename A = StdAlloc<T, FrameAlloc>>
-	using FrameQueue = std::queue<T, std::deque<T, A>>;
-
-	/** Set allocated with a frame allocator. */
-	template <typename T, typename P = std::less<T>, typename A = StdAlloc<T, FrameAlloc>>
-	using FrameSet = std::set < T, P, A > ;
-
-	/** Map allocated with a frame allocator. */
-	template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>, FrameAlloc>>
-	using FrameMap = std::map < K, V, P, A >;
-
-	/** UnorderedSet allocated with a frame allocator. */
-	template <typename T, typename H = std::hash<T>, typename C = std::equal_to<T>, typename A = StdAlloc<T, FrameAlloc>>
-	using FrameUnorderedSet = std::unordered_set < T, H, C, A >;
-
-	/** UnorderedMap allocated with a frame allocator. */
-	template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>, FrameAlloc>>
-	using FrameUnorderedMap = std::unordered_map < K, V, H, C, A >;
-
-	/** @} */
-	/** @addtogroup Internal-Utility
-	 *  @{
-	 */
-
-	/** @addtogroup Memory-Internal
-	 *  @{
-	 */
-
-	extern BS_THREADLOCAL FrameAlloc* _GlobalFrameAlloc;
-
-	/**
-	 * Specialized memory allocator implementations that allows use of a global frame allocator in normal 
-	 * new/delete/free/dealloc operators.
-	 */
-	template<>
-	class MemoryAllocator<FrameAlloc> : public MemoryAllocatorBase
-	{
-	public:
-		/** @copydoc MemoryAllocator::allocate */
-		static void* allocate(size_t bytes)
-		{
-			return bs_frame_alloc((UINT32)bytes);
-		}
-
-		/** @copydoc MemoryAllocator::allocateAligned */
-		static void* allocateAligned(size_t bytes, size_t alignment)
-		{
-#if BS_PROFILING_ENABLED
-			incAllocCount();
-#endif
-
-			return bs_frame_alloc_aligned((UINT32)bytes, (UINT32)alignment);
-		}
-
-		/** @copydoc MemoryAllocator::allocateAligned16 */
-		static void* allocateAligned16(size_t bytes)
-		{
-#if BS_PROFILING_ENABLED
-			incAllocCount();
-#endif
-
-			return bs_frame_alloc_aligned((UINT32)bytes, 16);
-		}
-
-		/** @copydoc MemoryAllocator::free */
-		static void free(void* ptr)
-		{
-			bs_frame_free(ptr);
-		}
-
-		/** @copydoc MemoryAllocator::freeAligned */
-		static void freeAligned(void* ptr)
-		{
-#if BS_PROFILING_ENABLED
-			incFreeCount();
-#endif
-
-			bs_frame_free_aligned(ptr);
-		}
-
-		/** @copydoc MemoryAllocator::freeAligned16 */
-		static void freeAligned16(void* ptr)
-		{
-#if BS_PROFILING_ENABLED
-			incFreeCount();
-#endif
-
-			bs_frame_free_aligned(ptr);
-		}
-	};
-
-	/** @} */
-	/** @} */
-}

+ 6 - 4
Source/BansheeUtility/Allocators/BsMemoryAllocator.h

@@ -4,11 +4,11 @@
 #undef min
 #undef min
 #undef max
 #undef max
 
 
-#include "Prerequisites/BsTypes.h"	        // for UINT64
+#include "Prerequisites/BsTypes.h"
 
 
 #include <atomic>
 #include <atomic>
 #include <limits>
 #include <limits>
-#include <new>                  /* For 'placement new' */
+#include <new>
 #include <utility>
 #include <utility>
 
 
 #if BS_PLATFORM == BS_PLATFORM_LINUX
 #if BS_PLATFORM == BS_PLATFORM_LINUX
@@ -437,6 +437,8 @@ namespace bs
 	/** @} */
 	/** @} */
 }
 }
 
 
-#include "Allocators/BsMemStack.h"
-#include "Allocators/BsGlobalFrameAlloc.h"
+#include "Allocators/BsStackAlloc.h"
+#include "Allocators/BsFreeAlloc.h"
+#include "Allocators/BsFrameAlloc.h"
+#include "Allocators/BsStaticAlloc.h"
 #include "Allocators/BsMemAllocProfiler.h"
 #include "Allocators/BsMemAllocProfiler.h"

+ 1 - 1
Source/BansheeUtility/Allocators/BsMemStack.cpp → Source/BansheeUtility/Allocators/BsStackAlloc.cpp

@@ -1,7 +1,7 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "Prerequisites/BsPrerequisitesUtil.h"
 #include "Prerequisites/BsPrerequisitesUtil.h"
-#include "Allocators/BsMemStack.h"
+#include "Allocators/BsStackAlloc.h"
 
 
 namespace bs
 namespace bs
 {
 {

+ 0 - 0
Source/BansheeUtility/Allocators/BsMemStack.h → Source/BansheeUtility/Allocators/BsStackAlloc.h


+ 138 - 100
Source/BansheeUtility/Allocators/BsStaticAlloc.h

@@ -15,19 +15,17 @@ namespace bs
 	/**
 	/**
 	 * Static allocator that attempts to perform zero heap (dynamic) allocations by always keeping an active preallocated 
 	 * Static allocator that attempts to perform zero heap (dynamic) allocations by always keeping an active preallocated 
 	 * buffer. The allocator provides a fixed amount of preallocated memory, and if the size of the allocated data goes over
 	 * buffer. The allocator provides a fixed amount of preallocated memory, and if the size of the allocated data goes over
-	 * that limit the allocator will fall back to dynamic heap allocations.
+	 * that limit the allocator will fall back to dynamic heap allocations using the selected allocator.
+	 * 
+	 * @note		Static allocations can only be freed if memory is deallocated in opposite order it is allocated.
+	 *				Otherwise static memory gets orphaned until a call to clear(). Dynamic memory allocations behave
+	 *				depending on the selected allocator.
 	 * 
 	 * 
-	 * @note	This kind of allocator is only able to free all of its memory at once. Freeing individual elements
-	 *			will not free the memory until a call to clear().
-	 * 			
 	 * @tparam	BlockSize			Size of the initially allocated static block, and minimum size of any dynamically 
 	 * @tparam	BlockSize			Size of the initially allocated static block, and minimum size of any dynamically 
 	 *								allocated memory.
 	 *								allocated memory.
-	 * @tparam	MaxDynamicMemory	Maximum amount of unused memory allowed in the buffer after a call to clear(). Keeping 
-	 *								active dynamic buffers can help prevent further memory allocations at the cost of 
-	 *								memory. This is not relevant if you stay within the bounds of the statically allocated 
-	 *								memory.
+	 * @tparam	DynamicAllocator	Allocator to fall-back to when static buffer is full.
 	 */
 	 */
-	template<int BlockSize = 512, int MaxDynamicMemory = 512>
+	template<int BlockSize = 512, class DynamicAllocator = TFrameAlloc<BlockSize>>
 	class StaticAlloc
 	class StaticAlloc
 	{
 	{
 	private:
 	private:
@@ -36,8 +34,7 @@ namespace bs
 		{
 		{
 		public:
 		public:
 			MemBlock(UINT8* data, UINT32 size) 
 			MemBlock(UINT8* data, UINT32 size) 
-				:mData(data), mFreePtr(0), mSize(size),
-				mPrevBlock(nullptr), mNextBlock(nullptr)
+				:mData(data), mFreePtr(0), mSize(size), mNextBlock(nullptr)
 			{ }
 			{ }
 
 
 			/** Allocates a piece of memory within the block. Caller must ensure the block has enough empty space. */
 			/** Allocates a piece of memory within the block. Caller must ensure the block has enough empty space. */
@@ -49,6 +46,16 @@ namespace bs
 				return freePtr;
 				return freePtr;
 			}
 			}
 
 
+			/** 
+			 * Frees a piece of memory within the block. If the memory isn't the last allocated memory, no deallocation
+			 * happens and that memory is instead orphaned.
+			 */
+			void free(UINT8* data, UINT32 allocSize)
+			{
+				if((data + allocSize) == (mData + mFreePtr))
+					mFreePtr -= allocSize;
+			}
+
 			/** Releases all allocations within a block but doesn't actually free the memory. */
 			/** Releases all allocations within a block but doesn't actually free the memory. */
 			void clear()
 			void clear()
 			{
 			{
@@ -58,24 +65,16 @@ namespace bs
 			UINT8* mData;
 			UINT8* mData;
 			UINT32 mFreePtr;
 			UINT32 mFreePtr;
 			UINT32 mSize;
 			UINT32 mSize;
-			MemBlock* mPrevBlock;
 			MemBlock* mNextBlock;
 			MemBlock* mNextBlock;
 		};
 		};
 
 
 	public:
 	public:
 		StaticAlloc()
 		StaticAlloc()
-			:mStaticBlock(mStaticData, BlockSize), mFreeBlock(&mStaticBlock),
-			mTotalAllocBytes(0)
-		{
-
-		}
+			: mFreePtr(0), mTotalAllocBytes(0)
+		{ }
 
 
 		~StaticAlloc()
 		~StaticAlloc()
-		{
-			assert(mFreeBlock == &mStaticBlock && mStaticBlock.mFreePtr == 0);
-
-			freeBlocks(mFreeBlock);
-		}
+		{ }
 
 
 		/**
 		/**
 		 * Allocates a new piece of memory of the specified size.
 		 * Allocates a new piece of memory of the specified size.
@@ -91,11 +90,16 @@ namespace bs
 			amount += sizeof(UINT32);
 			amount += sizeof(UINT32);
 #endif
 #endif
 
 
-			UINT32 freeMem = mFreeBlock->mSize - mFreeBlock->mFreePtr;
+			UINT32 freeMem = BlockSize - mFreePtr;
+			
+			UINT8* data;
 			if (amount > freeMem)
 			if (amount > freeMem)
-				allocBlock(amount);
-
-			UINT8* data = mFreeBlock->alloc(amount);
+				data = mDynamicAlloc.alloc(amount);
+			else
+			{
+				data = &mStaticData[mFreePtr];
+				mFreePtr += amount;
+			}
 
 
 #if BS_DEBUG_MODE
 #if BS_DEBUG_MODE
 			mTotalAllocBytes += amount;
 			mTotalAllocBytes += amount;
@@ -110,13 +114,33 @@ namespace bs
 		}
 		}
 
 
 		/** Deallocates a previously allocated piece of memory. */
 		/** Deallocates a previously allocated piece of memory. */
-		void free(void* data)
+		void free(void* data, UINT32 allocSize)
 		{
 		{
 			if (data == nullptr)
 			if (data == nullptr)
 				return;
 				return;
 
 
-			// Dealloc is only used for debug and can be removed if needed. All the actual deallocation
-			// happens in clear()
+			UINT8* dataPtr = (UINT8*)data;
+#if BS_DEBUG_MODE
+			dataPtr -= sizeof(UINT32);
+
+			UINT32* storedSize = (UINT32*)(dataPtr);
+			mTotalAllocBytes -= *storedSize;
+#endif
+
+			if(data > mStaticData && data < (mStaticData + BlockSize))
+			{
+				if((((UINT8*)data) + allocSize) == (mStaticData + mFreePtr))
+					mFreePtr -= allocSize;
+			}
+			else
+				mDynamicAlloc.free(dataPtr);
+		}
+
+		/** Deallocates a previously allocated piece of memory. */
+		void free(void* data)
+		{
+			if (data == nullptr)
+				return;
 
 
 #if BS_DEBUG_MODE
 #if BS_DEBUG_MODE
 			UINT8* dataPtr = (UINT8*)data;
 			UINT8* dataPtr = (UINT8*)data;
@@ -125,6 +149,8 @@ namespace bs
 			UINT32* storedSize = (UINT32*)(dataPtr);
 			UINT32* storedSize = (UINT32*)(dataPtr);
 			mTotalAllocBytes -= *storedSize;
 			mTotalAllocBytes -= *storedSize;
 #endif
 #endif
+			if(data < mStaticData || data >= (mStaticData + BlockSize))
+				mDynamicAlloc.free(dataPtr);
 		}
 		}
 
 
 		/**
 		/**
@@ -161,7 +187,7 @@ namespace bs
 		{
 		{
 			data->~T();
 			data->~T();
 
 
-			free(data);
+			free(data, sizeof(T));
 		}
 		}
 
 
 		/** Destructs and deallocates an array of objects allocated with the static frame allocator. */
 		/** Destructs and deallocates an array of objects allocated with the static frame allocator. */
@@ -171,7 +197,7 @@ namespace bs
 			for(unsigned int i = 0; i < count; i++)
 			for(unsigned int i = 0; i < count; i++)
 				data[i].~T();
 				data[i].~T();
 
 
-			free(data);
+			free(data, sizeof(T) * count);
 		}
 		}
 
 
 		/** Frees the internal memory buffers. All external allocations must be freed before calling this. */
 		/** Frees the internal memory buffers. All external allocations must be freed before calling this. */
@@ -179,94 +205,106 @@ namespace bs
 		{
 		{
 			assert(mTotalAllocBytes == 0);
 			assert(mTotalAllocBytes == 0);
 
 
-			MemBlock* dynamicBlock = mStaticBlock.mNextBlock;
-			INT32 totalDynamicMemAmount = 0;
-			UINT32 numDynamicBlocks = 0;
-
-			while (dynamicBlock != nullptr)
-			{
-				totalDynamicMemAmount += dynamicBlock->mFreePtr;
-				dynamicBlock->clear();
-			
-				dynamicBlock = dynamicBlock->mNextBlock;
-				numDynamicBlocks++;
-			}
-
-			mFreeBlock = &mStaticBlock;
-			mStaticBlock.clear();
-
-			if (numDynamicBlocks > 1)
-			{
-				freeBlocks(&mStaticBlock);
-				allocBlock(std::min(totalDynamicMemAmount, MaxDynamicMemory));
-				mFreeBlock = &mStaticBlock;
-			}
-			else if (numDynamicBlocks == 1 && MaxDynamicMemory == 0)
-			{
-				freeBlocks(&mStaticBlock);
-			}
+			mFreePtr = 0;
+			mDynamicAlloc.clear();
 		}
 		}
 
 
 	private:
 	private:
 		UINT8 mStaticData[BlockSize];
 		UINT8 mStaticData[BlockSize];
-		MemBlock mStaticBlock;
+		UINT32 mFreePtr;
+		DynamicAllocator mDynamicAlloc;
 
 
-		MemBlock* mFreeBlock;
 		UINT32 mTotalAllocBytes;
 		UINT32 mTotalAllocBytes;
+	};
 
 
-		/**
-		 * Allocates a dynamic block of memory of the wanted size. The exact allocation size might be slightly higher in 
-		 * order to store block meta data.
-		 */
-		MemBlock* allocBlock(UINT32 wantedSize)
-		{
-			UINT32 blockSize = BlockSize;
-			if (wantedSize > blockSize)
-				blockSize = wantedSize;
+	/** Allocator for the standard library that internally uses a static allocator. */
+	template <int BlockSize, class T>
+	class StdStaticAlloc
+	{
+	public:
+		typedef T value_type;
+		typedef value_type* pointer;
+		typedef const value_type* const_pointer;
+		typedef value_type& reference;
+		typedef const value_type& const_reference;
+		typedef std::size_t size_type;
+		typedef std::ptrdiff_t difference_type;
 
 
-			MemBlock* dynamicBlock = mFreeBlock->mNextBlock;
-			MemBlock* newBlock = nullptr;
-			while (dynamicBlock != nullptr)
-			{
-				if (dynamicBlock->mSize >= blockSize)
-				{
-					newBlock = dynamicBlock;
-					break;
-				}
+		StdStaticAlloc() = default; 
 
 
-				dynamicBlock = dynamicBlock->mNextBlock;
-			}
+		StdStaticAlloc(StaticAlloc<BlockSize, FreeAlloc>* alloc) noexcept
+			:mStaticAlloc(alloc)
+		{ }
 
 
-			if (newBlock == nullptr)
-			{
-				UINT8* data = (UINT8*)reinterpret_cast<UINT8*>(bs_alloc(blockSize + sizeof(MemBlock)));
-				newBlock = new (data)MemBlock(data + sizeof(MemBlock), blockSize);
-				newBlock->mPrevBlock = mFreeBlock;
-				mFreeBlock->mNextBlock = newBlock;
-			}
+		template<class U> StdStaticAlloc(const StdStaticAlloc<BlockSize, U>& alloc) noexcept
+			:mStaticAlloc(alloc.mStaticAlloc)
+		{ }
 
 
-			mFreeBlock = newBlock;
-			return newBlock;
-		}
+		template<class U> class rebind { public: typedef StdStaticAlloc<BlockSize, U> other; };
 
 
-		/** Releases memory for any dynamic blocks following the provided block (if there are any). */
-		void freeBlocks(MemBlock* start)
+		/** Allocate but don't initialize number elements of type T.*/
+		T* allocate(const size_t num) const
 		{
 		{
-			MemBlock* dynamicBlock = start->mNextBlock;
-			while (dynamicBlock != nullptr)
-			{
-				MemBlock* nextBlock = dynamicBlock->mNextBlock;
+			if (num == 0)
+				return nullptr;
 
 
-				dynamicBlock->~MemBlock();
-				bs_free(dynamicBlock);
+			if (num > static_cast<size_t>(-1) / sizeof(T))
+				return nullptr; // Error
 
 
-				dynamicBlock = nextBlock;
-			}
+			void* const pv = mStaticAlloc->alloc((UINT32)(num * sizeof(T)));
+			if (!pv)
+				return nullptr; // Error
 
 
-			start->mNextBlock = nullptr;
+			return static_cast<T*>(pv);
 		}
 		}
+
+		/** Deallocate storage p of deleted elements. */
+		void deallocate(T* p, size_t num) const noexcept
+		{
+			mStaticAlloc->free((UINT8*)p, (UINT32)num);
+		}
+
+		StaticAlloc<BlockSize, FreeAlloc>* mStaticAlloc = nullptr;
+
+		size_t max_size() const { return std::numeric_limits<UINT32>::max() / sizeof(T); }
+		void construct(pointer p, const_reference t) { new (p) T(t); }
+		void destroy(pointer p) { p->~T(); }
+		template<class U, class... Args>
+		void construct(U* p, Args&&... args) { new(p) U(std::forward<Args>(args)...); }
+
+		template <class T1, int N1, class T2, int N2>
+		friend bool operator== (const StdStaticAlloc<N1, T1>& a, const StdStaticAlloc<N2, T2>& b) throw();
+	
 	};
 	};
 
 
+	/** Return that all specializations of this allocator are interchangeable. */
+	template <class T1, int N1, class T2, int N2>
+	bool operator== (const StdStaticAlloc<N1, T1>& a, const StdStaticAlloc<N2, T2>& b) throw() 
+	{
+		return N1 == N2 && a.mStaticAlloc == b.mStaticAlloc;
+	}
+
+	/** Return that all specializations of this allocator are interchangeable. */
+	template <class T1, int N1, class T2, int N2>
+	bool operator!= (const StdStaticAlloc<N1, T1>& a, const StdStaticAlloc<N2, T2>& b) throw() 
+	{
+		return !(a == b);
+	}
+
+	/** @} */
 	/** @} */
 	/** @} */
+
+
+	/** @addtogroup Memory
+	 *  @{
+	 */
+
+	/** 
+	 * Equivalent to Vector, except it avoids any dynamic allocations until the number of elements exceeds @p Count. 
+	 * Requires allocator to be explicitly provided.
+	 */
+	template <typename T, int Count> 
+	using StaticVector = std::vector<T, StdStaticAlloc<sizeof(T) * Count, T>>;
+
 	/** @} */
 	/** @} */
 }
 }

+ 3 - 4
Source/BansheeUtility/CMakeSources.cmake

@@ -97,8 +97,7 @@ set(BS_BANSHEEUTILITY_INC_UTILITY
 
 
 set(BS_BANSHEEUTILITY_SRC_ALLOCATORS
 set(BS_BANSHEEUTILITY_SRC_ALLOCATORS
 	"Allocators/BsFrameAlloc.cpp"
 	"Allocators/BsFrameAlloc.cpp"
-	"Allocators/BsGlobalFrameAlloc.cpp"
-	"Allocators/BsMemStack.cpp"
+	"Allocators/BsStackAlloc.cpp"
 	"Allocators/BsMemoryAllocator.cpp"
 	"Allocators/BsMemoryAllocator.cpp"
 )
 )
 
 
@@ -121,12 +120,12 @@ set(BS_BANSHEEUTILITY_INC_RTTI
 
 
 set(BS_BANSHEEUTILITY_INC_ALLOCATORS
 set(BS_BANSHEEUTILITY_INC_ALLOCATORS
 	"Allocators/BsFrameAlloc.h"
 	"Allocators/BsFrameAlloc.h"
-	"Allocators/BsGlobalFrameAlloc.h"
 	"Allocators/BsMemAllocProfiler.h"
 	"Allocators/BsMemAllocProfiler.h"
 	"Allocators/BsMemoryAllocator.h"
 	"Allocators/BsMemoryAllocator.h"
-	"Allocators/BsMemStack.h"
+	"Allocators/BsStackAlloc.h"
 	"Allocators/BsStaticAlloc.h"
 	"Allocators/BsStaticAlloc.h"
 	"Allocators/BsGroupAlloc.h"
 	"Allocators/BsGroupAlloc.h"
+	"Allocators/BsFreeAlloc.h"
 )
 )
 
 
 set(BS_BANSHEEUTILITY_INC_THIRDPARTY
 set(BS_BANSHEEUTILITY_INC_THIRDPARTY

+ 2 - 3
Source/BansheeUtility/Math/BsDegree.h

@@ -2,8 +2,7 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #pragma once
 #pragma once
 
 
-#include "Prerequisites/BsPlatformDefines.h"
-#include "Prerequisites/BsRTTIPrerequisites.h"
+#include "Prerequisites/BsPrerequisitesUtil.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -47,7 +46,7 @@ namespace bs
 		Degree& operator-= (const Degree& d) { mDeg -= d.mDeg; return *this; }
 		Degree& operator-= (const Degree& d) { mDeg -= d.mDeg; return *this; }
 		Degree& operator-= (const Radian& r);
 		Degree& operator-= (const Radian& r);
 		Degree operator* (float f) const { return Degree (mDeg * f); }
 		Degree operator* (float f) const { return Degree (mDeg * f); }
-        Degree operator* (const Degree& f) const { return Degree (mDeg * f.mDeg); }
+		Degree operator* (const Degree& f) const { return Degree (mDeg * f.mDeg); }
 		Degree& operator*= (float f) { mDeg *= f; return *this; }
 		Degree& operator*= (float f) { mDeg *= f; return *this; }
 		Degree operator/ (float f) const { return Degree (mDeg / f); }
 		Degree operator/ (float f) const { return Degree (mDeg / f); }
 		Degree& operator/= (float f) { mDeg /= f; return *this; }
 		Degree& operator/= (float f) { mDeg /= f; return *this; }

+ 15 - 15
Source/BansheeUtility/Math/BsMath.h

@@ -13,10 +13,10 @@ namespace bs
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
-    /** Utility class providing common scalar math operations. */
-    class BS_UTILITY_EXPORT Math 
-    {
-    public:
+	/** Utility class providing common scalar math operations. */
+	class BS_UTILITY_EXPORT Math 
+	{
+	public:
 		/** Inverse cosine. */
 		/** Inverse cosine. */
 		static Radian acos(float val);
 		static Radian acos(float val);
 
 
@@ -30,16 +30,16 @@ namespace bs
 		static Radian atan2(float y, float x) { return Radian(std::atan2(y,x)); }
 		static Radian atan2(float y, float x) { return Radian(std::atan2(y,x)); }
 
 
 		/** Cosine. */
 		/** Cosine. */
-        static float cos(const Radian& val) { return (float)std::cos(val.valueRadians()); }
+		static float cos(const Radian& val) { return (float)std::cos(val.valueRadians()); }
 
 
 		/** Cosine. */
 		/** Cosine. */
-        static float cos(float val) { return (float)std::cos(val); }
+		static float cos(float val) { return (float)std::cos(val); }
 
 
 		/** Sine. */
 		/** Sine. */
-        static float sin(const Radian& val) { return (float)std::sin(val.valueRadians()); }
+		static float sin(const Radian& val) { return (float)std::sin(val.valueRadians()); }
 
 
 		/** Sine. */
 		/** Sine. */
-        static float sin(float val) { return (float)std::sin(val); }
+		static float sin(float val) { return (float)std::sin(val); }
 
 
 		/** Tangent. */
 		/** Tangent. */
 		static float tan(const Radian& val) { return (float)std::tan(val.valueRadians()); }
 		static float tan(const Radian& val) { return (float)std::tan(val.valueRadians()); }
@@ -51,10 +51,10 @@ namespace bs
 		static float sqrt(float val) { return (float)std::sqrt(val); }
 		static float sqrt(float val) { return (float)std::sqrt(val); }
 
 
 		/** Square root. */
 		/** Square root. */
-        static Radian sqrt(const Radian& val) { return Radian(std::sqrt(val.valueRadians())); }
+		static Radian sqrt(const Radian& val) { return Radian(std::sqrt(val.valueRadians())); }
 
 
 		/** Square root. */
 		/** Square root. */
-        static Degree sqrt(const Degree& val) { return Degree(std::sqrt(val.valueDegrees())); }
+		static Degree sqrt(const Degree& val) { return Degree(std::sqrt(val.valueDegrees())); }
 
 
 		/** Square root followed by an inverse. */
 		/** Square root followed by an inverse. */
 		static float invSqrt(float val);
 		static float invSqrt(float val);
@@ -141,14 +141,14 @@ namespace bs
 			return f != f;
 			return f != f;
 		}
 		}
 
 
-        /** Compare two floats, using tolerance for inaccuracies. */
-        static bool approxEquals(float a, float b, 
+		/** Compare two floats, using tolerance for inaccuracies. */
+		static bool approxEquals(float a, float b, 
 			float tolerance = std::numeric_limits<float>::epsilon())
 			float tolerance = std::numeric_limits<float>::epsilon())
 		{
 		{
 			return fabs(b - a) <= tolerance;
 			return fabs(b - a) <= tolerance;
 		}
 		}
 
 
-        /** Compare two doubles, using tolerance for inaccuracies. */
+		/** Compare two doubles, using tolerance for inaccuracies. */
 		static bool approxEquals(double a, double b, 
 		static bool approxEquals(double a, double b, 
 			double tolerance = std::numeric_limits<double>::epsilon())
 			double tolerance = std::numeric_limits<double>::epsilon())
 		{
 		{
@@ -171,8 +171,8 @@ namespace bs
 		static bool approxEquals(const Quaternion& a, const Quaternion& b, 
 		static bool approxEquals(const Quaternion& a, const Quaternion& b, 
 			float tolerance = std::numeric_limits<float>::epsilon());
 			float tolerance = std::numeric_limits<float>::epsilon());
 
 
-        /** Calculates the tangent space vector for a given set of positions / texture coords. */
-        static Vector3 calculateTriTangent(const Vector3& position1, const Vector3& position2, 
+		/** Calculates the tangent space vector for a given set of positions / texture coords. */
+		static Vector3 calculateTriTangent(const Vector3& position1, const Vector3& position2, 
 			const Vector3& position3, float u1, float v1, float u2, float v2, float u3, float v3);
 			const Vector3& position3, float u1, float v1, float u2, float v2, float u3, float v3);
 
 
 		/************************************************************************/
 		/************************************************************************/

+ 3 - 4
Source/BansheeUtility/Math/BsRadian.h

@@ -2,8 +2,7 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #pragma once
 #pragma once
 
 
-#include "Prerequisites/BsPlatformDefines.h"
-#include "Prerequisites/BsRTTIPrerequisites.h"
+#include "Prerequisites/BsPrerequisitesUtil.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -37,7 +36,7 @@ namespace bs
 		/** Wraps the angle in [0, 2 *  PI) range. */
 		/** Wraps the angle in [0, 2 *  PI) range. */
 		Radian wrap();
 		Radian wrap();
 
 
-        const Radian& operator+ () const { return *this; }
+		const Radian& operator+ () const { return *this; }
 		Radian operator+ (const Radian& r) const { return Radian (mRad + r.mRad); }
 		Radian operator+ (const Radian& r) const { return Radian (mRad + r.mRad); }
 		Radian operator+ (const Degree& d) const;
 		Radian operator+ (const Degree& d) const;
 		Radian& operator+= (const Radian& r) { mRad += r.mRad; return *this; }
 		Radian& operator+= (const Radian& r) { mRad += r.mRad; return *this; }
@@ -48,7 +47,7 @@ namespace bs
 		Radian& operator-= (const Radian& r) { mRad -= r.mRad; return *this; }
 		Radian& operator-= (const Radian& r) { mRad -= r.mRad; return *this; }
 		Radian& operator-= (const Degree& d);
 		Radian& operator-= (const Degree& d);
 		Radian operator* (float f) const { return Radian (mRad * f); }
 		Radian operator* (float f) const { return Radian (mRad * f); }
-        Radian operator* (const Radian& f) const { return Radian (mRad * f.mRad); }
+		Radian operator* (const Radian& f) const { return Radian (mRad * f.mRad); }
 		Radian& operator*= (float f) { mRad *= f; return *this; }
 		Radian& operator*= (float f) { mRad *= f; return *this; }
 		Radian operator/ (float f) const { return Radian (mRad / f); }
 		Radian operator/ (float f) const { return Radian (mRad / f); }
 		Radian& operator/= (float f) { mRad /= f; return *this; }
 		Radian& operator/= (float f) { mRad /= f; return *this; }

+ 210 - 210
Source/BansheeUtility/Math/BsVector4.h

@@ -12,22 +12,22 @@ namespace bs
 	 */
 	 */
 
 
 	/** A four dimensional vector. */
 	/** A four dimensional vector. */
-    class BS_UTILITY_EXPORT Vector4
-    {
-    public:
-        float x, y, z, w;
+	class BS_UTILITY_EXPORT Vector4
+	{
+	public:
+		float x, y, z, w;
 
 
-    public:
+	public:
 		Vector4()
 		Vector4()
 		{ }
 		{ }
 
 
-        Vector4(BS_ZERO zero)
+		Vector4(BS_ZERO zero)
 			:x(0.0f), y(0.0f), z(0.0f), w(0.0f)
 			:x(0.0f), y(0.0f), z(0.0f), w(0.0f)
-        { }
+		{ }
 
 
-        Vector4(float x, float y, float z, float w)
-            :x(x), y(y), z(z), w(w)
-        { }
+		Vector4(float x, float y, float z, float w)
+			:x(x), y(y), z(z), w(w)
+		{ }
 
 
 		explicit Vector4(const Vector3& vec, float w = 0.0f)
 		explicit Vector4(const Vector3& vec, float w = 0.0f)
 			:x(vec.x), y(vec.y), z(vec.z), w(w)
 			:x(vec.x), y(vec.y), z(vec.z), w(w)
@@ -43,18 +43,18 @@ namespace bs
 		}
 		}
 	
 	
 		float operator[] (UINT32 i) const
 		float operator[] (UINT32 i) const
-        {
-            assert (i < 4);
+		{
+			assert (i < 4);
 
 
-            return *(&x+i);
-        }
+			return *(&x+i);
+		}
 
 
 		float& operator[] (UINT32 i)
 		float& operator[] (UINT32 i)
-        {
-            assert(i < 4);
+		{
+			assert(i < 4);
 
 
-            return *(&x+i);
-        }
+			return *(&x+i);
+		}
 
 
 		/** Pointer accessor for direct copying. */
 		/** Pointer accessor for direct copying. */
 		float* ptr()
 		float* ptr()
@@ -68,15 +68,15 @@ namespace bs
 			return &x;
 			return &x;
 		}
 		}
 
 
-        Vector4& operator= (const Vector4& rhs)
-        {
-            x = rhs.x;
-            y = rhs.y;
-            z = rhs.z;
-            w = rhs.w;
+		Vector4& operator= (const Vector4& rhs)
+		{
+			x = rhs.x;
+			y = rhs.y;
+			z = rhs.z;
+			w = rhs.w;
 
 
-            return *this;
-        }
+			return *this;
+		}
 
 
 		Vector4& operator= (float rhs)
 		Vector4& operator= (float rhs)
 		{
 		{
@@ -88,194 +88,194 @@ namespace bs
 			return *this;
 			return *this;
 		}
 		}
 
 
-        bool operator== (const Vector4& rhs) const
-        {
-            return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
-        }
-
-        bool operator!= (const Vector4& rhs) const
-        {
-            return (x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w);
-        }
-
-        Vector4& operator= (const Vector3& rhs)
-        {
-            x = rhs.x;
-            y = rhs.y;
-            z = rhs.z;
-            w = 1.0f;
-
-            return *this;
-        }
-
-        Vector4 operator+ (const Vector4& rhs) const
-        {
-            return Vector4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w);
-        }
-
-        Vector4 operator- (const Vector4& rhs) const
-        {
-            return Vector4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w);
-        }
-
-        Vector4 operator* (float rhs) const
-        {
-            return Vector4(x * rhs, y * rhs, z * rhs, w * rhs);
-        }
-
-        Vector4 operator* (const Vector4& rhs) const
-        {
-            return Vector4(rhs.x * x, rhs.y * y, rhs.z * z, rhs.w * w);
-        }
-
-        Vector4 operator/ (float rhs) const
-        {
-            assert(rhs != 0.0f);
-
-            float inv = 1.0f / rhs;
-            return Vector4(x * inv, y * inv, z * inv, w * inv);
-        }
-
-        Vector4 operator/ (const Vector4& rhs) const
-        {
-            return Vector4(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w);
-        }
-
-        const Vector4& operator+ () const
-        {
-            return *this;
-        }
-
-        Vector4 operator- () const
-        {
-            return Vector4(-x, -y, -z, -w);
-        }
-
-        friend Vector4 operator* (float lhs, const Vector4& rhs)
-        {
-            return Vector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
-        }
-
-        friend Vector4 operator/ (float lhs, const Vector4& rhs)
-        {
-            return Vector4(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z, lhs / rhs.w);
-        }
-
-        friend Vector4 operator+ (const Vector4& lhs, float rhs)
-        {
-            return Vector4(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs);
-        }
-
-        friend Vector4 operator+ (float lhs, const Vector4& rhs)
-        {
-            return Vector4(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z, lhs + rhs.w);
-        }
-
-        friend Vector4 operator- (const Vector4& lhs, float rhs)
-        {
-            return Vector4(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs);
-        }
-
-        friend Vector4 operator- (float lhs, Vector4& rhs)
-        {
-            return Vector4(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z, lhs - rhs.w);
-        }
-
-        Vector4& operator+= (const Vector4& rhs)
-        {
-            x += rhs.x;
-            y += rhs.y;
-            z += rhs.z;
-            w += rhs.w;
-
-            return *this;
-        }
-
-        Vector4& operator-= (const Vector4& rhs)
-        {
-            x -= rhs.x;
-            y -= rhs.y;
-            z -= rhs.z;
-            w -= rhs.w;
-
-            return *this;
-        }
-
-        Vector4& operator*= (float rhs)
-        {
-            x *= rhs;
-            y *= rhs;
-            z *= rhs;
-            w *= rhs;
-
-            return *this;
-        }
-
-        Vector4& operator+= (float rhs)
-        {
-            x += rhs;
-            y += rhs;
-            z += rhs;
-            w += rhs;
-
-            return *this;
-        }
-
-        Vector4& operator-= (float rhs)
-        {
-            x -= rhs;
-            y -= rhs;
-            z -= rhs;
-            w -= rhs;
-
-            return *this;
-        }
-
-        Vector4& operator*= (Vector4& rhs)
-        {
-            x *= rhs.x;
-            y *= rhs.y;
-            z *= rhs.z;
-            w *= rhs.w;
-
-            return *this;
-        }
-
-        Vector4& operator/= (float rhs)
-        {
-            assert(rhs != 0.0f);
-
-            float inv = 1.0f / rhs;
-
-            x *= inv;
-            y *= inv;
-            z *= inv;
-            w *= inv;
-
-            return *this;
-        }
-
-        Vector4& operator/= (const Vector4& rhs)
-        {
-            x /= rhs.x;
-            y /= rhs.y;
-            z /= rhs.z;
-            w /= rhs.w;
-
-            return *this;
-        }
-
-        /** Calculates the dot (scalar) product of this vector with another. */
-        float dot(const Vector4& vec) const
-        {
-            return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
-        }
+		bool operator== (const Vector4& rhs) const
+		{
+			return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
+		}
+
+		bool operator!= (const Vector4& rhs) const
+		{
+			return (x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w);
+		}
+
+		Vector4& operator= (const Vector3& rhs)
+		{
+			x = rhs.x;
+			y = rhs.y;
+			z = rhs.z;
+			w = 1.0f;
+
+			return *this;
+		}
+
+		Vector4 operator+ (const Vector4& rhs) const
+		{
+			return Vector4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w);
+		}
+
+		Vector4 operator- (const Vector4& rhs) const
+		{
+			return Vector4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w);
+		}
+
+		Vector4 operator* (float rhs) const
+		{
+			return Vector4(x * rhs, y * rhs, z * rhs, w * rhs);
+		}
+
+		Vector4 operator* (const Vector4& rhs) const
+		{
+			return Vector4(rhs.x * x, rhs.y * y, rhs.z * z, rhs.w * w);
+		}
+
+		Vector4 operator/ (float rhs) const
+		{
+			assert(rhs != 0.0f);
+
+			float inv = 1.0f / rhs;
+			return Vector4(x * inv, y * inv, z * inv, w * inv);
+		}
+
+		Vector4 operator/ (const Vector4& rhs) const
+		{
+			return Vector4(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w);
+		}
+
+		const Vector4& operator+ () const
+		{
+			return *this;
+		}
+
+		Vector4 operator- () const
+		{
+			return Vector4(-x, -y, -z, -w);
+		}
+
+		friend Vector4 operator* (float lhs, const Vector4& rhs)
+		{
+			return Vector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
+		}
+
+		friend Vector4 operator/ (float lhs, const Vector4& rhs)
+		{
+			return Vector4(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z, lhs / rhs.w);
+		}
+
+		friend Vector4 operator+ (const Vector4& lhs, float rhs)
+		{
+			return Vector4(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs);
+		}
+
+		friend Vector4 operator+ (float lhs, const Vector4& rhs)
+		{
+			return Vector4(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z, lhs + rhs.w);
+		}
+
+		friend Vector4 operator- (const Vector4& lhs, float rhs)
+		{
+			return Vector4(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs);
+		}
+
+		friend Vector4 operator- (float lhs, Vector4& rhs)
+		{
+			return Vector4(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z, lhs - rhs.w);
+		}
+
+		Vector4& operator+= (const Vector4& rhs)
+		{
+			x += rhs.x;
+			y += rhs.y;
+			z += rhs.z;
+			w += rhs.w;
+
+			return *this;
+		}
+
+		Vector4& operator-= (const Vector4& rhs)
+		{
+			x -= rhs.x;
+			y -= rhs.y;
+			z -= rhs.z;
+			w -= rhs.w;
+
+			return *this;
+		}
+
+		Vector4& operator*= (float rhs)
+		{
+			x *= rhs;
+			y *= rhs;
+			z *= rhs;
+			w *= rhs;
+
+			return *this;
+		}
+
+		Vector4& operator+= (float rhs)
+		{
+			x += rhs;
+			y += rhs;
+			z += rhs;
+			w += rhs;
+
+			return *this;
+		}
+
+		Vector4& operator-= (float rhs)
+		{
+			x -= rhs;
+			y -= rhs;
+			z -= rhs;
+			w -= rhs;
+
+			return *this;
+		}
+
+		Vector4& operator*= (Vector4& rhs)
+		{
+			x *= rhs.x;
+			y *= rhs.y;
+			z *= rhs.z;
+			w *= rhs.w;
+
+			return *this;
+		}
+
+		Vector4& operator/= (float rhs)
+		{
+			assert(rhs != 0.0f);
+
+			float inv = 1.0f / rhs;
+
+			x *= inv;
+			y *= inv;
+			z *= inv;
+			w *= inv;
+
+			return *this;
+		}
+
+		Vector4& operator/= (const Vector4& rhs)
+		{
+			x /= rhs.x;
+			y /= rhs.y;
+			z /= rhs.z;
+			w /= rhs.w;
+
+			return *this;
+		}
+
+		/** Calculates the dot (scalar) product of this vector with another. */
+		float dot(const Vector4& vec) const
+		{
+			return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
+		}
 
 
 		/** Checks are any of the vector components NaN. */
 		/** Checks are any of the vector components NaN. */
 		inline bool isNaN() const;
 		inline bool isNaN() const;
 
 
-        static const Vector4 ZERO;
-    };
+		static const Vector4 ZERO;
+	};
 
 
 	/** @} */
 	/** @} */
 
 

+ 13 - 13
Source/MBansheeEngine/Math/AABox.cs

@@ -12,13 +12,13 @@ namespace BansheeEngine
     /// Axis aligned box represented by minimum and maximum point.
     /// Axis aligned box represented by minimum and maximum point.
     /// </summary>
     /// </summary>
     [StructLayout(LayoutKind.Sequential), SerializeObject]
     [StructLayout(LayoutKind.Sequential), SerializeObject]
-	public struct AABox // Note: Must match C++ class AABox
-	{
+    public struct AABox // Note: Must match C++ class AABox
+    {
         [SerializeField]
         [SerializeField]
         private Vector3 minimum;
         private Vector3 minimum;
 
 
         [SerializeField]
         [SerializeField]
-		private Vector3 maximum;
+        private Vector3 maximum;
 
 
         /// <summary>
         /// <summary>
         /// Corner of the box with minimum values (opposite to maximum corner).
         /// Corner of the box with minimum values (opposite to maximum corner).
@@ -46,21 +46,21 @@ namespace BansheeEngine
             get 
             get 
             { 		
             { 		
                 return new Vector3((maximum.x + minimum.x) * 0.5f,
                 return new Vector3((maximum.x + minimum.x) * 0.5f,
-			            (maximum.y + minimum.y) * 0.5f,
-			            (maximum.z + minimum.z) * 0.5f);
+                        (maximum.y + minimum.y) * 0.5f,
+                        (maximum.z + minimum.z) * 0.5f);
             }
             }
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Returns the width, height and depth of the box.
         /// Returns the width, height and depth of the box.
         /// </summary>
         /// </summary>
-	    public Vector3 Size
-	    {
-	        get
-	        {
-	            return maximum - minimum;
-	        }
-	    }
+        public Vector3 Size
+        {
+            get
+            {
+                return maximum - minimum;
+            }
+        }
 
 
         /// <summary>
         /// <summary>
         /// Creates a new axis aligned box.
         /// Creates a new axis aligned box.
@@ -100,7 +100,7 @@ namespace BansheeEngine
         {
         {
             return "Min: " + minimum + ". Max: " + maximum;
             return "Min: " + minimum + ". Max: " + maximum;
         }
         }
-	};
+    };
 
 
     /** @} */
     /** @} */
 }
 }