Răsfoiți Sursa

Allocator stuff

Panagiotis Christopoulos Charitos 13 ani în urmă
părinte
comite
c366d63010

+ 14 - 34
include/anki/gl/BufferObject.h

@@ -1,10 +1,7 @@
 #ifndef ANKI_GL_BUFFER_OBJECT_H
 #define ANKI_GL_BUFFER_OBJECT_H
 
-#include "anki/gl/Ogl.h"
-#include "anki/util/Assert.h"
-#include "anki/util/NonCopyable.h"
-#include "anki/util/StdTypes.h"
+#include "anki/gl/GlObject.h"
 
 namespace anki {
 
@@ -13,9 +10,11 @@ namespace anki {
 	
 /// A wrapper for OpenGL buffer objects (vertex arrays, texture buffers etc)
 /// to prevent us from making idiotic errors
-class BufferObject: public NonCopyable
+class BufferObject: public GlObject
 {
 public:
+	typedef GlObject Base;
+
 	/// @name Constructors/Destructor
 	/// @{
 
@@ -24,14 +23,9 @@ public:
 	{}
 
 	/// Move
-	BufferObject(BufferObject&& b)
-		: glId(b.glId), target(b.target), usage(b.usage), 
-			sizeInBytes(b.sizeInBytes)
-#if ANKI_DEBUG
-			, mapped(b.mapped)
-#endif
+	BufferObject(BufferObject&& b)	
 	{
-		b.glId = 0;
+		*this = std::move(b);
 	}
 
 	/// @see create
@@ -42,17 +36,17 @@ public:
 	}
 
 	/// It deletes the BO
-	~BufferObject();
+	~BufferObject()
+	{
+		destroy();
+	}
 	/// @}
 
+	/// Move
+	BufferObject& operator=(BufferObject&& b);
+
 	/// @name Accessors
 	/// @{
-	GLuint getGlId() const
-	{
-		ANKI_ASSERT(isCreated());
-		return glId;
-	}
-
 	GLenum getBufferTarget() const
 	{
 		ANKI_ASSERT(isCreated());
@@ -99,13 +93,7 @@ public:
 		GLenum usage);
 
 	/// Delete the BO
-	void destroy()
-	{
-		ANKI_ASSERT(isCreated());
-		unbind();
-		glDeleteBuffers(1, &glId);
-		glId = 0;
-	}
+	void destroy();
 
 	/// Write data to buffer. This means that maps the BO to local memory,
 	/// writes the local memory and unmaps it. Throws exception if the
@@ -135,12 +123,6 @@ public:
 	/// Unmap buffer
 	void unmap();
 
-	/// If create() is run successfully this returns true
-	Bool isCreated() const
-	{
-		return glId != 0;
-	}
-
 	/// Set the binding for this buffer
 	void setBinding(GLuint binding) const
 	{
@@ -151,8 +133,6 @@ public:
 	}
 
 private:
-	GLuint glId = 0; ///< The OpenGL id of the BO
-
 	/// Used in glBindBuffer(target, glId) and its for easy access so we
 	/// wont have to query the GL driver. Its the type of the buffer eg
 	/// GL_TEXTURE_BUFFER or GL_ELEMENT_ARRAY_BUFFER etc

+ 8 - 3
include/anki/gl/Fbo.h

@@ -17,6 +17,8 @@ class Texture;
 class Fbo: public GlObjectContextNonSharable
 {
 public:
+	typedef GlObjectContextNonSharable Base;
+
 	/// FBO target
 	enum FboTarget
 	{
@@ -36,15 +38,18 @@ public:
 		*this = std::move(b);
 	}
 
-	~Fbo();
+	~Fbo()
+	{
+		destroy();
+	}
 	/// @}
 
 	/// @name Operators
 	/// @{
 	Fbo& operator=(Fbo&& b)
 	{
-		GlObjectContextNonSharable::operator=(
-			std::forward<GlObjectContextNonSharable>(b));
+		destroy();
+		Base::operator=(std::forward<Base>(b));
 		return *this;
 	}
 	/// @}

+ 1 - 1
include/anki/gl/GlObject.h

@@ -36,7 +36,7 @@ public:
 	/// Move
 	GlObject& operator=(GlObject&& b)
 	{
-		ANKI_DEBUG(!isCreated());
+		ANKI_ASSERT(!isCreated());
 		glId = b.glId;
 		b.glId = 0;
 		return *this;

+ 19 - 38
include/anki/gl/ShaderProgram.h

@@ -1,13 +1,10 @@
 #ifndef ANKI_GL_SHADER_PROGRAM_H
 #define ANKI_GL_SHADER_PROGRAM_H
 
+#include "anki/gl/GlObject.h"
 #include "anki/util/ConstCharPtrHashMap.h"
-#include "anki/util/Assert.h"
 #include "anki/math/Forward.h"
-#include "anki/gl/Ogl.h"
 #include "anki/util/Vector.h"
-#include "anki/util/StdTypes.h"
-#include "anki/util/NonCopyable.h"
 #include <string>
 #include <memory>
 
@@ -279,9 +276,11 @@ private:
 };
 
 /// Shader program object
-class ShaderProgram: public NonCopyable
+class ShaderProgram: public GlObject
 {
 public:
+	typedef GlObject Base;
+
 	typedef Vector<ShaderProgramUniformVariable>
 		UniformVariablesContainer;
 	typedef Vector<ShaderProgramAttributeVariable>
@@ -292,44 +291,40 @@ public:
 	/// @name Constructors/Destructor
 	/// @{
 	ShaderProgram()
-	{
-		init();
-	}
+	{}
+
+	/// Move. It's not movable untill we need it
+	ShaderProgram(ShaderProgram&& b) = delete;
 
 	ShaderProgram(const char* vertSource, const char* tcSource, 
 		const char* teSource, const char* geomSource, const char* fragSource,
 		const char* transformFeedbackVaryings[],
 		const GLenum xfbBufferMode = GL_SEPARATE_ATTRIBS)
 	{
-		init();
 		create(vertSource, tcSource, teSource, geomSource, fragSource,
 			transformFeedbackVaryings, xfbBufferMode);
 	}
 
 	~ShaderProgram()
 	{
-		if(isCreated())
-		{
-			destroy();
-		}
+		destroy();
 	}
 	/// @}
 
+	/// Move deleted. It's not movable untill we need it
+	ShaderProgram& operator=(ShaderProgram&& b) = delete;
+
 	/// @name Accessors
 	/// @{
-	GLuint getGlId() const
-	{
-		ANKI_ASSERT(isCreated());
-		return glId;
-	}
-
 	const UniformVariablesContainer& getUniformVariables() const
 	{
+		ANKI_ASSERT(isCreated());
 		return unis;
 	}
 
 	const AttributeVariablesContainer& getAttributeVariables() const
 	{
+		ANKI_ASSERT(isCreated());
 		return attribs;
 	}
 	/// @}
@@ -410,12 +405,11 @@ private:
 
 	static thread_local const ShaderProgram* current;
 
-	GLuint glId; ///< The OpenGL ID of the shader program
-	GLuint vertShaderGlId; ///< Vertex shader OpenGL id
-	GLuint tcShaderGlId; ///< Tessellation control shader OpenGL id
-	GLuint teShaderGlId; ///< Tessellation eval shader OpenGL id
-	GLuint geomShaderGlId; ///< Geometry shader OpenGL id
-	GLuint fragShaderGlId; ///< Fragment shader OpenGL id
+	GLuint vertShaderGlId = 0; ///< Vertex shader OpenGL id
+	GLuint tcShaderGlId = 0; ///< Tessellation control shader OpenGL id
+	GLuint teShaderGlId = 0; ///< Tessellation eval shader OpenGL id
+	GLuint geomShaderGlId = 0; ///< Geometry shader OpenGL id
+	GLuint fragShaderGlId = 0; ///< Fragment shader OpenGL id
 
 	/// @name Containers
 	/// @{
@@ -446,19 +440,6 @@ private:
 	/// @exception Exception
 	void link() const;
 
-	/// Returns true if the class points to a valid GL ID
-	bool isCreated() const
-	{
-		return glId != 0;
-	}
-
-	/// Common construction code
-	void init()
-	{
-		glId = vertShaderGlId = tcShaderGlId = teShaderGlId =
-			geomShaderGlId = fragShaderGlId = 0;
-	}
-
 	void destroy();
 };
 /// @}

+ 8 - 13
include/anki/gl/Vao.h

@@ -32,7 +32,10 @@ public:
 	}
 
 	/// Destroy VAO from the OpenGL context
-	~Vao();
+	~Vao()
+	{
+		destroy();
+	}
 	/// @}
 
 	/// @name Operators
@@ -41,10 +44,8 @@ public:
 	/// Move
 	Vao& operator=(Vao&& b)
 	{
-		if(isCreated())
-		{
-			destroy();
-		}
+		crateNonSharable();
+		destroy();
 
 		Base::operator=(std::forward<Base>(b));
 		attachments = b.attachments;
@@ -63,14 +64,7 @@ public:
 	}
 
 	/// Destroy
-	void destroy()
-	{
-		checkNonSharable();
-		ANKI_ASSERT(isCreated());
-		unbind();
-		glDeleteVertexArrays(1, &glId);
-		glId = 0;
-	}
+	void destroy();
 
 	/// Attach an array buffer VBO. See @link
 	/// http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribPointer.xml
@@ -120,6 +114,7 @@ public:
 
 	U32 getAttachmentsCount() const
 	{
+		ANKI_ASSERT(isCreated());
 		return attachments;
 	}
 

+ 1 - 1
include/anki/scene/Scene.h

@@ -32,7 +32,7 @@ public:
 		typedef typename ConstCharPtrHashMap<T*>::Type NameToItemMap;
 	};
 
-	/// The size of the internal allocator
+	/// The size of the internal allocator. 1MB
 	const PtrSize ALLOCATOR_SIZE = 0x100000;
 
 	/// @name Constructors/Destructor

+ 3 - 3
include/anki/scene/SkinNode.h

@@ -335,17 +335,17 @@ private:
 	/// @param[out] translations Translations vector
 	/// @param[out] rotations Rotations vector
 	static void interpolate(const SkelAnim& animation, float frame,
-		Vector<Vec3>& translations, std::vector<Mat3>& rotations);
+		Vector<Vec3>& translations, Vector<Mat3>& rotations);
 
 	/// Calculate the global pose
 	static void updateBoneTransforms(const Skeleton& skel,
-		Vector<Vec3>& translations, std::vector<Mat3>& rotations);
+		Vector<Vec3>& translations, Vector<Mat3>& rotations);
 
 	/// Deform the heads and tails
 	static void deformHeadsTails(const Skeleton& skeleton,
 		const Vector<Vec3>& boneTranslations,
 		const Vector<Mat3>& boneRotations,
-		Vector<Vec3>& heads, std::vector<Vec3>& tails);
+		Vector<Vec3>& heads, Vector<Vec3>& tails);
 };
 
 } // end namespace

+ 34 - 0
include/anki/util/Allocator.h

@@ -165,6 +165,20 @@ inline bool operator==(const Allocator<T1>&, const AnotherAllocator&)
 	return false;
 }
 
+/// Another allocator of the same type can deallocate from this one
+template<typename T1, typename T2>
+inline bool operator!=(const Allocator<T1>&, const Allocator<T2>&)
+{
+	return false;
+}
+
+/// Another allocator of the another type cannot deallocate from this one
+template<typename T1, typename AnotherAllocator>
+inline bool operator!=(const Allocator<T1>&, const AnotherAllocator&)
+{
+	return true;
+}
+
 namespace detail {
 
 /// Thread safe memory pool
@@ -425,6 +439,26 @@ inline bool operator==(
 {
 	return false;
 }
+
+/// Another allocator of the same type can deallocate from this one
+template<typename T1, typename T2, Bool deallocationFlag, U32 alignmentBits>
+inline bool operator!=(
+	const StackAllocator<T1, deallocationFlag, alignmentBits>&,
+	const StackAllocator<T2, deallocationFlag, alignmentBits>&)
+{
+	return false;
+}
+
+/// Another allocator of the another type cannot deallocate from this one
+template<typename T1, typename AnotherAllocator, Bool deallocationFlag,
+	U32 alignmentBits>
+inline bool operator!=(
+	const StackAllocator<T1, deallocationFlag, alignmentBits>&,
+	const AnotherAllocator&)
+{
+	return true;
+}
+
 /// @}
 /// @}
 

+ 6 - 4
include/anki/util/Object.h

@@ -4,6 +4,7 @@
 #include "anki/util/Assert.h"
 #include "anki/util/Vector.h"
 #include "anki/util/StdTypes.h"
+#include "anki/util/Allocator.h"
 #include <algorithm>
 
 namespace anki {
@@ -14,16 +15,16 @@ namespace anki {
 /// @{
 
 /// A hierarchical object
-template<typename T>
+template<typename T, typename Alloc = Allocator<T>>
 class Object
 {
 public:
 	typedef T Value;
-	typedef Vector<Value*> Container;
+	typedef Vector<Value*, Alloc> Container;
 
 	/// Calls addChild if parent is not nullptr
-	Object(Value* self_, Value* parent_)
-		: self(self_)
+	Object(Value* self_, Value* parent_, const Alloc& alloc = Alloc())
+		: self(self_), childs(alloc)
 	{
 		ANKI_ASSERT(self != nullptr && "Self can't be nullptr");
 		ANKI_ASSERT(parent_ != this && "Cannot put itself");
@@ -113,6 +114,7 @@ private:
 	Value* parent = nullptr; ///< May be nullptr
 	Container childs;
 };
+
 /// @}
 /// @}
 

+ 7 - 6
include/anki/util/Vector.h

@@ -3,6 +3,8 @@
 
 #include "anki/util/Assert.h"
 #include "anki/util/Functions.h"
+#include "anki/util/Allocator.h"
+#include "anki/util/Memory.h"
 #include <vector>
 
 namespace anki {
@@ -12,16 +14,16 @@ namespace anki {
 /// @addtogroup containers
 /// @{
 
-template<typename T>
-using Vector = std::vector<T>;
+template<typename T, typename Alloc = Allocator<T>>
+using Vector = std::vector<T, Alloc>;
 
 /// Vector of pointers. The same as the regular vector but it deallocates the
 /// pointers
-template<typename T>
-class PtrVector: public Vector<T*>
+template<typename T, typename Alloc = Allocator<T>>
+class PtrVector: public Vector<T*, Alloc>
 {
 public:
-	typedef Vector<T*> Base;
+	typedef Vector<T*, Alloc> Base;
 
 	~PtrVector()
 	{
@@ -33,7 +35,6 @@ public:
 
 	typename Base::iterator erase(typename Base::iterator pos)
 	{
-		propperDelete(*pos);
 		return Base::erase(pos);
 	}
 };

+ 18 - 2
src/gl/BufferObject.cpp

@@ -9,11 +9,27 @@
 namespace anki {
 
 //==============================================================================
-BufferObject::~BufferObject()
+BufferObject& BufferObject::operator=(BufferObject&& b)
+{
+	destroy();
+	Base::operator=(std::forward<Base>(b));
+	target = b.target;
+	usage = b.usage;
+	sizeInBytes = b.sizeInBytes;
+#if ANKI_DEBUG
+	mapped = b.mapped;
+#endif
+	return *this;
+}
+
+//==============================================================================
+void BufferObject::destroy()
 {
 	if(isCreated())
 	{
-		destroy();
+		unbind();
+		glDeleteBuffers(1, &glId);
+		glId = 0;
 	}
 }
 

+ 6 - 13
src/gl/Fbo.cpp

@@ -14,15 +14,6 @@ static const Array<GLenum, 8> colorAttachments = {{
 	GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5,
 	GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7}};
 
-//==============================================================================
-Fbo::~Fbo()
-{
-	if(isCreated())
-	{
-		destroy();
-	}
-}
-
 //==============================================================================
 void Fbo::create()
 {
@@ -35,11 +26,13 @@ void Fbo::create()
 //==============================================================================
 void Fbo::destroy()
 {
-	ANKI_ASSERT(isCreated());
 	checkNonSharable();
-	bindDefault();
-	glDeleteFramebuffers(1, &glId);
-	glId = 0;
+	if(isCreated())
+	{
+		bindDefault();
+		glDeleteFramebuffers(1, &glId);
+		glId = 0;
+	}
 }
 
 //==============================================================================

+ 13 - 2
src/gl/ShaderProgram.cpp

@@ -460,34 +460,38 @@ void ShaderProgram::destroy()
 	if(vertShaderGlId != 0)
 	{
 		glDeleteShader(vertShaderGlId);
+		vertShaderGlId = 0;
 	}
 
 	if(tcShaderGlId != 0)
 	{
 		glDeleteShader(tcShaderGlId);
+		tcShaderGlId = 0;
 	}
 
 	if(teShaderGlId != 0)
 	{
 		glDeleteShader(teShaderGlId);
+		teShaderGlId = 0;
 	}
 
 	if(geomShaderGlId != 0)
 	{
 		glDeleteShader(geomShaderGlId);
+		geomShaderGlId = 0;
 	}
 
 	if(fragShaderGlId != 0)
 	{
 		glDeleteShader(fragShaderGlId);
+		fragShaderGlId = 0;
 	}
 
 	if(glId != 0)
 	{
 		glDeleteProgram(glId);
+		glId = 0;
 	}
-
-	init();
 }
 
 //==============================================================================
@@ -812,6 +816,7 @@ void ShaderProgram::initUniformBlocks()
 const ShaderProgramAttributeVariable*
 	ShaderProgram::tryFindAttributeVariable(const char* name) const
 {
+	ANKI_ASSERT(isCreated());
 	NameToAttribVarHashMap::const_iterator it = nameToAttribVar.find(name);
 	return (it == nameToAttribVar.end()) ? nullptr : it->second;
 }
@@ -820,6 +825,7 @@ const ShaderProgramAttributeVariable*
 const ShaderProgramAttributeVariable&
 	ShaderProgram::findAttributeVariable(const char* name) const
 {
+	ANKI_ASSERT(isCreated());
 	const ShaderProgramAttributeVariable* var = tryFindAttributeVariable(name);
 	if(var == nullptr)
 	{
@@ -832,6 +838,7 @@ const ShaderProgramAttributeVariable&
 const ShaderProgramUniformVariable* ShaderProgram::tryFindUniformVariable(
 	const char* name) const
 {
+	ANKI_ASSERT(isCreated());
 	NameToUniVarHashMap::const_iterator it = nameToUniVar.find(name);
 	if(it == nameToUniVar.end())
 	{
@@ -844,6 +851,7 @@ const ShaderProgramUniformVariable* ShaderProgram::tryFindUniformVariable(
 const ShaderProgramUniformVariable& ShaderProgram::findUniformVariable(
 	const char* name) const
 {
+	ANKI_ASSERT(isCreated());
 	const ShaderProgramUniformVariable* var = tryFindUniformVariable(name);
 	if(var == nullptr)
 	{
@@ -856,6 +864,7 @@ const ShaderProgramUniformVariable& ShaderProgram::findUniformVariable(
 const ShaderProgramUniformBlock* ShaderProgram::tryFindUniformBlock(
 	const char* name) const
 {
+	ANKI_ASSERT(isCreated());
 	NameToUniformBlockHashMap::const_iterator it = nameToBlock.find(name);
 	return (it == nameToBlock.end()) ? nullptr : it->second;
 }
@@ -864,6 +873,7 @@ const ShaderProgramUniformBlock* ShaderProgram::tryFindUniformBlock(
 const ShaderProgramUniformBlock& ShaderProgram::findUniformBlock(
 	const char* name) const
 {
+	ANKI_ASSERT(isCreated());
 	const ShaderProgramUniformBlock* block = tryFindUniformBlock(name);
 	if(block == nullptr)
 	{
@@ -875,6 +885,7 @@ const ShaderProgramUniformBlock& ShaderProgram::findUniformBlock(
 //==============================================================================
 std::ostream& operator<<(std::ostream& s, const ShaderProgram& x)
 {
+	ANKI_ASSERT(x.isCreated());
 	s << "ShaderProgram\n";
 	s << "Uniform variables:\n";
 	for(auto var : x.unis)

+ 9 - 4
src/gl/Vao.cpp

@@ -11,11 +11,16 @@ namespace anki {
 const Vao* Vao::current = nullptr;
 
 //==============================================================================
-Vao::~Vao()
+void Vao::destroy()
 {
+	checkNonSharable();
+
 	if(isCreated())
 	{
-		destroy();
+		unbind();
+		glDeleteVertexArrays(1, &glId);
+		glId = 0;
+		attachments = 0;
 	}
 }
 
@@ -25,10 +30,10 @@ void Vao::attachArrayBufferVbo(const Vbo* vbo, const GLint attribVarLocation,
 	const PtrSize stride, const PtrSize offset)
 {
 	ANKI_ASSERT(isCreated());
+	checkNonSharable();
 	ANKI_ASSERT(vbo->getBufferTarget() == GL_ARRAY_BUFFER
 		&& "Only GL_ARRAY_BUFFER is accepted");
 	ANKI_ASSERT(vbo->isCreated());
-	checkNonSharable();
 
 	bind();
 	vbo->bind();
@@ -57,10 +62,10 @@ void Vao::attachArrayBufferVbo(const Vbo* vbo,
 void Vao::attachElementArrayBufferVbo(const Vbo* vbo)
 {
 	ANKI_ASSERT(isCreated());
+	checkNonSharable();
 	ANKI_ASSERT(vbo->getBufferTarget() == GL_ELEMENT_ARRAY_BUFFER
 		&& "Only GL_ELEMENT_ARRAY_BUFFER is accepted");
 	ANKI_ASSERT(vbo->isCreated());
-	checkNonSharable();
 
 	bind();
 	vbo->bind();

+ 3 - 3
src/scene/SkinNode.cpp

@@ -195,7 +195,7 @@ void SkinNode::frameUpdate(float prevUpdateTime, float crntTime, int f)
 
 //==============================================================================
 void SkinNode::interpolate(const SkelAnim& animation, float frame,
-	Vector<Vec3>& boneTranslations, std::vector<Mat3>& boneRotations)
+	Vector<Vec3>& boneTranslations, Vector<Mat3>& boneRotations)
 {
 	ANKI_ASSERT(frame < animation.getFramesNum());
 
@@ -260,7 +260,7 @@ void SkinNode::interpolate(const SkelAnim& animation, float frame,
 
 //==============================================================================
 void SkinNode::updateBoneTransforms(const Skeleton& skeleton,
-	Vector<Vec3>& boneTranslations, std::vector<Mat3>& boneRotations)
+	Vector<Vec3>& boneTranslations, Vector<Mat3>& boneRotations)
 {
 	std::array<uint, 128> queue;
 	uint head = 0, tail = 0;
@@ -320,7 +320,7 @@ void SkinNode::updateBoneTransforms(const Skeleton& skeleton,
 void SkinNode::deformHeadsTails(const Skeleton& skeleton,
     const Vector<Vec3>& boneTranslations,
     const Vector<Mat3>& boneRotations,
-    Vector<Vec3>& heads, std::vector<Vec3>& tails)
+	Vector<Vec3>& heads, Vector<Vec3>& tails)
 {
 	for(uint i = 0; i < skeleton.getBones().size(); i++)
 	{