Panagiotis Christopoulos Charitos 13 rokov pred
rodič
commit
b2b665a780

+ 0 - 113
include/anki/core/ParallelManager.h

@@ -1,113 +0,0 @@
-#ifndef ANKI_CORE_PARALLEL_MANAGER_H
-#define ANKI_CORE_PARALLEL_MANAGER_H
-
-#include "anki/util/Barrier.h"
-#include "anki/util/Singleton.h"
-#include "anki/util/Vector.h"
-#include <thread>
-
-namespace anki {
-
-class ParallelManager;
-class ParallelJob;
-
-/// The base class of the parameters the we pass in the job
-struct ParallelJobParameters
-{};
-
-/// The callback that we feed to the job
-typedef void (*ParallelJobCallback)(ParallelJobParameters&, const ParallelJob&);
-
-/// The thread that executes a ParallelJobCallback
-class ParallelJob
-{
-public:
-	/// Constructor
-	ParallelJob(uint32_t id, const ParallelManager* manager,
-		Barrier* barrier);
-
-	/// @name Accessors
-	/// @{
-	uint32_t getId() const
-	{
-		return id;
-	}
-
-	const ParallelManager& getManager() const
-	{
-		return *manager;
-	}
-	/// @}
-
-	/// Assign new job to the thread
-	void assignNewJob(ParallelJobCallback callback,
-		ParallelJobParameters& jobParams);
-
-private:
-	uint32_t id; ///< An ID
-	std::thread thread; ///< Runs the workingFunc
-	std::mutex mutex; ///< Protect the ParallelJob::job
-	std::condition_variable condVar; ///< To wake up the thread
-	Barrier* barrier; ///< For synchronization
-	ParallelJobCallback callback; ///< Its NULL if there are no pending job
-	ParallelJobParameters* params;
-	/// Know your father and pass him to the jobs
-	const ParallelManager* manager;
-
-	/// Start thread
-	void start()
-	{
-		thread = std::thread(&ParallelJob::workingFunc, this);
-	}
-
-	/// Thread loop
-	void workingFunc();
-};
-
-/// Parallel job dispatcher.You feed it with jobs and sends them for
-/// execution in parallel and then waits for all to finish
-class ParallelManager
-{
-public:
-	/// Default constructor
-	ParallelManager()
-	{}
-
-	/// Constructor #2
-	ParallelManager(uint threadsNum)
-	{
-		init(threadsNum);
-	}
-
-	/// Init the manager
-	void init(uint threadsNum);
-
-	/// Assign a job to a working thread
-	void assignNewJob(uint jobId, ParallelJobCallback callback,
-		ParallelJobParameters& jobParams)
-	{
-		jobs[jobId]->assignNewJob(callback, jobParams);
-	}
-
-	/// Wait for all jobs to finish
-	void waitForAllJobsToFinish()
-	{
-		barrier->wait();
-	}
-
-	uint getThreadsNum() const
-	{
-		return jobs.size();
-	}
-
-private:
-	PtrVector<ParallelJob> jobs; ///< Worker threads
-	std::unique_ptr<Barrier> barrier; ///< Synchronization barrier
-};
-
-/// Singleton
-typedef Singleton<ParallelManager> ParallelManagerSingleton;
-
-} // end namespace anki
-
-#endif

+ 112 - 0
include/anki/core/ThreadPool.h

@@ -0,0 +1,112 @@
+#ifndef ANKI_CORE_PARALLEL_MANAGER_H
+#define ANKI_CORE_PARALLEL_MANAGER_H
+
+#include "anki/util/Barrier.h"
+#include "anki/util/Singleton.h"
+#include "anki/util/Vector.h"
+#include "anki/util/StdTypes.h"
+#include <thread>
+
+namespace anki {
+
+// Forward
+class ThreadPool;
+
+/// A job assignment for a ThreadWorker
+struct ThreadJob
+{
+	virtual ~ThreadJob()
+	{}
+
+	virtual void operator()() = 0;
+};
+
+/// A dummy job
+struct ThreadJobDummy
+{
+	void operator()()
+	{}
+};
+
+/// The thread that executes a ThreadJobCallback
+class ThreadWorker
+{
+public:
+	/// Constructor
+	ThreadWorker(U32 id, Barrier* barrier);
+
+	/// @name Accessors
+	/// @{
+	U32 getId() const
+	{
+		return id;
+	}
+	/// @}
+
+	/// Assign new job to the thread
+	void assignNewJob(ThreadJob* job);
+
+private:
+	U32 id = 0; ///< An ID
+	std::thread thread; ///< Runs the workingFunc
+	std::mutex mutex; ///< Protect the ThreadWorker::job
+	std::condition_variable condVar; ///< To wake up the thread
+	Barrier* barrier = nullptr; ///< For synchronization
+	ThreadJob* job = nullptr; ///< Its NULL if there are no pending job
+
+	/// Start thread
+	void start()
+	{
+		thread = std::thread(&ThreadWorker::workingFunc, this);
+	}
+
+	/// Thread loop
+	void workingFunc();
+};
+
+/// Parallel job dispatcher.You feed it with jobs and sends them for
+/// execution in parallel and then waits for all to finish
+class ThreadPool
+{
+public:
+	/// Default constructor
+	ThreadPool()
+	{}
+
+	/// Constructor #2
+	ThreadPool(uint threadsNum)
+	{
+		init(threadsNum);
+	}
+
+	/// Init the manager
+	void init(U threadsNum);
+
+	/// Assign a job to a working thread
+	void assignNewJob(uint jobId, ThreadJob* job)
+	{
+		jobs[jobId]->assignNewJob(job);
+	}
+
+	/// Wait for all jobs to finish
+	void waitForAllJobsToFinish()
+	{
+		barrier->wait();
+	}
+
+	uint getThreadsNum() const
+	{
+		return jobs.size();
+	}
+
+private:
+	PtrVector<ThreadWorker> jobs; ///< Worker threads
+	std::unique_ptr<Barrier> barrier; ///< Synchronization barrier
+};
+
+/// Singleton
+typedef Singleton<ThreadPool> ThreadPoolSingleton;
+
+} // end namespace anki
+
+#endif

+ 2 - 2
include/anki/core/Timestamp.h

@@ -5,8 +5,8 @@
 
 
 namespace anki {
 namespace anki {
 
 
-/// Give the current timestamp. It actualy gives the current frame. Used to 
-/// indicate updates. It is actualy returning the current frame
+/// Give the current timestamp. It actually gives the current frame. Used to
+/// indicate updates. It is actually returning the current frame
 class Timestamp
 class Timestamp
 {
 {
 public:
 public:

+ 3 - 0
include/anki/renderer/Is.h

@@ -91,6 +91,9 @@ public: // XXX
 	/// Contains common data for all shader programs
 	/// Contains common data for all shader programs
 	Ubo commonUbo;
 	Ubo commonUbo;
 
 
+	/// Track the updates of commonUbo
+	U32 commonUboUpdateTimestamp = Timestamp::getTimestamp();
+
 	/// Contains info of all the lights
 	/// Contains info of all the lights
 	Ubo lightsUbo;
 	Ubo lightsUbo;
 
 

+ 5 - 2
include/anki/renderer/Renderer.h

@@ -193,16 +193,18 @@ public:
 	{
 	{
 		return planes;
 		return planes;
 	}
 	}
-
 	const Vec2& getLimitsOfNearPlane() const
 	const Vec2& getLimitsOfNearPlane() const
 	{
 	{
 		return limitsOfNearPlane;
 		return limitsOfNearPlane;
 	}
 	}
-
 	const Vec2& getLimitsOfNearPlane2() const
 	const Vec2& getLimitsOfNearPlane2() const
 	{
 	{
 		return limitsOfNearPlane2;
 		return limitsOfNearPlane2;
 	}
 	}
+	U32 getPlanesUpdateTimestamp() const
+	{
+		return planesUpdateTimestamp;
+	}
 
 
 	double getMsTime() const
 	double getMsTime() const
 	{
 	{
@@ -319,6 +321,7 @@ protected:
 	/// @name Optimization vars
 	/// @name Optimization vars
 	/// Used in other stages
 	/// Used in other stages
 	/// @{
 	/// @{
+	U32 planesUpdateTimestamp = Timestamp::getTimestamp();
 
 
 	/// Used to to calculate the frag pos in view space inside a few shader
 	/// Used to to calculate the frag pos in view space inside a few shader
 	/// programs
 	/// programs

+ 22 - 22
include/anki/scene/Frustumable.h

@@ -30,21 +30,21 @@ public:
 		return *frustum;
 		return *frustum;
 	}
 	}
 
 
-	float getNear() const
+	F32 getNear() const
 	{
 	{
 		return frustum->getNear();
 		return frustum->getNear();
 	}
 	}
-	void setNear(const float x)
+	void setNear(const F32 x)
 	{
 	{
 		frustum->setNear(x);
 		frustum->setNear(x);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
-	float getFar() const
+	F32 getFar() const
 	{
 	{
 		return frustum->getFar();
 		return frustum->getFar();
 	}
 	}
-	void setFar(const float x)
+	void setFar(const F32 x)
 	{
 	{
 		frustum->setFar(x);
 		frustum->setFar(x);
 		frustumUpdate();
 		frustumUpdate();
@@ -59,7 +59,7 @@ public:
 		return vinfo;
 		return vinfo;
 	}
 	}
 
 
-	uint32_t getFrustumableTimestamp() const
+	U32 getFrustumableTimestamp() const
 	{
 	{
 		return timestamp;
 		return timestamp;
 	}
 	}
@@ -93,7 +93,7 @@ protected:
 	VisibilityInfo vinfo;
 	VisibilityInfo vinfo;
 
 
 private:
 private:
-	uint32_t timestamp = Timestamp::getTimestamp();
+	U32 timestamp = Timestamp::getTimestamp();
 };
 };
 
 
 /// Perspective prustumable interface for scene nodes
 /// Perspective prustumable interface for scene nodes
@@ -111,28 +111,28 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	float getFovX() const
+	F32 getFovX() const
 	{
 	{
 		return get().getFovX();
 		return get().getFovX();
 	}
 	}
-	void setFovX(float ang)
+	void setFovX(F32 ang)
 	{
 	{
 		get().setFovX(ang);
 		get().setFovX(ang);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
-	float getFovY() const
+	F32 getFovY() const
 	{
 	{
 		return get().getFovY();
 		return get().getFovY();
 	}
 	}
-	void setFovY(float ang)
+	void setFovY(F32 ang)
 	{
 	{
 		get().setFovY(ang);
 		get().setFovY(ang);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	/// Set all the parameters and recalculate the planes and shape
 	/// Set all the parameters and recalculate the planes and shape
-	void setAll(float fovX_, float fovY_, float near_, float far_)
+	void setAll(F32 fovX_, F32 fovY_, F32 near_, F32 far_)
 	{
 	{
 		get().setAll(fovX_, fovY_, near_, far_);
 		get().setAll(fovX_, fovY_, near_, far_);
 		frustumUpdate();
 		frustumUpdate();
@@ -165,49 +165,49 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	float getLeft() const
+	F32 getLeft() const
 	{
 	{
 		return get().getLeft();
 		return get().getLeft();
 	}
 	}
-	void setLeft(float f)
+	void setLeft(F32 f)
 	{
 	{
 		get().setLeft(f);
 		get().setLeft(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
-	float getRight() const
+	F32 getRight() const
 	{
 	{
 		return get().getRight();
 		return get().getRight();
 	}
 	}
-	void setRight(float f)
+	void setRight(F32 f)
 	{
 	{
 		get().setRight(f);
 		get().setRight(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
-	float getTop() const
+	F32 getTop() const
 	{
 	{
 		return get().getTop();
 		return get().getTop();
 	}
 	}
-	void setTop(float f)
+	void setTop(F32 f)
 	{
 	{
 		get().setTop(f);
 		get().setTop(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
-	float getBottom() const
+	F32 getBottom() const
 	{
 	{
 		return get().getBottom();
 		return get().getBottom();
 	}
 	}
-	void setBottom(float f)
+	void setBottom(F32 f)
 	{
 	{
 		get().setBottom(f);
 		get().setBottom(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	/// Set all
 	/// Set all
-	void setAll(float left_, float right_, float near_,
-		float far_, float top_, float bottom_)
+	void setAll(F32 left_, F32 right_, F32 near_,
+		F32 far_, F32 top_, F32 bottom_)
 	{
 	{
 		get().setAll(left_, right_, near_, far_, top_, bottom_);
 		get().setAll(left_, right_, near_, far_, top_, bottom_);
 		frustumUpdate();
 		frustumUpdate();
@@ -226,6 +226,6 @@ private:
 };
 };
 /// @}
 /// @}
 
 
-} // namespace anki
+} // end namespace anki
 
 
 #endif
 #endif

+ 13 - 4
include/anki/scene/Scene.h

@@ -7,6 +7,7 @@
 #include "anki/util/Singleton.h"
 #include "anki/util/Singleton.h"
 #include "anki/scene/Sector.h"
 #include "anki/scene/Sector.h"
 #include "anki/util/Vector.h"
 #include "anki/util/Vector.h"
+#include "anki/core/Timestamp.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -40,13 +41,14 @@ public:
 	{
 	{
 		return ambientCol;
 		return ambientCol;
 	}
 	}
-	Vec3& getAmbientColor()
-	{
-		return ambientCol;
-	}
 	void setAmbientColor(const Vec3& x)
 	void setAmbientColor(const Vec3& x)
 	{
 	{
 		ambientCol = x;
 		ambientCol = x;
+		ambiendColorUpdateTimestamp = Timestamp::getTimestamp();
+	}
+	U32 getAmbientColorUpdateTimestamp() const
+	{
+		return ambiendColorUpdateTimestamp;
 	}
 	}
 
 
 	Camera& getActiveCamera()
 	Camera& getActiveCamera()
@@ -61,6 +63,11 @@ public:
 	void setActiveCamera(Camera* cam)
 	void setActiveCamera(Camera* cam)
 	{
 	{
 		mainCam = cam;
 		mainCam = cam;
+		activeCameraChangeTimestamp = Timestamp::getTimestamp();
+	}
+	U32 getActiveCameraChangeTimestamp() const
+	{
+		return activeCameraChangeTimestamp;
 	}
 	}
 
 
 	Types<SceneNode>::ConstIterator getAllNodesBegin() const
 	Types<SceneNode>::ConstIterator getAllNodesBegin() const
@@ -101,7 +108,9 @@ private:
 	Types<SceneNode>::Container nodes;
 	Types<SceneNode>::Container nodes;
 	Types<SceneNode>::NameToItemMap nameToNode;
 	Types<SceneNode>::NameToItemMap nameToNode;
 	Vec3 ambientCol = Vec3(1.0); ///< The global ambient color
 	Vec3 ambientCol = Vec3(1.0); ///< The global ambient color
+	U32 ambiendColorUpdateTimestamp = Timestamp::getTimestamp();
 	Camera* mainCam = nullptr;
 	Camera* mainCam = nullptr;
+	U32 activeCameraChangeTimestamp = Timestamp::getTimestamp();
 	VisibilityTester vtester;
 	VisibilityTester vtester;
 
 
 	/// Add to a container
 	/// Add to a container

+ 43 - 14
include/anki/util/Array.h

@@ -2,32 +2,61 @@
 #define ANKI_UTIL_ARRAY_H
 #define ANKI_UTIL_ARRAY_H
 
 
 #include "anki/util/Assert.h"
 #include "anki/util/Assert.h"
-#include <array>
+#include "anki/util/StdTypes.h"
 
 
 namespace anki {
 namespace anki {
 
 
 /// @addtogroup util
 /// @addtogroup util
 /// @{
 /// @{
-template<typename T, size_t size>
-class Array: public std::array<T, size>
+
+/// Array
+template<typename T, U N>
+struct Array
 {
 {
-public:
-	typedef std::array<T, size> Base;
+	typedef T Value;
+	typedef Value* Iterator;
+	typedef const Value* ConstIterator;
+	typedef Value& Reference;
+	typedef const Value& ConstReference;
+
+	Value data[N];
 
 
-#if !NDEBUG
-	typename Base::reference operator[](typename Base::size_type n)
+	Reference operator[](U n)
 	{
 	{
-		ANKI_ASSERT(n < Base::size());
-		return Base::operator[](n);
+		ANKI_ASSERT(n < N);
+		return data[n];
 	}
 	}
 
 
-	typename Base::const_reference operator[](
-		typename Base::size_type n) const
+	ConstReference operator[](U n) const
 	{
 	{
-		ANKI_ASSERT(n < Base::size());
-		return Base::operator[](n);
+		ANKI_ASSERT(n < N);
+		return data[n];
+	}
+
+	Iterator begin()
+	{
+		return &data[0];
+	}
+
+	ConstIterator begin() const
+	{
+		return &data[0];
+	}
+
+	Iterator end()
+	{
+		return &data[0] + N;
+	}
+
+	ConstIterator end() const
+	{
+		return &data[0] + N;
+	}
+
+	constexpr U getSize() const
+	{
+		return N;
 	}
 	}
-#endif
 };
 };
 /// @}
 /// @}
 
 

+ 7 - 3
shaders/IsLpGeneric.glsl

@@ -32,6 +32,8 @@ layout(std140, row_major, binding = 0) uniform commonBlock
 	/// limitsOfNearPlane and the zw is an optimization see PpsSsao.glsl and 
 	/// limitsOfNearPlane and the zw is an optimization see PpsSsao.glsl and 
 	/// r403 for the clean one
 	/// r403 for the clean one
 	uniform vec4 limitsOfNearPlane_;
 	uniform vec4 limitsOfNearPlane_;
+
+	uniform vec4 sceneAmbientColor;
 };
 };
 
 
 #define planes nearPlanes.zw
 #define planes nearPlanes.zw
@@ -168,7 +170,7 @@ void main()
 	// Lighting
 	// Lighting
 	uint lightsCount = tiles[vInstanceId].lightsCount;
 	uint lightsCount = tiles[vInstanceId].lightsCount;
 
 
-	fColor = diffuseAndSpec.rgb * 0.1;
+	fColor = diffuseAndSpec.rgb * sceneAmbientColor.rgb;
 	for(uint i = 0; i < lightsCount; ++i)
 	for(uint i = 0; i < lightsCount; ++i)
 	{
 	{
 		uint lightId = tiles[vInstanceId].lightIndices[i / 4][i % 4];
 		uint lightId = tiles[vInstanceId].lightIndices[i / 4][i % 4];
@@ -195,8 +197,10 @@ void main()
 	}
 	}
 #endif
 #endif
 
 
-	/*if(lightsCount > 0)
+#if 0
+	if(lightsCount > 0)
 	{
 	{
 		fColor += vec3(0.0, float(lightsCount) / 7.0, 0.0);
 		fColor += vec3(0.0, float(lightsCount) / 7.0, 0.0);
-	}*/
+	}
+#endif
 }
 }

+ 17 - 19
src/core/ParallelManager.cpp → src/core/ThreadPool.cpp

@@ -1,51 +1,49 @@
-#include "anki/core/ParallelManager.h"
+#include "anki/core/ThreadPool.h"
 
 
 namespace anki {
 namespace anki {
 
 
 //==============================================================================
 //==============================================================================
-// ParallelJob                                                                 =
+// ThreadWorker                                                                =
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-ParallelJob::ParallelJob(uint32_t id_, const ParallelManager* manager_,
-	Barrier* barrier_)
-	: id(id_), barrier(barrier_), callback(nullptr), manager(manager_)
+ThreadWorker::ThreadWorker(U32 id_, Barrier* barrier_)
+	: id(id_), barrier(barrier_)
 {
 {
 	start();
 	start();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void ParallelJob::assignNewJob(ParallelJobCallback callback_,
-	ParallelJobParameters& jobParams_)
+void ThreadWorker::assignNewJob(ThreadJob* job_)
 {
 {
 	mutex.lock();
 	mutex.lock();
-	callback = callback_;
-	params = &jobParams_;
+	ANKI_ASSERT(job == nullptr);
+	job = job_;
 	mutex.unlock();
 	mutex.unlock();
-	condVar.notify_one();
+	condVar.notify_one(); // Wake the thread
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void ParallelJob::workingFunc()
+void ThreadWorker::workingFunc()
 {
 {
 	while(1)
 	while(1)
 	{
 	{
 		// Wait for something
 		// Wait for something
 		{
 		{
 			std::unique_lock<std::mutex> lock(mutex);
 			std::unique_lock<std::mutex> lock(mutex);
-			while(callback == nullptr)
+			while(job == nullptr)
 			{
 			{
 				condVar.wait(lock);
 				condVar.wait(lock);
 			}
 			}
 		}
 		}
 
 
 		// Exec
 		// Exec
-		callback(*params, *this);
+		(*job)();
 
 
 		// Nullify
 		// Nullify
 		{
 		{
 			std::lock_guard<std::mutex> lock(mutex);
 			std::lock_guard<std::mutex> lock(mutex);
-			callback = nullptr;
+			job = nullptr;
 		}
 		}
 
 
 		barrier->wait();
 		barrier->wait();
@@ -53,19 +51,19 @@ void ParallelJob::workingFunc()
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-// ParallelManager                                                             =
+// ThreadPool                                                                  =
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-void ParallelManager::init(uint threadsNum)
+void ThreadPool::init(U threadsNum)
 {
 {
 	barrier.reset(new Barrier(threadsNum + 1));
 	barrier.reset(new Barrier(threadsNum + 1));
 
 
-	for(uint i = 0; i < threadsNum; i++)
+	for(U i = 0; i < threadsNum; i++)
 	{
 	{
-		jobs.push_back(new ParallelJob(i, this, barrier.get()));
+		jobs.push_back(new ThreadWorker(i, barrier.get()));
 	}
 	}
 }
 }
 
 
 
 
-} // end namespace
+} // end namespace anki

+ 1 - 0
src/core/Timestamp.cpp

@@ -2,6 +2,7 @@
 
 
 namespace anki {
 namespace anki {
 
 
+// WARNING: If you change that prepare for allot of pain
 U32 Timestamp::timestamp = 1;
 U32 Timestamp::timestamp = 1;
 
 
 } // end namespace anki
 } // end namespace anki

+ 36 - 10
src/renderer/Is.cpp

@@ -3,6 +3,7 @@
 #include "anki/scene/Scene.h"
 #include "anki/scene/Scene.h"
 #include "anki/scene/Camera.h"
 #include "anki/scene/Camera.h"
 #include "anki/scene/Light.h"
 #include "anki/scene/Light.h"
+#include "anki/core/ThreadPool.h"
 
 
 #define BLEND_ENABLE 1
 #define BLEND_ENABLE 1
 
 
@@ -52,6 +53,17 @@ struct ShaderCommonUniforms
 {
 {
 	Vec4 nearPlanes;
 	Vec4 nearPlanes;
 	Vec4 limitsOfNearPlane;
 	Vec4 limitsOfNearPlane;
+	Vec4 sceneAmbientColor;
+};
+
+//==============================================================================
+
+/// XXX
+struct UbosUpdateJob: ThreadJob
+{
+	ShaderPointLights* pointLights;
+	PointLight* visibleLights;
+	U32 visibleLightsCount;
 };
 };
 
 
 //==============================================================================
 //==============================================================================
@@ -433,10 +445,11 @@ void Is::pointLightsPass()
 				}
 				}
 			}
 			}
 
 
-			if(lightsInTileCount > MAX_LIGHTS_PER_TILE)
+			/*if(lightsInTileCount > MAX_LIGHTS_PER_TILE)
 			{
 			{
-				throw ANKI_EXCEPTION("Too many lights per tile");
-			}
+				//throw ANKI_EXCEPTION("Too many lights per tile");
+				ANKI_LOGW("Too many lights per tile: " << lightsInTileCount);
+			}*/
 
 
 			tile.lightsCount = lightsInTileCount;
 			tile.lightsCount = lightsInTileCount;
 		}
 		}
@@ -494,14 +507,27 @@ void Is::run()
 	GlStateSingleton::get().disable(GL_BLEND);
 	GlStateSingleton::get().disable(GL_BLEND);
 
 
 	// Write common block
 	// Write common block
-	const Camera& cam = r->getScene().getActiveCamera();
-	ShaderCommonUniforms blk;
-	blk.nearPlanes = Vec4(cam.getNear(), 0.0, r->getPlanes().x(),
-		r->getPlanes().y());
-	blk.limitsOfNearPlane = Vec4(r->getLimitsOfNearPlane(),
-		r->getLimitsOfNearPlane2());
+	Scene& scene = r->getScene();
+	if(commonUboUpdateTimestamp < r->getPlanesUpdateTimestamp()
+		|| commonUboUpdateTimestamp < scene.getAmbientColorUpdateTimestamp()
+		|| commonUboUpdateTimestamp == 1)
+	{
+		const Camera& cam = scene.getActiveCamera();
+		ShaderCommonUniforms blk;
+		blk.nearPlanes = Vec4(cam.getNear(), 0.0, r->getPlanes().x(),
+			r->getPlanes().y());
+		blk.limitsOfNearPlane = Vec4(r->getLimitsOfNearPlane(),
+			r->getLimitsOfNearPlane2());
+		blk.sceneAmbientColor = Vec4(r->getScene().getAmbientColor(), 0.0);
+
+		commonUbo.write(&blk);
+
+		commonUboUpdateTimestamp = Timestamp::getTimestamp();
+	}
 
 
-	commonUbo.write(&blk);
+	commonUbo.setBinding(0);
+	lightsUbo.setBinding(1);
+	tilesUbo.setBinding(2);
 
 
 	// Update tiles
 	// Update tiles
 	updateTiles();
 	updateTiles();

+ 17 - 7
src/renderer/Renderer.cpp

@@ -64,18 +64,28 @@ void Renderer::init(const RendererInitializer& initializer)
 void Renderer::render(Scene& scene_)
 void Renderer::render(Scene& scene_)
 {
 {
 	scene = &scene_;
 	scene = &scene_;
-	const Camera& cam = scene->getActiveCamera();
+	Camera& cam = scene->getActiveCamera();
 
 
 	// Calc a few vars
 	// Calc a few vars
 	//
 	//
-	calcPlanes(Vec2(cam.getNear(), cam.getFar()), planes);
+	U32 camUpdateTimestamp = cam.getFrustumable()->getFrustumableTimestamp();
+	if(planesUpdateTimestamp < scene->getActiveCameraChangeTimestamp()
+		|| planesUpdateTimestamp < camUpdateTimestamp
+		|| planesUpdateTimestamp == 1)
+	{
+		calcPlanes(Vec2(cam.getNear(), cam.getFar()), planes);
+
+		ANKI_ASSERT(cam.getCameraType() == Camera::CT_PERSPECTIVE);
+		const PerspectiveCamera& pcam =
+			static_cast<const PerspectiveCamera&>(cam);
 
 
-	ANKI_ASSERT(cam.getCameraType() == Camera::CT_PERSPECTIVE);
-	const PerspectiveCamera& pcam = static_cast<const PerspectiveCamera&>(cam);
-	calcLimitsOfNearPlane(pcam, limitsOfNearPlane);
-	limitsOfNearPlane2 = limitsOfNearPlane * 2.0;
+		calcLimitsOfNearPlane(pcam, limitsOfNearPlane);
+		limitsOfNearPlane2 = limitsOfNearPlane * 2.0;
+
+		planesUpdateTimestamp = Timestamp::getTimestamp();
+	}
 
 
-	viewProjectionMat = cam.getProjectionMatrix() * cam.getViewMatrix();
+	viewProjectionMat = cam.getViewProjectionMatrix();
 
 
 	if(enableStagesProfilingFlag)
 	if(enableStagesProfilingFlag)
 	{
 	{

+ 9 - 16
testapp/Main.cpp

@@ -36,7 +36,7 @@
 #include "anki/event/MainRendererPpsHdrEvent.h"
 #include "anki/event/MainRendererPpsHdrEvent.h"
 #include "anki/resource/ShaderProgramPrePreprocessor.h"
 #include "anki/resource/ShaderProgramPrePreprocessor.h"
 #include "anki/resource/Material.h"
 #include "anki/resource/Material.h"
-#include "anki/core/ParallelManager.h"
+#include "anki/core/ThreadPool.h"
 #include "anki/core/Timestamp.h"
 #include "anki/core/Timestamp.h"
 
 
 using namespace anki;
 using namespace anki;
@@ -79,8 +79,8 @@ void init()
 		1.0));
 		1.0));
 
 
 	// lights
 	// lights
-	Vec3 lpos(-100.0, 0.0, 0.0);
-	for(int i = 0; i < 3; i++)
+	Vec3 lpos(-100.0, 0.0, -20.0);
+	for(int i = 0; i < 50; i++)
 	{
 	{
 		for(int j = 0; j < 10; j++)
 		for(int j = 0; j < 10; j++)
 		{
 		{
@@ -93,11 +93,11 @@ void init()
 			point->setSpecularColor(Vec4(0.0, 0.0, 1.0, 0.0));
 			point->setSpecularColor(Vec4(0.0, 0.0, 1.0, 0.0));
 			point->setLocalTranslation(lpos);
 			point->setLocalTranslation(lpos);
 
 
-			lpos.z() += 2.0;
+			lpos.z() += 4.0;
 		}
 		}
 
 
-		lpos.x() += 2.0;
-		lpos.z() = 0;
+		lpos.x() += 4.0;
+		lpos.z() = -20;
 	}
 	}
 
 
 
 
@@ -166,9 +166,6 @@ void execStdinScpripts()
 	}
 	}
 }
 }
 
 
-namespace anki {
-		extern U deletemeto; }
-
 //==============================================================================
 //==============================================================================
 void mainLoopExtra()
 void mainLoopExtra()
 {
 {
@@ -182,8 +179,6 @@ void mainLoopExtra()
 	static Movable* mover = SceneSingleton::get().getActiveCamera().getMovable();
 	static Movable* mover = SceneSingleton::get().getActiveCamera().getMovable();
 	Input& in = InputSingleton::get();
 	Input& in = InputSingleton::get();
 
 
-	SceneSingleton::get().setAmbientColor(Vec3(0.2));
-
 	if(in.getKey(SDL_SCANCODE_1))
 	if(in.getKey(SDL_SCANCODE_1))
 	{
 	{
 		mover = &SceneSingleton::get().getActiveCamera();
 		mover = &SceneSingleton::get().getActiveCamera();
@@ -218,9 +213,7 @@ void mainLoopExtra()
 
 
 	if(in.getKey(SDL_SCANCODE_P) == 1)
 	if(in.getKey(SDL_SCANCODE_P) == 1)
 	{
 	{
-		std::cout << "sdfffffffffffffffff" << std::endl;
-
-		deletemeto = !deletemeto;
+		SceneSingleton::get().getActiveCamera().getFrustumable()->setFar(250.0);
 	}
 	}
 
 
 	if(in.getKey(SDL_SCANCODE_UP)) mover->rotateLocalX(ang);
 	if(in.getKey(SDL_SCANCODE_UP)) mover->rotateLocalX(ang);
@@ -282,7 +275,7 @@ void mainLoop()
 
 
 		// Sleep
 		// Sleep
 		//
 		//
-#if 1
+#if 0
 		timer.stop();
 		timer.stop();
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		{
 		{
@@ -338,7 +331,7 @@ void initSubsystems(int argc, char* argv[])
 	StdinListenerSingleton::get().start();
 	StdinListenerSingleton::get().start();
 
 
 	// Parallel jobs
 	// Parallel jobs
-	ParallelManagerSingleton::get().init(4);
+	ThreadPoolSingleton::get().init(4);
 }
 }
 
 
 //==============================================================================
 //==============================================================================