2
0
Эх сурвалжийг харах

Scene refactoring. WONT COMPILE

Panagiotis Christopoulos Charitos 12 жил өмнө
parent
commit
5741041905

+ 16 - 25
include/anki/scene/Frustumable.h → include/anki/scene/FrustumComponent.h

@@ -1,5 +1,5 @@
-#ifndef ANKI_SCENE_FRUSTUMABLE_H
-#define ANKI_SCENE_FRUSTUMABLE_H
+#ifndef ANKI_SCENE_FRUSTUM_COMPONENT_H
+#define ANKI_SCENE_FRUSTUM_COMPONENT_H
 
 
 #include "anki/collision/Frustum.h"
 #include "anki/collision/Frustum.h"
 #include "anki/scene/SpatialComponent.h"
 #include "anki/scene/SpatialComponent.h"
@@ -8,27 +8,25 @@
 namespace anki {
 namespace anki {
 
 
 // Forward
 // Forward
-class SectorGroup;
-class Sector;
 struct VisibilityTestResults;
 struct VisibilityTestResults;
 
 
 /// @addtogroup Scene
 /// @addtogroup Scene
 /// @{
 /// @{
 
 
-/// Frustumable interface for scene nodes
-class Frustumable
+/// Frustum component interface for scene nodes. Useful for nodes that are 
+/// frustums like cameras and lights
+class FrustumComponent
 {
 {
-	friend class SectorGroup;
-	friend class Sector;
-
 public:
 public:
 	/// @name Constructors
 	/// @name Constructors
 	/// @{
 	/// @{
 
 
 	/// Pass the frustum here so we can avoid the virtuals
 	/// Pass the frustum here so we can avoid the virtuals
-	Frustumable(Frustum* fr)
+	FrustumComponent(Frustum* fr)
 		: frustum(fr)
 		: frustum(fr)
-	{}
+	{
+		ANKI_ASSERT(frustum);
+	}
 	/// @}
 	/// @}
 
 
 	/// @name Accessors
 	/// @name Accessors
@@ -38,7 +36,7 @@ public:
 		return *frustum;
 		return *frustum;
 	}
 	}
 
 
-	Timestamp getFrustumableTimestamp() const
+	Timestamp getFrustumComponentTimestamp() const
 	{
 	{
 		return timestamp;
 		return timestamp;
 	}
 	}
@@ -58,29 +56,23 @@ public:
 		return viewProjectionMat;
 		return viewProjectionMat;
 	}
 	}
 
 
-	/// Call this after the tests. Before it will point to junk
-	const VisibilityTestResults& getVisibilityTestResults() const
-	{
-		ANKI_ASSERT(visible != nullptr);
-		return *visible;
-	}
-
 	/// Get the origin for sorting and visibility tests
 	/// Get the origin for sorting and visibility tests
-	virtual const Vec3& getFrustumableOrigin() const = 0;
+	virtual const Vec3& getFrustumComponentOrigin() const = 0;
 
 
 	void setVisibilityTestResults(VisibilityTestResults* visible_)
 	void setVisibilityTestResults(VisibilityTestResults* visible_)
 	{
 	{
 		ANKI_ASSERT(visible == nullptr);
 		ANKI_ASSERT(visible == nullptr);
 		visible = visible_;
 		visible = visible_;
 	}
 	}
-	VisibilityTestResults* getVisibilityTestResults()
+	/// Call this after the tests. Before it will point to junk
+	VisibilityTestResults& getVisibilityTestResults()
 	{
 	{
-		ANKI_ASSERT(visible);
-		return visible;
+		ANKI_ASSERT(visible != nullptr);
+		return *visible;
 	}
 	}
 	/// @}
 	/// @}
 
 
-	void frustumableMarkUpdated()
+	void frustumMarkForUpdate()
 	{
 	{
 		timestamp = getGlobTimestamp();
 		timestamp = getGlobTimestamp();
 	}
 	}
@@ -115,7 +107,6 @@ private:
 	/// frame and before any visibility tests are run
 	/// frame and before any visibility tests are run
 	VisibilityTestResults* visible = nullptr;
 	VisibilityTestResults* visible = nullptr;
 };
 };
-
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 53 - 45
include/anki/scene/RenderComponent.h

@@ -10,8 +10,6 @@
 
 
 namespace anki {
 namespace anki {
 
 
-class SceneNode;
-
 /// @addtogroup Scene
 /// @addtogroup Scene
 /// @{
 /// @{
 
 
@@ -30,31 +28,31 @@ enum BuildinMaterialVariableId
 };
 };
 
 
 // Forward
 // Forward
-class RenderingComponentVariable;
+class RenderComponentVariable;
 
 
 template<typename T>
 template<typename T>
-class RenderingComponentVariableTemplate;
+class RenderComponentVariableTemplate;
 
 
-/// RenderingComponent variable base. Its a visitable
+/// RenderComponent variable base. Its a visitable
 typedef VisitableCommonBase<
 typedef VisitableCommonBase<
-	RenderingComponentVariable, //< The base
-	RenderingComponentVariableTemplate<F32>,
-	RenderingComponentVariableTemplate<Vec2>,
-	RenderingComponentVariableTemplate<Vec3>,
-	RenderingComponentVariableTemplate<Vec4>,
-	RenderingComponentVariableTemplate<Mat3>,
-	RenderingComponentVariableTemplate<Mat4>,
-	RenderingComponentVariableTemplate<TextureResourcePointer>>
-	RenderingComponentVariableVisitable;
+	RenderComponentVariable, //< The base
+	RenderComponentVariableTemplate<F32>,
+	RenderComponentVariableTemplate<Vec2>,
+	RenderComponentVariableTemplate<Vec3>,
+	RenderComponentVariableTemplate<Vec4>,
+	RenderComponentVariableTemplate<Mat3>,
+	RenderComponentVariableTemplate<Mat4>,
+	RenderComponentVariableTemplate<TextureResourcePointer>>
+	RenderComponentVariableVisitable;
 
 
 /// A wrapper on top of MaterialVariable
 /// A wrapper on top of MaterialVariable
-class RenderingComponentVariable: public RenderingComponentVariableVisitable
+class RenderComponentVariable: public RenderComponentVariableVisitable
 {
 {
 public:
 public:
-	typedef RenderingComponentVariableVisitable Base;
+	typedef RenderComponentVariableVisitable Base;
 
 
-	RenderingComponentVariable(const MaterialVariable* mvar_);
-	virtual ~RenderingComponentVariable();
+	RenderComponentVariable(const MaterialVariable* mvar_);
+	virtual ~RenderComponentVariable();
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
@@ -72,9 +70,9 @@ public:
 	const T* getValues() const
 	const T* getValues() const
 	{
 	{
 		ANKI_ASSERT(
 		ANKI_ASSERT(
-			Base::getVariadicTypeId<RenderingComponentVariableTemplate<T>>()
+			Base::getVariadicTypeId<RenderComponentVariableTemplate<T>>()
 			== Base::getVisitableTypeId());
 			== Base::getVisitableTypeId());
-		return static_cast<const RenderingComponentVariableTemplate<T>*>(
+		return static_cast<const RenderComponentVariableTemplate<T>*>(
 			this)->get();
 			this)->get();
 	}
 	}
 
 
@@ -83,9 +81,9 @@ public:
 	void setValues(const T* values, U32 size)
 	void setValues(const T* values, U32 size)
 	{
 	{
 		ANKI_ASSERT(
 		ANKI_ASSERT(
-			Base::getVariadicTypeId<RenderingComponentVariableTemplate<T>>()
+			Base::getVariadicTypeId<RenderComponentVariableTemplate<T>>()
 			== Base::getVisitableTypeId());
 			== Base::getVisitableTypeId());
-		static_cast<RenderingComponentVariableTemplate<T>*>(this)->set(
+		static_cast<RenderComponentVariableTemplate<T>*>(this)->set(
 			values, size);
 			values, size);
 	}
 	}
 
 
@@ -101,6 +99,8 @@ public:
 		return mvar->findShaderProgramUniformVariable(key);
 		return mvar->findShaderProgramUniformVariable(key);
 	}
 	}
 
 
+	virtual void cleanup(SceneAllocator<U8> alloc) = 0;
+
 protected:
 protected:
 	const MaterialVariable* mvar = nullptr;
 	const MaterialVariable* mvar = nullptr;
 
 
@@ -108,25 +108,22 @@ private:
 	BuildinMaterialVariableId buildinId;
 	BuildinMaterialVariableId buildinId;
 };
 };
 
 
-/// RenderingComponent variable
+/// RenderComponent variable
 template<typename T>
 template<typename T>
-class RenderingComponentVariableTemplate: public RenderingComponentVariable
+class RenderComponentVariableTemplate: public RenderComponentVariable
 {
 {
 public:
 public:
 	typedef T Type;
 	typedef T Type;
 
 
-	RenderingComponentVariableTemplate(const MaterialVariable* mvar_)
-		: RenderingComponentVariable(mvar_)
+	RenderComponentVariableTemplate(const MaterialVariable* mvar_)
+		: RenderComponentVariable(mvar_)
 	{
 	{
 		setupVisitable(this);
 		setupVisitable(this);
 	}
 	}
 
 
-	~RenderingComponentVariableTemplate()
+	~RenderComponentVariableTemplate()
 	{
 	{
-		if(copy)
-		{
-			propperDelete(copy);
-		}
+		ANKI_ASSERT(copy == nullptr && "Forgot to delete");
 	}
 	}
 
 
 	const T* get() const
 	const T* get() const
@@ -136,44 +133,55 @@ public:
 		return (copy) ? copy : mvar->getValues<T>();
 		return (copy) ? copy : mvar->getValues<T>();
 	}
 	}
 
 
-	void set(const T* values, U32 size)
+	void set(const T* values, U32 size, SceneAllocator<U8> alloc)
 	{
 	{
 		ANKI_ASSERT(size <= mvar->getArraySize());
 		ANKI_ASSERT(size <= mvar->getArraySize());
 		if(copy == nullptr)
 		if(copy == nullptr)
 		{
 		{
-			copy = new T[mvar->getArraySize()];
+			copy = alloc.newArray<T>(getArraySize());
 		}
 		}
 		memcpy(copy, values, sizeof(T) * size);
 		memcpy(copy, values, sizeof(T) * size);
 	}
 	}
+
+	/// Call that manualy
+	void cleanup(SceneAllocator<U8> alloc)
+	{
+		if(copy)
+		{
+			alloc.deleteArray(copy, getArraySize());
+			copy = nullptr;
+		}
+	}
+
 private:
 private:
 	T* copy = nullptr;
 	T* copy = nullptr;
 };
 };
 
 
-/// RenderingComponent interface. Implemented by renderable scene nodes
-class RenderingComponent
+/// RenderComponent interface. Implemented by renderable scene nodes
+class RenderComponent
 {
 {
 public:
 public:
-	typedef SceneVector<RenderingComponentVariable*> Variables;
+	typedef SceneVector<RenderComponentVariable*> Variables;
 
 
 	/// @param node Pass note to steal it's allocator
 	/// @param node Pass note to steal it's allocator
-	RenderingComponent(SceneNode* node);
+	RenderComponent(SceneNode* node);
 
 
-	virtual ~RenderingComponent();
+	virtual ~RenderComponent();
 
 
 	/// Access to VAOs
 	/// Access to VAOs
-	virtual const ModelPatchBase& getRenderingComponentModelPatchBase() = 0;
+	virtual const ModelPatchBase& getRenderComponentModelPatchBase() = 0;
 
 
 	/// Access the material
 	/// Access the material
-	virtual const Material& getRenderingComponentMaterial() = 0;
+	virtual const Material& getRenderComponentMaterial() = 0;
 
 
 	/// Information for movables. It's actualy an array of transformations.
 	/// Information for movables. It's actualy an array of transformations.
-	virtual const Transform* getRenderingComponentWorldTransforms()
+	virtual const Transform* getRenderComponentWorldTransforms()
 	{
 	{
 		return nullptr;
 		return nullptr;
 	}
 	}
 
 
 	/// Number of instances. If greater than 1 then it's instanced
 	/// Number of instances. If greater than 1 then it's instanced
-	virtual U32 getRenderingComponentInstancesCount()
+	virtual U32 getRenderComponentInstancesCount()
 	{
 	{
 		return 1;
 		return 1;
 	}
 	}
@@ -192,7 +200,7 @@ public:
 
 
 	/// Iterate variables using a lambda
 	/// Iterate variables using a lambda
 	template<typename Func>
 	template<typename Func>
-	void iterateRenderingComponentVariables(Func func)
+	void iterateRenderComponentVariables(Func func)
 	{
 	{
 		for(auto var : vars)
 		for(auto var : vars)
 		{
 		{
@@ -202,7 +210,7 @@ public:
 
 
 	U32 getSubMeshesCount()
 	U32 getSubMeshesCount()
 	{
 	{
-		return getRenderingComponentModelPatchBase().getSubMeshesCount();
+		return getRenderComponentModelPatchBase().getSubMeshesCount();
 	}
 	}
 
 
 	/// Reset on frame start
 	/// Reset on frame start
@@ -211,7 +219,7 @@ public:
 
 
 protected:
 protected:
 	/// The derived class needs to call that
 	/// The derived class needs to call that
-	void init(PropertyMap& pmap);
+	void init();
 
 
 private:
 private:
 	Variables vars;
 	Variables vars;

+ 2 - 2
include/anki/util/Allocator.h

@@ -195,7 +195,7 @@ public:
 		{
 		{
 			alloc.destroy(&x[i]);
 			alloc.destroy(&x[i]);
 		}
 		}
-		alloc.deallocate(x);
+		alloc.deallocate(x, n);
 	}
 	}
 };
 };
 
 
@@ -453,7 +453,7 @@ public:
 		{
 		{
 			alloc.destroy(&x[i]);
 			alloc.destroy(&x[i]);
 		}
 		}
-		alloc.deallocate(x);
+		alloc.deallocate(x, n);
 	}
 	}
 
 
 private:
 private:

+ 7 - 0
include/anki/util/Functions.h

@@ -40,6 +40,13 @@ Type getAlignedRoundUp(PtrSize alignment, Type value)
 	return (Type)v;
 	return (Type)v;
 }
 }
 
 
+/// Check if a number is aligned
+template<typename Type>
+bool isAligned(PtrSize alignment, Type value)
+{
+	return ((PtrSize)value % alignment) == 0;
+}
+
 /// Get the size in bytes of a vector
 /// Get the size in bytes of a vector
 template<typename Vec>
 template<typename Vec>
 inline PtrSize getVectorSizeInBytes(const Vec& v)
 inline PtrSize getVectorSizeInBytes(const Vec& v)

+ 4 - 177
include/anki/util/Memory.h

@@ -87,184 +87,11 @@ private:
 	std::atomic<U8*> top = {nullptr};
 	std::atomic<U8*> top = {nullptr};
 };
 };
 
 
-/// Allocate a new object and call it's constructor
-template<typename Type, typename Alloc = Allocator<Type>, typename... Args>
-Type* newInstance(Alloc alloc, Args&&... args)
-{
-	typename Alloc::template rebind<Type>::other allocc(alloc);
-
-	Type* x = allocc.allocate(1);
-	allocc.construct(x, std::forward<Args>(args)...);
-	return x;
-}
-
-/// XXX
-template<typename Type, typename Alloc = Allocator<Type>, typename... Args>
-Type* newArray(PtrSize n, Alloc alloc, Args&&... args)
-{
-	typename Alloc::template rebind<Type>::other allocc(alloc);
-
-	Type* x = allocc.allocate(n);
-	allocc.construct(x, std::forward<Args>(args)...);
-	return x;
-}
-
-/// XXX
-template<typename Type, typename Alloc = Allocator<Type>>
-void deleteObject(Alloc alloc, Type* x)
-{
-	typename Alloc::template rebind<Type>::other allocc(alloc);
-
-	allocc.destroy(x);
-	allocc.deallocate(x, 1);
-}
-
-/// Functior that imitates the new operator. The functior allocates memory for
-/// a number of elements and calls their constructor. The interesting thing is
-/// that if the elements size is >1 then it allocates size bigger than the
-/// required. The extra chunk is a number that will be used in
-/// deleteObjectArray to identify the number of elements that were allocated
-template<typename T, typename Alloc = Allocator<T>>
-struct New
-{
-	template<typename... Args>
-	T* operator()(PtrSize n, Alloc alloc, Args&&... args)
-	{
-		ANKI_ASSERT(n != 0);
-		T* out;
-
-		// If the number of elements is then do a simple allocaton
-		if(n == 1)
-		{
-			out = alloc.allocate(n);
-		}
-		else
-		{
-			// Allocate a memory block that includes the array size
-			typedef typename Alloc::template rebind<U8>::other CharAlloc;
-			CharAlloc charAlloc(alloc);
-			U8* mem = charAlloc.allocate(sizeof(PtrSize) + n * sizeof(T));
-
-			// Set the size of the block
-			*(PtrSize*)mem = n;
-
-			// Set the output address
-			out = (T*)(mem + sizeof(PtrSize));
-		}
-
-		// Call the constuctors
-		for(PtrSize i = 0; i < n; i++)
-		{
-			alloc.construct(&out[i], std::forward<Args>(args)...);
-		}
-
-		// Return result
-		return out;
-	}
-};
-
-/// Function that imitates the delete operator
-template<typename T, typename Alloc = Allocator<T>>
-struct Delete
-{
-	Alloc alloc;
-
-	Delete(const Alloc& alloc_ = Alloc())
-		: alloc(alloc_)
-	{}
-
-	void operator()(void* ptr)
-	{
-		T* p = (T*)ptr;
-
-		// Make sure the type is defined
-		typedef U8 TypeMustBeComplete[sizeof(T) ? 1 : -1];
-		(void) sizeof(TypeMustBeComplete);
-
-		if(p)
-		{
-			// Call the destructor
-			alloc.destroy(p);
-
-			// Deallocate
-			alloc.deallocate(p, 1);
-		}
-	}
-};
-
-/// Function that imitates the delete[] operator
-template<typename T, typename Alloc = Allocator<T>>
-struct DeleteArray
-{
-	Alloc alloc;
-
-	DeleteArray(const Alloc& alloc_ = Alloc())
-		: alloc(alloc_)
-	{}
-
-	void operator()(void* ptr)
-	{
-		// Make sure the type is defined
-		typedef U8 TypeMustBeComplete[sizeof(T) ? 1 : -1];
-		(void) sizeof(TypeMustBeComplete);
-
-		T* p = (T*)ptr;
-
-		if(p)
-		{
-			// Get the allocated block
-			U8* block = (U8*)(p) - sizeof(PtrSize);
-
-			// Get number of elements
-			const PtrSize n = *(PtrSize*)block;
-
-			// Call the destructors
-			for(PtrSize i = 0; i < n; i++)
-			{
-				alloc.destroy(&p[i]);
-			}
-
-			// Deallocate the block
-			typename Alloc::template rebind<U8>::other allocc(alloc);
-			allocc.deallocate(block, n * sizeof(T) + sizeof(PtrSize));
-
-			// nullify
-			ptr = nullptr;
-		}
-	}
-};
-
-/// Allocate memory using an allocator
-#define ANKI_NEW(Type_, alloc_, ...) \
-	New<Type_, decltype(alloc_)::rebind<Type_>::other>{}( \
-		1, alloc_, ## __VA_ARGS__)
-
-/// Allocate memory using an allocator
-#define ANKI_NEW_0(Type_, alloc_) \
-	New<Type_, decltype(alloc_)::rebind<Type_>::other>{}( \
-		1, alloc_)
-
-/// Allocate memory using an allocator
-#define ANKI_NEW_ARRAY(Type_, alloc_, n_, ...) \
-	New<Type_, decltype(alloc_)::rebind<Type_>::other>{}( \
-		n_, alloc_, ## __VA_ARGS__)
-
-/// Allocate memory using an allocator
-#define ANKI_NEW_ARRAY_0(Type_, alloc_, n_) \
-	New<Type_, decltype(alloc_)::rebind<Type_>::other>{}( \
-		n_, alloc_)
-
-/// Delete memory allocated by #ANKI_NEW
-#define ANKI_DELETE(ptr_, alloc_) \
-	Delete<RemovePointer<decltype(ptr_)>::Type, \
-		decltype(alloc_)::rebind<RemovePointer<decltype(ptr_)>::Type>::other \
-		>{alloc_}(ptr_);
+/// Allocate aligned memory
+extern void* mallocAligned(PtrSize size, PtrSize alignmentBytes);
 
 
-/// Delete memory allocated by #ANKI_NEW_ARRAY
-#define ANKI_DELETE_ARRAY(ptr_, alloc_) \
-	DeleteArray<RemovePointer<decltype(ptr_)>::Type, \
-		decltype(alloc_)::rebind<RemovePointer<decltype(ptr_)>::Type>::other \
-		>{alloc_}(ptr_);
+/// Free aligned memory
+extern void freeAligned(void* ptr);
 
 
 /// @}
 /// @}
 /// @}
 /// @}

+ 30 - 39
src/scene/RenderComponent.cpp

@@ -1,4 +1,4 @@
-#include "anki/scene/RenderingComponent.h"
+#include "anki/scene/RenderComponent.h"
 #include "anki/scene/SceneNode.h"
 #include "anki/scene/SceneNode.h"
 #include "anki/resource/TextureResource.h"
 #include "anki/resource/TextureResource.h"
 #include "anki/gl/ShaderProgram.h"
 #include "anki/gl/ShaderProgram.h"
@@ -10,20 +10,21 @@ namespace anki {
 // Misc                                                                        =
 // Misc                                                                        =
 //==============================================================================
 //==============================================================================
 
 
-/// Create a new RenderingComponentVariable given a MaterialVariable
-struct CreateNewRenderingComponentVariableVisitor
+/// Create a new RenderComponentVariable given a MaterialVariable
+struct CreateNewRenderComponentVariableVisitor
 {
 {
 	const MaterialVariable* mvar = nullptr;
 	const MaterialVariable* mvar = nullptr;
-	PropertyMap* pmap = nullptr;
-	RenderingComponent::RenderingComponentVariables* vars = nullptr;
+	RenderComponent::Variables* vars = nullptr;
 
 
 	template<typename TMaterialVariableTemplate>
 	template<typename TMaterialVariableTemplate>
 	void visit(const TMaterialVariableTemplate&) const
 	void visit(const TMaterialVariableTemplate&) const
 	{
 	{
 		typedef typename TMaterialVariableTemplate::Type Type;
 		typedef typename TMaterialVariableTemplate::Type Type;
 
 
-		RenderingComponentVariableTemplate<Type>* rvar =
-			new RenderingComponentVariableTemplate<Type>(mvar);
+		SceneAllocator<U8> alloc = vars->get_allocator();
+
+		RenderComponentVariableTemplate<Type>* rvar =
+			alloc.newInstance<RenderComponentVariableTemplate<Type>>(mvar);
 
 
 		vars->push_back(rvar);
 		vars->push_back(rvar);
 	}
 	}
@@ -40,11 +41,11 @@ static Array<const char*, BMV_COUNT - 1> buildinNames = {{
 	"msDepthMap"}};
 	"msDepthMap"}};
 
 
 //==============================================================================
 //==============================================================================
-// RenderingComponentVariable                                                  =
+// RenderComponentVariable                                                     =
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-RenderingComponentVariable::RenderingComponentVariable(
+RenderComponentVariable::RenderComponentVariable(
 	const MaterialVariable* mvar_)
 	const MaterialVariable* mvar_)
 	: mvar(mvar_)
 	: mvar(mvar_)
 {
 {
@@ -72,35 +73,37 @@ RenderingComponentVariable::RenderingComponentVariable(
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-RenderingComponentVariable::~RenderingComponentVariable()
+RenderComponentVariable::~RenderComponentVariable()
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================
-// RenderingComponent                                                          =
+// RenderComponent                                                             =
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-RenderingComponent::RenderingComponent(SceneNode* node)
+RenderComponent::RenderComponent(SceneNode* node)
 	: vars(node->getSceneAllocator())
 	: vars(node->getSceneAllocator())
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================
-RenderingComponent::~RenderingComponent()
+RenderComponent::~RenderComponent()
 {
 {
-	for(RenderingComponentVariable* var : vars)
+	SceneAllocator<U8> alloc = vars.get_allocator();
+
+	for(RenderComponentVariable* var : vars)
 	{
 	{
-		delete var;
+		var->cleanup(alloc);
+		alloc.deleteInstance(var);
 	}
 	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void RenderingComponent::init(PropertyMap& pmap)
+void RenderComponent::init()
 {
 {
-	const Material& mtl = getRenderingComponentMaterial();
+	const Material& mtl = getRenderComponentMaterial();
 
 
 	// Create the material variables using a visitor
 	// Create the material variables using a visitor
-	CreateNewRenderingComponentVariableVisitor vis;
-	vis.pmap = &pmap;
+	CreateNewRenderComponentVariableVisitor vis;
 	vis.vars = &vars;
 	vis.vars = &vars;
 
 
 	vars.reserve(mtl.getVariables().size());
 	vars.reserve(mtl.getVariables().size());
@@ -111,28 +114,16 @@ void RenderingComponent::init(PropertyMap& pmap)
 		mv->acceptVisitor(vis);
 		mv->acceptVisitor(vis);
 	}
 	}
 
 
-	// FUTURE if the material is simple (only viewprojection matrix and samlers)
-	// then use a common UBO. It will save the copying to the UBO and the 
-	// binding
-
-	// Init the UBO
-	const ShaderProgramUniformBlock* block = mtl.getCommonUniformBlock();
-
-	if(block)
-	{
-		ubo.create(block->getSize(), nullptr, GlObject::DOUBLE_OBJECT);
-	}
-
 	// Instancing sanity checks
 	// Instancing sanity checks
-	U32 instancesCount = getRenderingComponentInstancesCount();
-	const MaterialVariable* mv =
-		mtl.findVariableByName("instancingModelViewProjectionMatrices");
-
-	if(mv && mv->getAShaderProgramUniformVariable().getSize() < instancesCount)
+	U32 instancesCount = getRenderComponentInstancesCount();
+	iterateRenderComponentVariables([&](RenderComponentVariable& var)
 	{
 	{
-		throw ANKI_EXCEPTION("The renderable needs more instances that the "
-			"shader program can handle");
-	}
+		if(var.getArraySize() < instancesCount)
+		{
+			throw ANKI_EXCEPTION("The renderable needs more instances that "
+				"the shader program can handle");
+		}
+	});
 }
 }
 
 
 }  // end namespace anki
 }  // end namespace anki

+ 51 - 11
src/util/Memory.cpp

@@ -7,6 +7,10 @@
 
 
 namespace anki {
 namespace anki {
 
 
+//==============================================================================
+// StackMemoryPool                                                             =
+//==============================================================================
+
 //==============================================================================
 //==============================================================================
 struct MemoryBlockHeader
 struct MemoryBlockHeader
 {
 {
@@ -19,16 +23,16 @@ StackMemoryPool::StackMemoryPool(PtrSize size, U32 alignmentBytes_)
 		memsize(getAlignedRoundUp(alignmentBytes, size))
 		memsize(getAlignedRoundUp(alignmentBytes, size))
 {
 {
 	ANKI_ASSERT(memsize > 0);
 	ANKI_ASSERT(memsize > 0);
-	memory = (U8*)::malloc(memsize);
+	memory = (U8*)mallocAligned(memsize, alignmentBytes);
 
 
 	if(memory != nullptr)
 	if(memory != nullptr)
 	{
 	{
 		// Align allocated memory
 		// Align allocated memory
-		top = getAlignedRoundUp(alignmentBytes, memory);
+		top = memory;
 	}
 	}
 	else
 	else
 	{
 	{
-		throw ANKI_EXCEPTION("malloc() failed");
+		throw ANKI_EXCEPTION("Failed to allocate memory");
 	}
 	}
 }
 }
 
 
@@ -37,7 +41,7 @@ StackMemoryPool::~StackMemoryPool()
 {
 {
 	if(memory != nullptr)
 	if(memory != nullptr)
 	{
 	{
-		::free(memory);
+		freeAligned(memory);
 	}
 	}
 }
 }
 
 
@@ -46,7 +50,7 @@ StackMemoryPool& StackMemoryPool::operator=(StackMemoryPool&& other)
 {
 {
 	if(memory != nullptr)
 	if(memory != nullptr)
 	{
 	{
-		::free(memory);
+		freeAligned(memory);
 	}
 	}
 
 
 	memory = other.memory;
 	memory = other.memory;
@@ -73,10 +77,10 @@ void* StackMemoryPool::allocate(PtrSize size_) throw()
 	// memory is nullptr if moved
 	// memory is nullptr if moved
 	ANKI_ASSERT(memory != nullptr);
 	ANKI_ASSERT(memory != nullptr);
 
 
-	PtrSize memBlockSize = 
+	PtrSize headerSize = 
 		getAlignedRoundUp(alignmentBytes, sizeof(MemoryBlockHeader));
 		getAlignedRoundUp(alignmentBytes, sizeof(MemoryBlockHeader));
 	PtrSize size = 
 	PtrSize size = 
-		getAlignedRoundUp(alignmentBytes, size_ + memBlockSize);
+		getAlignedRoundUp(alignmentBytes, size_ + headerSize);
 
 
 	ANKI_ASSERT(size < std::numeric_limits<U32>::max() && "Too big allocation");
 	ANKI_ASSERT(size < std::numeric_limits<U32>::max() && "Too big allocation");
 
 
@@ -88,7 +92,7 @@ void* StackMemoryPool::allocate(PtrSize size_) throw()
 		((MemoryBlockHeader*)out)->size = size;
 		((MemoryBlockHeader*)out)->size = size;
 
 
 		// Set the correct output
 		// Set the correct output
-		out += memBlockSize;
+		out += headerSize;
 	}
 	}
 	else
 	else
 	{
 	{
@@ -103,12 +107,12 @@ void* StackMemoryPool::allocate(PtrSize size_) throw()
 Bool StackMemoryPool::free(void* ptr) throw()
 Bool StackMemoryPool::free(void* ptr) throw()
 {
 {
 	// memory is nullptr if moved
 	// memory is nullptr if moved
-	ANKI_ASSERT(memory != nullptr);
+	ANKI_ASSERT(memory != nullptr && ptr != nullptr);
 
 
 	// Correct the p
 	// Correct the p
-	PtrSize memBlockSize = 
+	PtrSize headerSize = 
 		getAlignedRoundUp(alignmentBytes, sizeof(MemoryBlockHeader));
 		getAlignedRoundUp(alignmentBytes, sizeof(MemoryBlockHeader));
-	U8* realptr = (U8*)ptr - memBlockSize;
+	U8* realptr = (U8*)ptr - headerSize;
 
 
 	// realptr should be inside the pool's preallocated memory
 	// realptr should be inside the pool's preallocated memory
 	ANKI_ASSERT(realptr >= memory && realptr < memory + memsize);
 	ANKI_ASSERT(realptr >= memory && realptr < memory + memsize);
@@ -146,4 +150,40 @@ void StackMemoryPool::reset()
 	top = getAlignedRoundUp(alignmentBytes, memory);
 	top = getAlignedRoundUp(alignmentBytes, memory);
 }
 }
 
 
+//==============================================================================
+// Other                                                                       =
+//==============================================================================
+
+//==============================================================================
+void* mallocAligned(PtrSize size, PtrSize alignmentBytes)
+{
+#if ANKI_POSIX
+	void* out;
+	int err = posix_memalign(&out, alignmentBytes, size);
+
+	if(!err)
+	{
+		// Make sure it's aligned
+		ANKI_ASSERT(isAligned(alignmentBytes, out));
+		return out;
+	}
+	else
+	{
+		return nullptr;
+	}
+#else
+#	error "Unimplemented"
+#endif
+}
+
+//==============================================================================
+void freeAligned(void* ptr)
+{
+#if ANKI_POSIX
+	::free(ptr);
+#else
+#	error "Unimplemented"
+#endif
+}
+
 } // end namespace anki
 } // end namespace anki