浏览代码

Scene & alignment bugs

Panagiotis Christopoulos Charitos 12 年之前
父节点
当前提交
2e5f8b6eb4

+ 3 - 2
bench/Main.cpp

@@ -161,8 +161,9 @@ void initScene()
 
 	scene.setAmbientColor(Vec4(0.1, 0.05, 0.05, 0.0) * 2);
 
-	PerspectiveCamera* cam = new PerspectiveCamera(
-		"main_camera", &scene, nullptr, Movable::MF_NONE);
+	PerspectiveCamera* cam = nullptr;
+	scene.newSceneNode(
+		cam, "main_camera", &scene, nullptr, (U32)Movable::MF_NONE);
 
 	const F32 ang = 45.0;
 	cam->setAll(

+ 30 - 16
include/anki/scene/SceneGraph.h

@@ -94,22 +94,6 @@ public:
 		return activeCameraChangeTimestamp;
 	}
 
-	Types<SceneNode>::ConstIterator getSceneNodesBegin() const
-	{
-		return nodes.begin();
-	}
-	Types<SceneNode>::Iterator getSceneNodesBegin()
-	{
-		return nodes.begin();
-	}
-	Types<SceneNode>::ConstIterator getSceneNodesEnd() const
-	{
-		return nodes.end();
-	}
-	Types<SceneNode>::Iterator getSceneNodesEnd()
-	{
-		return nodes.end();
-	}
 	U32 getSceneNodesCount() const
 	{
 		return nodes.size();
@@ -148,6 +132,36 @@ public:
 	SceneNode& findSceneNode(const char* name);
 	SceneNode* tryFindSceneNode(const char* name);
 
+	/// Iterate the scene nodes using a lambda
+	template<typename Func>
+	void iterateSceneNodes(Func func)
+	{
+		for(SceneNode* psn : nodes)
+		{
+			func(*psn);
+		}
+	}
+
+	/// Iterate the scene nodes using a lambda
+	template<typename Func>
+	void iterateSceneNodes(PtrSize begin, PtrSize count, Func func)
+	{
+		ANKI_ASSERT(begin < nodes.size() && count <= nodes.size());
+		for(auto it = nodes.begin() + begin; it != nodes.begin() + count; it++)
+		{
+			func(*(*it));
+		}
+	}
+
+	/// Create a new SceneNode
+	template<typename Node, typename... Args>
+	void newSceneNode(Node*& node, Args&&... args)
+	{
+		SceneAllocator<Node> al = alloc;
+		node = al.allocate(1);
+		al.construct(node, std::forward<Args>(args)...);
+	}
+
 private:
 	SceneAllocator<U8> alloc;
 	SceneAllocator<U8> frameAlloc;

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

@@ -144,7 +144,7 @@ public:
 	}
 
 	/// Return the last frame the node was updated. It checks all components
-	U32 getLastUpdateFrame();
+	U32 getLastUpdateFrame() const;
 
 protected:
 	struct

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

@@ -185,7 +185,7 @@ inline bool operator!=(const Allocator<T1>&, const AnotherAllocator&)
 /// @tparam deallocationFlag If true then the allocator will try to deallocate
 ///                          the memory. This is extremely important to
 ///                          understand when it should be true. See notes
-/// @tparam alignmentBits Set the alighment in bits
+/// @tparam alignmentBytes Set the alighment in bytes
 ///
 /// @note The deallocationFlag can brake the allocator when the deallocations
 ///       are not in the correct order. For example when deallocationFlag==true
@@ -194,10 +194,10 @@ inline bool operator!=(const Allocator<T1>&, const AnotherAllocator&)
 /// @note Don't ever EVER remove the double copy constructor and the double
 ///       operator=. The compiler will create defaults
 template<typename T, Bool deallocationFlag = false,
-	U32 alignmentBits = StackMemoryPool::SAFE_ALIGNMENT>
+	U32 alignmentBytes = StackMemoryPool::SAFE_ALIGNMENT>
 class StackAllocator
 {
-	template<typename U, Bool deallocationFlag_, U32 alignmentBits_>
+	template<typename U, Bool deallocationFlag_, U32 alignmentBytes_>
 	friend class StackAllocator;
 
 public:
@@ -221,14 +221,14 @@ public:
 	/// Copy constructor
 	template<typename U>
 	StackAllocator(
-		const StackAllocator<U, deallocationFlag, alignmentBits>& b) throw()
+		const StackAllocator<U, deallocationFlag, alignmentBytes>& b) throw()
 	{
 		*this = b;
 	}
 	/// Constuctor with size
 	StackAllocator(size_type size) throw()
 	{
-		mpool.reset(new StackMemoryPool(size, alignmentBits));
+		mpool.reset(new StackMemoryPool(size, alignmentBytes));
 	}
 
 	/// Destructor
@@ -244,7 +244,7 @@ public:
 	/// Copy
 	template<typename U>
 	StackAllocator& operator=(
-		const StackAllocator<U, deallocationFlag, alignmentBits>& b)
+		const StackAllocator<U, deallocationFlag, alignmentBytes>& b)
 	{
 		mpool = b.mpool;
 		return *this;
@@ -338,7 +338,7 @@ public:
 	template<typename U>
 	struct rebind
 	{
-		typedef StackAllocator<U, deallocationFlag, alignmentBits> other;
+		typedef StackAllocator<U, deallocationFlag, alignmentBytes> other;
 	};
 
 	/// Reinit the allocator. All existing allocated memory will be lost
@@ -359,38 +359,38 @@ private:
 };
 
 /// Another allocator of the same type can deallocate from this one
-template<typename T1, typename T2, Bool deallocationFlag, U32 alignmentBits>
+template<typename T1, typename T2, Bool deallocationFlag, U32 alignmentBytes>
 inline bool operator==(
-	const StackAllocator<T1, deallocationFlag, alignmentBits>&,
-	const StackAllocator<T2, deallocationFlag, alignmentBits>&)
+	const StackAllocator<T1, deallocationFlag, alignmentBytes>&,
+	const StackAllocator<T2, deallocationFlag, alignmentBytes>&)
 {
 	return true;
 }
 
 /// Another allocator of the another type cannot deallocate from this one
 template<typename T1, typename AnotherAllocator, Bool deallocationFlag,
-	U32 alignmentBits>
+	U32 alignmentBytes>
 inline bool operator==(
-	const StackAllocator<T1, deallocationFlag, alignmentBits>&,
+	const StackAllocator<T1, deallocationFlag, alignmentBytes>&,
 	const AnotherAllocator&)
 {
 	return false;
 }
 
 /// Another allocator of the same type can deallocate from this one
-template<typename T1, typename T2, Bool deallocationFlag, U32 alignmentBits>
+template<typename T1, typename T2, Bool deallocationFlag, U32 alignmentBytes>
 inline bool operator!=(
-	const StackAllocator<T1, deallocationFlag, alignmentBits>&,
-	const StackAllocator<T2, deallocationFlag, alignmentBits>&)
+	const StackAllocator<T1, deallocationFlag, alignmentBytes>&,
+	const StackAllocator<T2, deallocationFlag, alignmentBytes>&)
 {
 	return false;
 }
 
 /// Another allocator of the another type cannot deallocate from this one
 template<typename T1, typename AnotherAllocator, Bool deallocationFlag,
-	U32 alignmentBits>
+	U32 alignmentBytes>
 inline bool operator!=(
-	const StackAllocator<T1, deallocationFlag, alignmentBits>&,
+	const StackAllocator<T1, deallocationFlag, alignmentBytes>&,
 	const AnotherAllocator&)
 {
 	return true;

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

@@ -27,14 +27,14 @@ public:
 #if ANKI_CPU_ARCH == ANKI_CPU_ARCH_INTEL
 		16
 #elif ANKI_CPU_ARCH == ANKI_CPU_ARCH_ARM
-		32
+		16
 #else
 #	error "See file"
 #endif
 		;
 
 	/// Default constructor
-	StackMemoryPool(PtrSize size, U32 alignmentBits = SAFE_ALIGNMENT);
+	StackMemoryPool(PtrSize size, U32 alignmentBytes = SAFE_ALIGNMENT);
 
 	/// Move
 	StackMemoryPool(StackMemoryPool&& other)

+ 4 - 6
src/renderer/Dbg.cpp

@@ -64,16 +64,14 @@ void Dbg::run()
 	drawer->setModelMatrix(Mat4::getIdentity());
 	//drawer->drawGrid();
 
-	for(auto it = scene.getSceneNodesBegin();
-		it != scene.getSceneNodesEnd(); it++)
+	scene.iterateSceneNodes([&](SceneNode& node)
 	{
-		SceneNode* node = *it;
-		Spatial* sp = node->getSpatial();
+		Spatial* sp = node.getSpatial();
 		if(bitsEnabled(DF_SPATIAL) && sp)
 		{
-			sceneDrawer->draw(*node);
+			sceneDrawer->draw(node);
 		}
-	}
+	});
 
 	// Draw sectors
 	for(const Sector* sector : scene.getSectorGroup().getSectors())

+ 1 - 1
src/scene/SceneNode.cpp

@@ -54,7 +54,7 @@ SceneAllocator<U8> SceneNode::getSceneFrameAllocator() const
 }
 
 //==============================================================================
-U32 SceneNode::getLastUpdateFrame()
+U32 SceneNode::getLastUpdateFrame() const
 {
 	U32 max = 0;
 

+ 26 - 29
src/scene/Visibility.cpp

@@ -36,7 +36,7 @@ struct SortSubspatialsFunctor
 struct VisibilityTestJob: ThreadJob
 {
 	U nodesCount = 0;
-	SceneGraph::Types<SceneNode>::Container::iterator nodes;
+	SceneGraph* scene = nullptr;
 	SceneNode* frustumableSn = nullptr;
 	Tiler* tiler = nullptr;
 	SceneFrameAllocator<U8> frameAlloc;
@@ -102,26 +102,25 @@ struct VisibilityTestJob: ThreadJob
 		Frustumable* frustumable = frustumableSn->getFrustumable();
 		ANKI_ASSERT(frustumable);
 
-		for(auto it = nodes + start; it != nodes + end; it++)
+		scene->iterateSceneNodes(start, end, [&](SceneNode& node)
 		{
-			SceneNode* node = *it;
+			Frustumable* fr = node.getFrustumable();
 
-			Frustumable* fr = node->getFrustumable();
 			// Skip if it is the same
 			if(ANKI_UNLIKELY(frustumable == fr))
 			{
-				continue;
+				return;
 			}
 
-			Spatial* sp = node->getSpatial();
+			Spatial* sp = node.getSpatial();
 			if(!sp)
 			{
-				continue;
+				return;
 			}
 
 			if(!frustumable->insideFrustum(*sp))
 			{
-				continue;
+				return;
 			}
 
 			// Hierarchical spatial => check subspatials
@@ -130,36 +129,36 @@ struct VisibilityTestJob: ThreadJob
 			if(!handleSubspatials(*frustumable, *sp, subSpatialIndices, 
 				subSpatialIndicesCount))
 			{
-				continue;
+				return;
 			}
 
 			// renderable
-			Renderable* r = node->getRenderable();
+			Renderable* r = node.getRenderable();
 			if(r)
 			{
 				visible->renderables.push_back(VisibleNode(
-					node, subSpatialIndices, subSpatialIndicesCount));
+					&node, subSpatialIndices, subSpatialIndicesCount));
 			}
 			else
 			{
-				Light* l = node->getLight();
+				Light* l = node.getLight();
 				if(l)
 				{
-					visible->lights.push_back(VisibleNode(node, nullptr, 0));
+					visible->lights.push_back(VisibleNode(&node, nullptr, 0));
 
 					if(l->getShadowEnabled() && fr)
 					{
-						testLight(*node);
+						testLight(node);
 					}
 				}
 				else
 				{
-					continue;
+					return;
 				}
 			}
 
 			sp->enableBits(Spatial::SF_VISIBLE_CAMERA);
-		} // end for
+		}); // end for
 	}
 
 	/// Test an individual light
@@ -174,26 +173,24 @@ struct VisibilityTestJob: ThreadJob
 
 		ref.setVisibilityTestResults(lvisible);
 
-		for(auto it = nodes; it != nodes + nodesCount; it++)
+		scene->iterateSceneNodes([&](SceneNode& node)
 		{
-			SceneNode* node = *it;
-
-			Frustumable* fr = node->getFrustumable();
+			Frustumable* fr = node.getFrustumable();
 			// Wont check the same
 			if(ANKI_UNLIKELY(&ref == fr))
 			{
-				continue;
+				return;
 			}
 
-			Spatial* sp = node->getSpatial();
+			Spatial* sp = node.getSpatial();
 			if(!sp)
 			{
-				continue;
+				return;
 			}
 
 			if(!ref.insideFrustum(*sp))
 			{
-				continue;
+				return;
 			}
 
 			// Hierarchical spatial => check subspatials
@@ -202,18 +199,18 @@ struct VisibilityTestJob: ThreadJob
 			if(!handleSubspatials(ref, *sp, subSpatialIndices, 
 				subSpatialIndicesCount))
 			{
-				continue;
+				return;
 			}
 
 			sp->enableBits(Spatial::SF_VISIBLE_LIGHT);
 
-			Renderable* r = node->getRenderable();
+			Renderable* r = node.getRenderable();
 			if(r)
 			{
 				lvisible->renderables.push_back(VisibleNode(
-					node, subSpatialIndices, subSpatialIndicesCount));
+					&node, subSpatialIndices, subSpatialIndicesCount));
 			}
-		}
+		}); // end lambda
 	}
 };
 
@@ -232,7 +229,7 @@ void doVisibilityTests(SceneNode& fsn, SceneGraph& scene,
 	for(U i = 0; i < threadPool.getThreadsCount(); i++)
 	{
 		jobs[i].nodesCount = scene.getSceneNodesCount();
-		jobs[i].nodes = scene.getSceneNodesBegin();
+		jobs[i].scene = &scene;
 		jobs[i].frustumableSn = &fsn;
 		jobs[i].tiler = &r.getTiler();
 		jobs[i].frameAlloc = scene.getFrameAllocator();

+ 12 - 8
src/util/Memory.cpp

@@ -1,6 +1,7 @@
 #include "anki/util/Memory.h"
 #include "anki/util/Assert.h"
 #include "anki/util/Exception.h"
+#include "anki/util/Functions.h"
 #include <limits>
 #include <cstdlib>
 #include <cstring>
@@ -14,15 +15,15 @@ struct MemoryBlockHeader
 };
 
 //==============================================================================
-StackMemoryPool::StackMemoryPool(PtrSize size, U32 alignmentBits)
-	: alignmentBytes(alignmentBits / 8), memsize(calcAlignSize(size))
+StackMemoryPool::StackMemoryPool(PtrSize size, U32 alignmentBytes_)
+	: alignmentBytes(alignmentBytes_), memsize(calcAlignSize(size))
 {
 	ANKI_ASSERT(memsize > 0);
 	memory = (U8*)::malloc(memsize);
 
 	if(memory != nullptr)
 	{
-		top = memory;
+		top = (U8*)calcAlignSize((PtrSize)memory);
 	}
 	else
 	{
@@ -71,7 +72,9 @@ void* StackMemoryPool::allocate(PtrSize size_) throw()
 	// memory is nullptr if moved
 	ANKI_ASSERT(memory != nullptr);
 
-	PtrSize size = calcAlignSize(size_ + sizeof(MemoryBlockHeader));
+	PtrSize memBlockSize = calcAlignSize(sizeof(MemoryBlockHeader));
+	PtrSize size = 
+		calcAlignSize(size_ + memBlockSize);
 
 	ANKI_ASSERT(size < std::numeric_limits<U32>::max() && "Too big allocation");
 
@@ -83,7 +86,7 @@ void* StackMemoryPool::allocate(PtrSize size_) throw()
 		((MemoryBlockHeader*)out)->size = size;
 
 		// Set the correct output
-		out += sizeof(MemoryBlockHeader);
+		out += memBlockSize;
 	}
 	else
 	{
@@ -101,7 +104,8 @@ Bool StackMemoryPool::free(void* ptr) throw()
 	ANKI_ASSERT(memory != nullptr);
 
 	// Correct the p
-	U8* realptr = (U8*)ptr - sizeof(MemoryBlockHeader);
+	PtrSize memBlockSize = calcAlignSize(sizeof(MemoryBlockHeader));
+	U8* realptr = (U8*)ptr - memBlockSize;
 
 	// realptr should be inside the pool's preallocated memory
 	ANKI_ASSERT(realptr >= memory && realptr < memory + memsize);
@@ -136,13 +140,13 @@ void StackMemoryPool::reset()
 	memset(memory, 0xCC, memsize);
 #endif
 
-	top = memory;
+	top = (U8*)calcAlignSize((PtrSize)memory);
 }
 
 //==============================================================================
 PtrSize StackMemoryPool::calcAlignSize(PtrSize size) const
 {
-	return (size + alignmentBytes - 1) & ~(alignmentBytes - 1);
+	return alignSizeRoundUp(alignmentBytes, size);
 }
 
 } // end namespace anki