Просмотр исходного кода

- Making buffer object thread safe
- Adding thread safe singleton
- Style in Mat4
- Other

Panagiotis Christopoulos Charitos 13 лет назад
Родитель
Сommit
f16c149ec3

+ 1 - 3
CMakeLists.txt

@@ -124,7 +124,7 @@ ANKI_ADD_LIB(${GLEW_INCLUDE_DIR} ${GLEW_LIBRARY_DIR} ${GLEW_INCLUDE_DIR}/GL/glew
 #
 # Defines & flags
 #
-ADD_DEFINITIONS("-DANKI_MATH_INTEL_SIMD -DGLEW_MX -pedantic-errors -pedantic -ansi -Wall -Winline -W -Wwrite-strings -Wno-unused -Wfatal-errors -Werror -Wno-long-long -msse4")
+ADD_DEFINITIONS("-DANKI_MATH_INTEL_SIMD -DGLEW_MX -Dthread_local=__thread -pedantic-errors -pedantic -ansi -Wall -Winline -W -Wwrite-strings -Wno-unused -Wfatal-errors -Werror -Wno-long-long -msse4 -std=c++0x")
 
 # Add a few compiler specific stuff 
 IF(${CMAKE_CXX_COMPILER} MATCHES ".*clang\\+\\+$")	
@@ -140,8 +140,6 @@ ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
 	ADD_DEFINITIONS("-DANKI_PLATFORM_WINDOWS")
 ENDIF()
 
-ADD_DEFINITIONS("-std=c++0x")
-
 IF(CMAKE_BUILD_TYPE STREQUAL Debug)
 	# Removed because they do not work with boost::regexpr and who knows what
 	# else

+ 3 - 5
anki/gl/BufferObject.cpp

@@ -3,9 +3,11 @@
 #include "anki/gl/GlException.h"
 #include "anki/util/Exception.h"
 
-
 namespace anki {
 
+//==============================================================================
+
+const thread_local BufferObject* BufferObject::lastBindedBo = nullptr;
 
 //==============================================================================
 BufferObject::~BufferObject()
@@ -16,7 +18,6 @@ BufferObject::~BufferObject()
 	}
 }
 
-
 //==============================================================================
 void BufferObject::create(GLenum target_, uint sizeInBytes_,
 	const void* dataPtr, GLenum usage_)
@@ -50,7 +51,6 @@ void BufferObject::create(GLenum target_, uint sizeInBytes_,
 	ANKI_CHECK_GL_ERROR();
 }
 
-
 //==============================================================================
 void BufferObject::write(void* buff)
 {
@@ -63,7 +63,6 @@ void BufferObject::write(void* buff)
 	unbind();
 }
 
-
 //==============================================================================
 void BufferObject::write(void* buff, size_t offset, size_t size)
 {
@@ -77,5 +76,4 @@ void BufferObject::write(void* buff, size_t offset, size_t size)
 	unbind();
 }
 
-
 } // end namespace

+ 9 - 5
anki/gl/BufferObject.h

@@ -5,10 +5,8 @@
 #include "anki/util/Assert.h"
 #include "anki/util/StdTypes.h"
 
-
 namespace anki {
 
-
 /// A wrapper for OpenGL buffer objects (vertex arrays, texture buffers etc)
 /// to prevent us from making idiotic errors
 class BufferObject
@@ -63,7 +61,11 @@ public:
 	void bind() const
 	{
 		ANKI_ASSERT(isCreated());
-		glBindBuffer(target, glId);
+		if(lastBindedBo != this)
+		{
+			glBindBuffer(target, glId);
+			lastBindedBo = this;
+		}
 	}
 
 	/// Unbind BO
@@ -71,6 +73,7 @@ public:
 	{
 		ANKI_ASSERT(isCreated());
 		glBindBuffer(target, 0);
+		lastBindedBo = nullptr;
 	}
 
 	/// Creates a new BO with the given parameters and checks if everything
@@ -113,6 +116,9 @@ public:
 	}
 
 private:
+	/// Opt to save a few glBindBuffer calls
+	static const thread_local BufferObject* lastBindedBo; 
+
 	GLuint glId; ///< The OpenGL id of the BO
 
 	/// Used in glBindBuffer(target, glId) and its for easy access so we
@@ -124,8 +130,6 @@ private:
 	size_t sizeInBytes; ///< The size of the buffer
 };
 
-
 } // end namespace anki
 
-
 #endif

+ 4 - 28
anki/gl/ShaderProgram.cpp

@@ -1,14 +1,11 @@
 #include "anki/gl/ShaderProgram.h"
 #include "anki/gl/GlException.h"
-#include "anki/core/Logger.h"
 #include "anki/math/Math.h"
 #include "anki/util/Exception.h"
 #include "anki/gl/Texture.h"
 
-
 namespace anki {
 
-
 //==============================================================================
 // ShaderProgramVariable                                                       =
 //==============================================================================
@@ -23,7 +20,6 @@ void ShaderProgramUniformVariable::doSanityChecks() const
 		getName().c_str()) == getLocation());
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const float x) const
 {
@@ -34,7 +30,6 @@ void ShaderProgramUniformVariable::set(const float x) const
 	glUniform1f(getLocation(), x);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Vec2& x) const
 {
@@ -45,7 +40,6 @@ void ShaderProgramUniformVariable::set(const Vec2& x) const
 	glUniform2f(getLocation(), x.x(), x.y());
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const float x[], uint size) const
 {
@@ -56,7 +50,6 @@ void ShaderProgramUniformVariable::set(const float x[], uint size) const
 	glUniform1fv(getLocation(), size, x);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Vec2 x[], uint size) const
 {
@@ -67,7 +60,6 @@ void ShaderProgramUniformVariable::set(const Vec2 x[], uint size) const
 	glUniform2fv(getLocation(), size, &(const_cast<Vec2&>(x[0]))[0]);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Vec3 x[], uint size) const
 {
@@ -78,7 +70,6 @@ void ShaderProgramUniformVariable::set(const Vec3 x[], uint size) const
 	glUniform3fv(getLocation(), size, &(const_cast<Vec3&>(x[0]))[0]);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Vec4 x[], uint size) const
 {
@@ -89,7 +80,6 @@ void ShaderProgramUniformVariable::set(const Vec4 x[], uint size) const
 	glUniform4fv(getLocation(), size, &(const_cast<Vec4&>(x[0]))[0]);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Mat3 x[], uint size) const
 {
@@ -100,7 +90,6 @@ void ShaderProgramUniformVariable::set(const Mat3 x[], uint size) const
 	glUniformMatrix3fv(getLocation(), size, true, &(x[0])[0]);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Mat4 x[], uint size) const
 {
@@ -111,7 +100,6 @@ void ShaderProgramUniformVariable::set(const Mat4 x[], uint size) const
 	glUniformMatrix4fv(getLocation(), size, true, &(x[0])[0]);
 }
 
-
 //==============================================================================
 void ShaderProgramUniformVariable::set(const Texture& tex) const
 {
@@ -123,7 +111,6 @@ void ShaderProgramUniformVariable::set(const Texture& tex) const
 	glUniform1i(getLocation(), tex.getUnit());
 }
 
-
 //==============================================================================
 // ShaderProgram                                                               =
 //==============================================================================
@@ -143,7 +130,6 @@ const char* ShaderProgram::stdSourceCode =
 
 const ShaderProgram* ShaderProgram::currentProgram = nullptr;
 
-
 //==============================================================================
 void ShaderProgram::create(const char* vertSource, const char* tcSource, 
 	const char* teSource, const char* geomSource, const char* fragSource,
@@ -260,7 +246,6 @@ void ShaderProgram::destroy()
 	glDeleteProgram(glId);
 }
 
-
 //==============================================================================
 GLuint ShaderProgram::createAndCompileShader(const char* sourceCode,
 	const char* preproc, GLenum type)
@@ -301,7 +286,6 @@ GLuint ShaderProgram::createAndCompileShader(const char* sourceCode,
 	return glId;
 }
 
-
 //==============================================================================
 void ShaderProgram::link() const
 {
@@ -327,7 +311,6 @@ void ShaderProgram::link() const
 	}
 }
 
-
 //==============================================================================
 void ShaderProgram::getUniAndAttribVars()
 {
@@ -349,9 +332,8 @@ void ShaderProgram::getUniAndAttribVars()
 		int loc = glGetAttribLocation(glId, &name_[0]);
 		if(loc == -1) // if -1 it means that its an FFP var
 		{
-			ANKI_WARNING("You are using FFP vertex attributes (\"" 
-				<< &name_[0] << "\")");
-			continue;
+			throw ANKI_EXCEPTION("You are using FFP vertex attributes (\"" 
+				+ std::string(&name_[0]) + "\")");
 		}
 
 		ShaderProgramAttributeVariable* var =
@@ -376,9 +358,8 @@ void ShaderProgram::getUniAndAttribVars()
 		int loc = glGetUniformLocation(glId, &name_[0]);
 		if(loc == -1) // if -1 it means that its an FFP var
 		{
-			ANKI_WARNING("You are using FFP vertex uniforms (\"" 
-				<< &name_[0] << "\")");
-			continue;
+			throw ANKI_EXCEPTION("You are using FFP vertex uniforms (\"" 
+				+ std::string(&name_[0]) + "\")");
 		}
 
 		ShaderProgramUniformVariable* var =
@@ -392,7 +373,6 @@ void ShaderProgram::getUniAndAttribVars()
 	}
 }
 
-
 //==============================================================================
 const ShaderProgramVariable* ShaderProgram::findVariableByName(
 	const char* name) const
@@ -405,7 +385,6 @@ const ShaderProgramVariable* ShaderProgram::findVariableByName(
 	return it->second;
 }
 
-
 //==============================================================================
 const ShaderProgramAttributeVariable*
 	ShaderProgram::findAttributeVariableByName(const char* name) const
@@ -418,7 +397,6 @@ const ShaderProgramAttributeVariable*
 	return it->second;
 }
 
-
 //==============================================================================
 const ShaderProgramUniformVariable* ShaderProgram::findUniformVariableByName(
 	const char* name) const
@@ -431,7 +409,6 @@ const ShaderProgramUniformVariable* ShaderProgram::findUniformVariableByName(
 	return it->second;
 }
 
-
 //==============================================================================
 std::ostream& operator<<(std::ostream& s, const ShaderProgram& x)
 {
@@ -446,5 +423,4 @@ std::ostream& operator<<(std::ostream& s, const ShaderProgram& x)
 	return s;
 }
 
-
 } // end namespace

+ 8 - 8
anki/gl/ShaderProgram.h

@@ -9,14 +9,15 @@
 #include <GL/glew.h>
 #include <vector>
 
-
 namespace anki {
 
-
 class ShaderProgram;
 class Texture;
 
+/// @addtogroup gl
+/// @{
 
+//==============================================================================
 /// Shader program variable. The type is attribute or uniform
 class ShaderProgramVariable
 {
@@ -91,7 +92,7 @@ private:
 	const ShaderProgram* fatherSProg;
 };
 
-
+//==============================================================================
 /// Uniform shader variable
 class ShaderProgramUniformVariable: public ShaderProgramVariable
 {
@@ -152,7 +153,7 @@ private:
 	void doSanityChecks() const;
 };
 
-
+//==============================================================================
 /// Attribute shader program variable
 class ShaderProgramAttributeVariable: public ShaderProgramVariable
 {
@@ -165,7 +166,7 @@ public:
 	{}
 };
 
-
+//==============================================================================
 /// Shader program object
 ///
 /// Shader program. Combines. Every shader program consist of one OpenGL ID, a 
@@ -333,10 +334,9 @@ private:
 	}
 
 	void destroy();
-}; 
-
+};
+/// @}
 
 } // end namespace
 
-
 #endif

+ 20 - 21
anki/math/Mat4.inl.h

@@ -821,8 +821,7 @@ inline float Mat4::getDet() const
 // getInverse
 inline Mat4 Mat4::getInverse() const
 {
-	float tmp[12];
-	float det;
+	std::array<float, 12> tmp;
 	const Mat4& in = (*this);
 	Mat4 m4;
 
@@ -869,25 +868,25 @@ inline Mat4 Mat4::getInverse() const
 	tmp[10] = in(0, 0) * in(1, 1);
 	tmp[11] = in(1, 0) * in(0, 1);
 
-	m4(2, 0) = tmp[0] * in(1, 3) + tmp[3] * in(2, 3) + tmp[4] * in(3, 3);
-	m4(2, 0)-= tmp[1] * in(1, 3) + tmp[2] * in(2, 3) + tmp[5] * in(3, 3);
-	m4(2, 1) = tmp[1] * in(0, 3) + tmp[6] * in(2, 3) + tmp[9] * in(3, 3);
-	m4(2, 1)-= tmp[0] * in(0, 3) + tmp[7] * in(2, 3) + tmp[8] * in(3, 3);
-	m4(2, 2) = tmp[2] * in(0, 3) + tmp[7] * in(1, 3) + tmp[10] * in(3, 3);
-	m4(2, 2)-= tmp[3] * in(0, 3) + tmp[6] * in(1, 3) + tmp[11] * in(3, 3);
-	m4(2, 3) = tmp[5] * in(0, 3) + tmp[8] * in(1, 3) + tmp[11] * in(2, 3);
-	m4(2, 3)-= tmp[4] * in(0, 3) + tmp[9] * in(1, 3) + tmp[10] * in(2, 3);
-	m4(3, 0) = tmp[2] * in(2, 2) + tmp[5] * in(3, 2) + tmp[1] * in(1, 2);
-	m4(3, 0)-= tmp[4] * in(3, 2) + tmp[0] * in(1, 2) + tmp[3] * in(2, 2);
-	m4(3, 1) = tmp[8] * in(3, 2) + tmp[0] * in(0, 2) + tmp[7] * in(2, 2);
-	m4(3, 1)-= tmp[6] * in(2, 2) + tmp[9] * in(3, 2) + tmp[1] * in(0, 2);
-	m4(3, 2) = tmp[6] * in(1, 2) + tmp[11] * in(3, 2) + tmp[3] * in(0, 2);
-	m4(3, 2)-= tmp[10] * in(3, 2) + tmp[2] * in(0, 2) + tmp[7] * in(1, 2);
-	m4(3, 3) = tmp[10] * in(2, 2) + tmp[4] * in(0, 2) + tmp[9] * in(1, 2);
-	m4(3, 3)-= tmp[8] * in(1, 2) + tmp[11] * in(2, 2) + tmp[5] * in(0, 2);
-
-	det = (*this)(0, 0) * m4(0, 0) + (*this)(1, 0) * m4(0, 1) 
-		+ (*this)(2, 0) * m4(0, 2) + (*this)(3, 0) * m4(0, 3);
+	m4(2, 0) =  tmp[0] * in(1, 3) + tmp[3] * in(2, 3) + tmp[4] * in(3, 3);
+	m4(2, 0) -= tmp[1] * in(1, 3) + tmp[2] * in(2, 3) + tmp[5] * in(3, 3);
+	m4(2, 1) =  tmp[1] * in(0, 3) + tmp[6] * in(2, 3) + tmp[9] * in(3, 3);
+	m4(2, 1) -= tmp[0] * in(0, 3) + tmp[7] * in(2, 3) + tmp[8] * in(3, 3);
+	m4(2, 2) =  tmp[2] * in(0, 3) + tmp[7] * in(1, 3) + tmp[10] * in(3, 3);
+	m4(2, 2) -= tmp[3] * in(0, 3) + tmp[6] * in(1, 3) + tmp[11] * in(3, 3);
+	m4(2, 3) =  tmp[5] * in(0, 3) + tmp[8] * in(1, 3) + tmp[11] * in(2, 3);
+	m4(2, 3) -= tmp[4] * in(0, 3) + tmp[9] * in(1, 3) + tmp[10] * in(2, 3);
+	m4(3, 0) =  tmp[2] * in(2, 2) + tmp[5] * in(3, 2) + tmp[1] * in(1, 2);
+	m4(3, 0) -= tmp[4] * in(3, 2) + tmp[0] * in(1, 2) + tmp[3] * in(2, 2);
+	m4(3, 1) =  tmp[8] * in(3, 2) + tmp[0] * in(0, 2) + tmp[7] * in(2, 2);
+	m4(3, 1) -= tmp[6] * in(2, 2) + tmp[9] * in(3, 2) + tmp[1] * in(0, 2);
+	m4(3, 2) =  tmp[6] * in(1, 2) + tmp[11] * in(3, 2) + tmp[3] * in(0, 2);
+	m4(3, 2) -= tmp[10] * in(3, 2) + tmp[2] * in(0, 2) + tmp[7] * in(1, 2);
+	m4(3, 3) =  tmp[10] * in(2, 2) + tmp[4] * in(0, 2) + tmp[9] * in(1, 2);
+	m4(3, 3) -= tmp[8] * in(1, 2) + tmp[11] * in(2, 2) + tmp[5] * in(0, 2);
+
+	float det = in(0, 0) * m4(0, 0) + in(1, 0) * m4(0, 1) 
+		+ in(2, 0) * m4(0, 2) + in(3, 0) * m4(0, 3);
 
 	ANKI_ASSERT(!Math::isZero(det)); // Cannot invert, det == 0
 	det = 1.0 / det;

+ 43 - 14
anki/util/Singleton.h

@@ -1,14 +1,12 @@
 #ifndef ANKI_UTIL_SINGLETON_H
 #define ANKI_UTIL_SINGLETON_H
 
-#ifndef NULL
-#	define NULL 0
-#endif
-
-
 namespace anki {
 
+/// @addtogroup util
+/// @{
 
+//==============================================================================
 /// This template makes a class singleton
 template<typename T>
 class Singleton
@@ -16,28 +14,59 @@ class Singleton
 public:
 	typedef T Value;
 
+	// Non copyable
+	Singleton(const Singleton&) = delete;
+	Singleton& operator=(const Singleton&) = delete;
+
+	// Non constructable
+	Singleton() = delete;
+	~Singleton() = delete;
+
+	/// Get instance
 	static Value& get()
 	{
 		return *(instance ? instance : (instance = new Value));
 	}
 
-protected:
-	Singleton();
-	~Singleton();
-
 private:
 	static Value* instance;
-
-	Singleton(const Singleton&);
-	Singleton& operator=(const Singleton&);
 };
 
+template <typename T>
+typename Singleton<T>::Value* Singleton<T>::instance = nullptr;
+
+//==============================================================================
+/// This template makes a class singleton with thread local instance
+template<typename T>
+class SingletonThreadSafe
+{
+public:
+	typedef T Value;
+
+	// Non copyable
+	SingletonThreadSafe(const SingletonThreadSafe&) = delete;
+	SingletonThreadSafe& operator=(const SingletonThreadSafe&) = delete;
+
+	// Non constructable
+	SingletonThreadSafe() = delete;
+	~SingletonThreadSafe() = delete;
+
+	/// Get instance
+	static Value& get()
+	{
+		return *(instance ? instance : (instance = new Value));
+	}
+
+private:
+	static thread_local Value* instance;
+};
 
 template <typename T>
-typename Singleton<T>::Value* Singleton<T>::instance = NULL;
+thread_local typename SingletonThreadSafe<T>::Value* 
+	SingletonThreadSafe<T>::instance = nullptr;
 
+/// @}
 
 } // end namespace
 
-
 #endif