ソースを参照

Removing Exceptions

Panagiotis Christopoulos Charitos 11 年 前
コミット
f32f9916cd
69 ファイル変更928 行追加531 行削除
  1. 4 4
      include/anki/gl/GlCommandBufferHandle.h
  2. 8 14
      include/anki/gl/GlProgram.h
  3. 5 8
      include/anki/gl/GlProgramHandle.h
  4. 10 0
      include/anki/renderer/Hdr.h
  5. 2 1
      include/anki/renderer/Ms.h
  6. 7 0
      include/anki/resource/Common.h
  7. 7 10
      include/anki/resource/Image.h
  8. 16 0
      include/anki/resource/TextureResource.h
  9. 6 0
      include/anki/scene/Light.h
  10. 13 13
      include/anki/util/Allocator.h
  11. 13 12
      include/anki/util/Array.h
  12. 179 0
      include/anki/util/DArray.h
  13. 1 0
      include/anki/util/File.h
  14. 32 24
      include/anki/util/Logger.h
  15. 1 6
      src/core/App.cpp
  16. 1 1
      src/core/CMakeLists.txt
  17. 1 1
      src/core/NativeWindowAndroid.cpp
  18. 1 1
      src/core/NativeWindowSdl.cpp
  19. 1 1
      src/event/SceneAmbientColorEvent.cpp
  20. 1 1
      src/gl/GlBuffer.cpp
  21. 1 1
      src/gl/GlCommandBuffer.cpp
  22. 34 34
      src/gl/GlCommandBufferHandle.cpp
  23. 1 1
      src/gl/GlError.cpp
  24. 1 1
      src/gl/GlFramebuffer.cpp
  25. 64 42
      src/gl/GlProgram.cpp
  26. 18 8
      src/gl/GlProgramHandle.cpp
  27. 1 1
      src/gl/GlProgramPipeline.cpp
  28. 1 1
      src/gl/GlQueue.cpp
  29. 1 1
      src/gl/GlState.cpp
  30. 1 1
      src/gl/GlSync.cpp
  31. 9 7
      src/gl/GlTexture.cpp
  32. 1 1
      src/input/InputAndroid.cpp
  33. 1 1
      src/input/InputSdl.cpp
  34. 11 10
      src/renderer/Dbg.cpp
  35. 1 1
      src/renderer/DebugDrawer.cpp
  36. 4 3
      src/renderer/Drawer.cpp
  37. 2 1
      src/renderer/Hdr.cpp
  38. 20 15
      src/renderer/Is.cpp
  39. 17 14
      src/renderer/Lf.cpp
  40. 4 3
      src/renderer/MainRenderer.cpp
  41. 15 10
      src/renderer/Ms.cpp
  42. 4 3
      src/renderer/Pps.cpp
  43. 14 10
      src/renderer/Renderer.cpp
  44. 16 14
      src/renderer/RenderingPass.cpp
  45. 4 3
      src/renderer/Sm.cpp
  46. 32 26
      src/renderer/Ssao.cpp
  47. 9 8
      src/renderer/Sslr.cpp
  48. 4 3
      src/renderer/Tiler.cpp
  49. 1 1
      src/resource/AsyncLoader.cpp
  50. 247 106
      src/resource/Image.cpp
  51. 1 1
      src/resource/Material.cpp
  52. 1 1
      src/resource/MaterialProgramCreator.cpp
  53. 1 1
      src/resource/MeshLoader.cpp
  54. 1 1
      src/resource/Model.cpp
  55. 1 1
      src/resource/ResourceManager.cpp
  56. 2 0
      src/resource/TextureResource.cpp
  57. 1 1
      src/scene/Octree.cpp
  58. 1 1
      src/scene/RenderComponent.cpp
  59. 1 1
      src/scene/Sector.cpp
  60. 1 1
      src/scene/Visibility.cpp
  61. 1 1
      src/script/LuaBinder.cpp
  62. 1 1
      src/script/ScriptManager.cpp
  63. 1 1
      src/ui/UiFtFontLoader.cpp
  64. 1 1
      src/ui/UiPainter.cpp
  65. 1 1
      src/util/CMakeLists.txt
  66. 12 12
      src/util/File.cpp
  67. 51 75
      src/util/Logger.cpp
  68. 0 1
      src/util/Memory.cpp
  69. 1 1
      testapp/Main.cpp

+ 4 - 4
include/anki/gl/GlCommandBufferHandle.h

@@ -131,10 +131,10 @@ public:
 	void setPolygonMode(GLenum face, GLenum mode);
 
 	/// Bind many textures
-	/// @param first The unit where the first texture will be bound
-	/// @param textures A list of textures to bind
-	void bindTextures(U32 first, 
-		const std::initializer_list<GlTextureHandle>& textures);
+	/// @param first The unit where the first texture will be bound.
+	/// @param textures The array of textures.
+	/// @param count The count of textures
+	void bindTextures(U32 first, GlTextureHandle textures[], U32 count);
 	/// @}
 
 	/// @name Drawcalls

+ 8 - 14
include/anki/gl/GlProgram.h

@@ -8,7 +8,7 @@
 
 #include "anki/gl/GlObject.h"
 #include "anki/util/Dictionary.h"
-#include "anki/util/Vector.h"
+#include "anki/util/DArray.h"
 
 namespace anki {
 
@@ -29,11 +29,7 @@ public:
 	using Base = GlObject;
 
 	template<typename T>
-	using ProgramVector = Vector<T, GlAllocator<T>>;
-
-	template<typename T>
-	using ProgramDictionary = 
-		Dictionary<T, GlAllocator<std::pair<CString, T>>>;
+	using DArray = DArray<T, GlAllocator<T>>;
 
 	GlProgram() = default;
 
@@ -58,13 +54,13 @@ public:
 		return m_type;
 	}
 
-	const ProgramVector<GlProgramVariable>& getVariables() const
+	const DArray<GlProgramVariable>& getVariables() const
 	{
 		ANKI_ASSERT(isCreated());
 		return m_variables;
 	}
 
-	const ProgramVector<GlProgramBlock>& getBlocks() const
+	const DArray<GlProgramBlock>& getBlocks() const
 	{
 		ANKI_ASSERT(isCreated());
 		return m_blocks;
@@ -75,14 +71,12 @@ public:
 
 private:
 	GLenum m_type;
-	ProgramVector<GlProgramVariable> m_variables;
-	ProgramDictionary<GlProgramVariable*> m_variablesDict;
-
-	ProgramVector<GlProgramBlock> m_blocks;
-	ProgramDictionary<GlProgramBlock*> m_blocksDict;
+	GlAllocator<U8> m_alloc;
+	DArray<GlProgramVariable> m_variables;
+	DArray<GlProgramBlock> m_blocks;
 
 	/// Keep all the names of blocks and variables in a single place
-	char* m_names = nullptr;
+	DArray<char> m_names;
 
 	void destroy();
 

+ 5 - 8
include/anki/gl/GlProgramHandle.h

@@ -7,7 +7,6 @@
 #define ANKI_GL_GL_PROGRAM_HANDLE_H
 
 #include "anki/gl/GlContainerHandle.h"
-#include "anki/util/Vector.h"
 
 namespace anki {
 
@@ -24,10 +23,6 @@ class GlProgramHandle: public GlContainerHandle<GlProgram>
 public:
 	using Base = GlContainerHandle<GlProgram>;
 
-	// Re-define it here
-	template<typename T>
-	using ProgramVector = Vector<T, GlAllocator<T>>;
-
 	GlProgramHandle();
 
 	~GlProgramHandle();
@@ -37,13 +32,15 @@ public:
 		GLenum shaderType, const GlClientBufferHandle& source);
 
 	/// @name Accessors
-	/// They will sync
+	/// They will sync client with server.
 	/// @{
 	GLenum getType() const;
 
-	const ProgramVector<GlProgramVariable>& getVariables() const;
+	const GlProgramVariable* getVariablesBegin() const;
+	const GlProgramVariable* getVariablesEnd() const;
 
-	const ProgramVector<GlProgramBlock>& getBlocks() const;
+	const GlProgramBlock* getBlocksBegin() const;
+	const GlProgramBlock* getBlocksEnd() const;
 
 	const GlProgramVariable* tryFindVariable(const CString& name) const;
 

+ 10 - 0
include/anki/renderer/Hdr.h

@@ -54,6 +54,16 @@ public:
 	{
 		return m_vblurRt;
 	}
+
+	U32 _getWidth() const
+	{
+		return m_width;
+	}
+
+	U32 _getHeight() const
+	{
+		return m_height;
+	}
 	/// @}
 
 private:

+ 2 - 1
include/anki/renderer/Ms.h

@@ -62,7 +62,8 @@ private:
 	};
 
 	GlTextureHandle m_smallDepthRt; ///< A smaller depth buffer
-	GlFramebufferHandle m_smallDepthFb;
+	GlFramebufferHandle m_smallDepthFb; ///< Used to blit
+	UVec2 m_smallDepthSize;
 
 	Ez m_ez; /// EarlyZ pass
 

+ 7 - 0
include/anki/resource/Common.h

@@ -8,6 +8,7 @@
 
 #include "anki/util/Allocator.h"
 #include "anki/util/Vector.h"
+#include "anki/util/DArray.h"
 #include "anki/util/String.h"
 
 namespace anki {
@@ -25,6 +26,9 @@ using ResourceAllocator = HeapAllocator<T>;
 template<typename T>
 using ResourceVector = Vector<T, ResourceAllocator<T>>;
 
+template<typename T>
+using ResourceDArray = DArray<T, ResourceAllocator<T>>;
+
 using ResourceString = StringBase<ResourceAllocator<char>>;
 
 template<typename T>
@@ -33,6 +37,9 @@ using TempResourceAllocator = StackAllocator<T>;
 template<typename T>
 using TempResourceVector = Vector<T, TempResourceAllocator<T>>;
 
+template<typename T>
+using TempResourceDArray = DArray<T, TempResourceAllocator<T>>;
+
 using TempResourceString = StringBase<TempResourceAllocator<char>>;
 
 /// Contains initialization information for the resource classes.

+ 7 - 10
include/anki/resource/Image.h

@@ -8,7 +8,6 @@
 
 #include "anki/resource/Common.h"
 #include "anki/util/Functions.h"
-#include "anki/util/Vector.h"
 #include "anki/util/Enum.h"
 
 namespace anki {
@@ -51,18 +50,14 @@ public:
 	class Surface
 	{
 	public:
-		Surface(ResourceAllocator<U8>& alloc)
-		:	m_data(alloc)
-		{}
-
 		U32 m_width;
 		U32 m_height;
 		U32 m_mipLevel;
-		ResourceVector<U8> m_data;
+		ResourceDArray<U8> m_data;
 	};
 
 	Image(ResourceAllocator<U8>& alloc)
-	:	m_surfaces(alloc)
+	:	m_alloc(alloc)
 	{}
 
 	ColorFormat getColorFormat() const
@@ -99,18 +94,20 @@ public:
 
 	ResourceAllocator<U8> getAllocator() const
 	{
-		return m_surfaces.get_allocator();
+		return m_alloc;
 	}
 
 	/// Load an image file
 	/// @param[in] filename The file to load
 	/// @param[in] maxTextureSize Only load mipmaps less or equal to that. Used
 	///                           with AnKi textures
-	void load(const CString& filename, U32 maxTextureSize = MAX_U32);
+	ANKI_USE_RESULT Error load(
+		const CString& filename, U32 maxTextureSize = MAX_U32);
 
 private:
+	ResourceAllocator<U8> m_alloc;
 	/// [mip][depthFace]
-	ResourceVector<Surface> m_surfaces;
+	ResourceDArray<Surface> m_surfaces;
 	U8 m_mipLevels = 0;
 	U8 m_depth = 0;
 	DataCompression m_compression = DataCompression::NONE;

+ 16 - 0
include/anki/resource/TextureResource.h

@@ -43,8 +43,24 @@ public:
 		return m_tex;
 	}
 
+	U32 getWidth() const
+	{
+		return m_size.x();
+	}
+
+	U32 getHeight() const
+	{
+		return m_size.y();
+	}
+
+	U32 getDepth() const
+	{
+		return m_size.z();
+	}
+
 private:
 	GlTextureHandle m_tex;
+	UVec3 m_size;
 
 	/// Load a texture
 	void loadInternal(const CString& filename, ResourceInitializer& init);

+ 6 - 0
include/anki/scene/Light.h

@@ -155,6 +155,12 @@ public:
 		return m_flaresTex->getGlTexture();
 	}
 
+	U32 getLensFlareTextureDepth() const
+	{
+		ANKI_ASSERT(hasLensFlare());
+		return m_flaresTex->getDepth();
+	}
+
 	const Vec2& getLensFlaresSize() const
 	{
 		return m_flaresSize;

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

@@ -9,6 +9,7 @@
 #include "anki/util/Exception.h"
 #include "anki/util/Assert.h"
 #include "anki/util/Memory.h"
+#include "anki/util/Logger.h"
 #include <cstddef> // For ptrdiff_t
 #include <utility> // For forward
 
@@ -47,18 +48,18 @@ class GenericPoolAllocator
 
 public:
 	// Typedefs
-	typedef size_t size_type;
-	typedef ptrdiff_t difference_type;
-	typedef T* pointer;
-	typedef const T* const_pointer;
-	typedef T& reference;
-	typedef const T& const_reference;
-	typedef T value_type;
+	using size_type = size_t;
+	using difference_type = ptrdiff_t;
+	using pointer = T*;
+	using const_pointer = const T*;
+	using reference = T&;
+	using const_reference = const T&;
+	using value_type = T;
 
 	/// Move assignments between containers will copy the allocator as well. 
 	/// If propagate_on_container_move_assignment is not defined then not moves
 	/// are going to happen
-	typedef std::true_type propagate_on_container_move_assignment;
+	using propagate_on_container_move_assignment = std::true_type;
 
 	/// A struct to rebind the allocator to another allocator of type U
 	template<typename Y>
@@ -96,7 +97,7 @@ public:
 
 		if(error)
 		{
-			throw ANKI_EXCEPTION("Initialization failed");
+			ANKI_LOGF("Initialization failed");
 		}
 	}
 
@@ -152,10 +153,10 @@ public:
 
 		if(out == nullptr)
 		{
-			throw ANKI_EXCEPTION("Allocation failed. There is not enough room");
+			ANKI_LOGE("Allocation failed. There is not enough room");
 		}
 
-		return (pointer)out;
+		return reinterpret_cast<pointer>(out);
 	}
 
 	/// Deallocate memory
@@ -167,8 +168,7 @@ public:
 
 		if(checkFree && !ok)
 		{
-			throw ANKI_EXCEPTION("Freeing wrong pointer. "
-				"Pool's free returned false");
+			ANKI_LOGE("Freeing wrong pointer. Pool's free() returned false");
 		}
 	}
 

+ 13 - 12
include/anki/util/Array.h

@@ -16,19 +16,20 @@ namespace anki {
 
 /// Like std::array but with some additions
 template<typename T, PtrSize N>
-struct Array
+class Array
 {
-	typedef T Value;
-	typedef Value* Iterator;
-	typedef const Value* ConstIterator;
-	typedef Value& Reference;
-	typedef const Value& ConstReference;
-
-	// std compatible
-	typedef Iterator iterator;
-	typedef ConstIterator const_iterator;
-	typedef Reference reference;
-	typedef ConstReference const_reference;
+public:
+	using Value = T;
+	using Iterator = Value*;
+	using ConstIterator = const Value*;
+	using Reference = Value&;
+	using ConstReference = const Value&;
+
+	// STL compatible
+	using iterator = Iterator;
+	using const_iterator = ConstIterator;
+	using reference = Reference;
+	using const_reference = ConstReference;
 
 	Value m_data[N];
 

+ 179 - 0
include/anki/util/DArray.h

@@ -0,0 +1,179 @@
+// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#ifndef ANKI_UTIL_D_ARRAY_H
+#define ANKI_UTIL_D_ARRAY_H
+
+#include "anki/util/Allocator.h"
+#include "anki/util/NonCopyable.h"
+
+namespace anki {
+
+/// @addtogroup util_containers
+/// @{
+
+/// Dynamic array.
+template<typename T, typename TAlloc = HeapAllocator<T>>
+class DArray: public NonCopyable
+{
+public:
+	using Value = T;
+	using Allocator = TAlloc;
+	using Iterator = Value*;
+	using ConstIterator = const Value*;
+	using Reference = Value&;
+	using ConstReference = const Value&;
+
+	// STL compatible
+	using iterator = Iterator;
+	using const_iterator = ConstIterator;
+	using reference = Reference;
+	using const_reference = ConstReference;
+
+	DArray()
+	:	m_data(nullptr),
+		m_size(0)
+	{}
+
+	DArray(DArray&& b)
+	:	DArray()
+	{
+		move(b);
+	}
+
+	~DArray()
+	{
+		ANKI_ASSERT(m_data == nullptr && m_size == 0 
+			&& "Requires manual destruction");
+	}
+
+	DArray& operator=(DArray&& b)
+	{
+		move(b);
+		return *this;
+	}
+
+	Reference operator[](const PtrSize n)
+	{
+		ANKI_ASSERT(n < m_size);
+		return m_data[n];
+	}
+
+	ConstReference operator[](const PtrSize n) const
+	{
+		ANKI_ASSERT(n < m_size);
+		return m_data[n];
+	}
+
+	/// Make it compatible with the C++11 range based for loop.
+	Iterator begin()
+	{
+		return &m_data[0];
+	}
+
+	/// Make it compatible with the C++11 range based for loop.
+	ConstIterator begin() const
+	{
+		return &m_data[0];
+	}
+
+	/// Make it compatible with the C++11 range based for loop.
+	Iterator end()
+	{
+		return &m_data[0] + m_size;
+	}
+
+	/// Make it compatible with the C++11 range based for loop.
+	ConstIterator end() const
+	{
+		return &m_data[0] + m_size;
+	}
+
+	/// Make it compatible with STL.
+	Reference front() 
+	{
+		return m_data[0];
+	}
+
+	/// Make it compatible with STL.
+	ConstReference front() const
+	{
+		return m_data[0];
+	}
+
+	/// Make it compatible with STL.
+	Reference back() 
+	{
+		return m_data[m_size - 1];
+	}
+
+	/// Make it compatible with STL.
+	ConstReference back() const
+	{
+		return m_data[m_size - 1];
+	}
+
+	PtrSize getSize() const
+	{
+		return m_size;
+	}
+
+	/// Create the array.
+	ANKI_USE_RESULT Error create(Allocator alloc, PtrSize size)
+	{
+		ANKI_ASSERT(m_data == nullptr && m_size == 0);
+		ANKI_ASSERT(size);
+		Error err = ErrorCode::NONE;
+
+		destroy(alloc);
+
+		m_data = alloc.template newArray<Value>(size);
+		if(m_data)
+		{
+			m_size = size;
+		}
+		else
+		{
+			err = ErrorCode::OUT_OF_MEMORY;
+		}
+
+		return err;
+	}
+
+	/// Destroy the array.
+	void destroy(Allocator alloc)
+	{
+		if(m_data)
+		{
+			ANKI_ASSERT(m_size > 0);
+			alloc.deleteArray(m_data, m_size);
+
+			m_data = nullptr;
+			m_size = 0;
+		}
+
+		ANKI_ASSERT(m_data == nullptr && m_size == 0);
+	}
+
+private:
+	Value* m_data;
+	U32 m_size;
+
+	void move(DArray& b)
+	{
+		ANKI_ASSERT(m_data == nullptr && m_size == 0
+			&& "Cannot move before destroying");
+		m_data = b.m_data;
+		b.m_data = nullptr;
+		m_size = b.m_size;
+		b.m_size = 0;
+	}
+};
+
+/// @}
+
+} // end namespace anki
+
+#endif

+ 1 - 0
include/anki/util/File.h

@@ -9,6 +9,7 @@
 #include "anki/util/String.h"
 #include "anki/util/Enum.h"
 #include "anki/util/NonCopyable.h"
+#include <cstdio>
 
 namespace anki {
 

+ 32 - 24
include/anki/core/Logger.h → include/anki/util/Logger.h

@@ -3,18 +3,19 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_CORE_LOGGER_H
-#define ANKI_CORE_LOGGER_H
+#ifndef ANKI_UTIL_LOGGER_H
+#define ANKI_UTIL_LOGGER_H
 
 #include "anki/Config.h"
 #include "anki/util/Singleton.h"
-#include "anki/util/File.h"
 #include "anki/util/Thread.h"
-#include "anki/util/Enum.h"
 
 namespace anki {
 
-/// @addtogroup core
+// Forward
+class File;
+
+/// @addtogroup util_other
 /// @{
 
 /// The logger singleton class. The logger cannot print errors or throw
@@ -29,18 +30,11 @@ public:
 	{
 		NORMAL,
 		ERROR,
-		WARNING
+		WARNING,
+		FATAL,
+		COUNT
 	};
 
-	/// Logger init mask
-	enum class InitFlags: U8
-	{
-		NONE = 0,
-		WITH_SYSTEM_MESSAGE_HANDLER = 1 << 0,
-		WITH_LOG_FILE_MESSAGE_HANDLER  = 1 << 1
-	};
-	ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(InitFlags, friend);
-
 	/// Used as parammeter when emitting the signal
 	class Info
 	{
@@ -55,14 +49,17 @@ public:
 	/// The message handler callback
 	using MessageHandlerCallback = void (*)(void*, const Info& info);
 
-	/// Initialize the logger
-	Logger(InitFlags flags, HeapAllocator<U8>& alloc, const char* cacheDir);
+	/// Initialize the logger and add the default message handler
+	Logger();
 
 	~Logger();
 
 	/// Add a new message handler
 	void addMessageHandler(void* data, MessageHandlerCallback callback);
 
+	/// Add file message handler.
+	void addFileMessageHandler(File* file);
+
 	/// Send a message
 	void write(const char* file, int line, const char* func,
 		MessageType type, const char* msg);
@@ -75,20 +72,28 @@ private:
 	class Handler
 	{
 	public:
-		void* m_data;
-		MessageHandlerCallback m_callback;
+		void* m_data = nullptr;
+		MessageHandlerCallback m_callback = nullptr;
+
+		Handler() = default;
+
+		Handler(const Handler&) = default;
+
+		Handler(void* data, MessageHandlerCallback callback)
+		:	m_data(data),
+			m_callback(callback)
+		{}
 	};
 
 	Mutex m_mutex; ///< For thread safety
-	Vector<Handler> m_handlers;
-	File m_logfile;
-	char* m_cacheDir = nullptr;
+	Array<Handler, 4> m_handlers;
+	U32 m_handlersCount = 0;
 	
 	static void defaultSystemMessageHandler(void*, const Info& info);
-	static void logfileMessageHandler(void* vlogger, const Info& info);
+	static void fileMessageHandler(void* file, const Info& info);
 };
 
-typedef SingletonInit<Logger> LoggerSingleton;
+typedef Singleton<Logger> LoggerSingleton;
 /// @}
 
 } // end namespace
@@ -113,4 +118,7 @@ typedef SingletonInit<Logger> LoggerSingleton;
 #define ANKI_LOGE(...) ANKI_LOGGER_MESSAGE(Logger::MessageType::ERROR, \
 	__VA_ARGS__)
 
+#define ANKI_LOGF(...) ANKI_LOGGER_MESSAGE(Logger::MessageType::FATAL, \
+	__VA_ARGS__)
+
 #endif

+ 1 - 6
src/core/App.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/core/App.h"
 #include "anki/misc/ConfigSet.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/util/Exception.h"
 #include "anki/util/File.h"
 #include "anki/util/Filesystem.h"
@@ -117,11 +117,6 @@ void App::init(const ConfigSet& config_)
 
 	initDirs();
 
-	// Logger
-	LoggerSingleton::init(
-		Logger::InitFlags::WITH_SYSTEM_MESSAGE_HANDLER, m_heapAlloc,
-		&m_cacheDir[0]);
-
 	// Print a message
 	String msg(getAllocator());
 	msg.sprintf(

+ 1 - 1
src/core/CMakeLists.txt

@@ -1,4 +1,4 @@
-set(ANKI_CORE_SOURCES App.cpp Logger.cpp StdinListener.cpp Timestamp.cpp Counters.cpp Config.cpp)
+set(ANKI_CORE_SOURCES App.cpp StdinListener.cpp Timestamp.cpp Counters.cpp Config.cpp)
 
 if(${ANKI_WINDOW_BACKEND} STREQUAL "GLXX11")
 	set(ANKI_CORE_SOURCES ${ANKI_CORE_SOURCES} NativeWindowGlxX11.cpp)

+ 1 - 1
src/core/NativeWindowAndroid.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/core/NativeWindowAndroid.h"
 #include "anki/core/App.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/util/Exception.h"
 #include "anki/util/Array.h"
 #include "anki/util/StdTypes.h"

+ 1 - 1
src/core/NativeWindowSdl.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/core/NativeWindowSdl.h"
 #include "anki/core/Counters.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/util/Exception.h"
 #include <GL/glew.h>
 

+ 1 - 1
src/event/SceneAmbientColorEvent.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/event/SceneAmbientColorEvent.h"
 #include "anki/scene/SceneGraph.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 1 - 1
src/gl/GlBuffer.cpp

@@ -7,7 +7,7 @@
 #include "anki/gl/GlBuffer.h"
 #include "anki/gl/GlError.h"
 #include "anki/util/Exception.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include <cmath>
 
 namespace anki {

+ 1 - 1
src/gl/GlCommandBuffer.cpp

@@ -7,7 +7,7 @@
 #include "anki/gl/GlQueue.h"
 #include "anki/gl/GlDevice.h"
 #include "anki/gl/GlError.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/core/Counters.h"
 #include <cstring>
 

+ 34 - 34
src/gl/GlCommandBufferHandle.cpp

@@ -9,7 +9,6 @@
 #include "anki/gl/GlFramebuffer.h"
 #include "anki/gl/GlTextureHandle.h"
 #include "anki/gl/GlTexture.h"
-#include "anki/util/Vector.h"
 #include "anki/core/Counters.h"
 #include <utility>
 
@@ -415,50 +414,51 @@ void GlCommandBufferHandle::setPolygonMode(GLenum face, GLenum mode)
 }
 
 //==============================================================================
-void GlCommandBufferHandle::bindTextures(U32 first, 
-	const std::initializer_list<GlTextureHandle>& textures)
+class BindTexturesCommand: public GlCommand
 {
-	using Vec = 
-		Vector<GlTextureHandle, GlCommandBufferAllocator<GlTextureHandle>>;
-		
-	class Command: public GlCommand
-	{
-	public:
-		Vec m_texes;
-		U32 m_first;
+public:
+	static const U MAX_BIND_TEXTURES = 8;
 
-		Command(Vec& texes, U32 first)
-			: m_first(first)
-		{
-			m_texes = std::move(texes);
-		}
+	Array<GlTextureHandle, MAX_BIND_TEXTURES> m_texes;
+	U32 m_texCount;
+	U32 m_first;
 
-		Error operator()(GlCommandBuffer* commands)
+	BindTexturesCommand(
+		GlTextureHandle textures[], U count, U32 first)
+	:	m_first(first)
+	{
+		m_texCount = count;
+		GlTextureHandle* t = textures;
+		while(count-- != 0)
 		{
-			Array<GLuint, 16> names;
-
-			U count = 0;
-			for(GlTextureHandle& t : m_texes)
-			{
-				names[count++] = t._get().getGlName();
-			}
+			m_texes[count] = *t;
+			++t;
+		}
+	}
 
-			ANKI_ASSERT(count > 0);
-			glBindTextures(m_first, count, &names[0]);
+	Error operator()(GlCommandBuffer* commands)
+	{
+		Array<GLuint, MAX_BIND_TEXTURES> names;
 
-			return ErrorCode::NONE;
+		U count = m_texCount;
+		U i = 0;
+		while(count-- != 0)
+		{
+			names[i++] = m_texes[count]._get().getGlName();
 		}
-	};
 
-	Vec texes(_getAllocator());
-	texes.reserve(textures.size());
+		glBindTextures(m_first, m_texCount, &names[0]);
 
-	for(const GlTextureHandle& t : textures)
-	{
-		texes.push_back(t);
+		return ErrorCode::NONE;
 	}
+};
+
+void GlCommandBufferHandle::bindTextures(U32 first, 
+	GlTextureHandle textures[], U32 count)
+{
+	ANKI_ASSERT(count > 0);
 
-	_pushBackNewCommand<Command>(texes, first);
+	_pushBackNewCommand<BindTexturesCommand>(&textures[0], count, first);
 }
 
 //==============================================================================

+ 1 - 1
src/gl/GlError.cpp

@@ -4,7 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/gl/GlError.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include <cstring>
 
 namespace anki {

+ 1 - 1
src/gl/GlFramebuffer.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/gl/GlFramebuffer.h"
 #include "anki/gl/GlTexture.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 64 - 42
src/gl/GlProgram.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/gl/GlProgram.h"
 #include "anki/util/StringList.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 #define ANKI_DUMP_SHADERS ANKI_DEBUG
 
@@ -91,7 +91,7 @@ const GlProgramBlock* GlProgramVariable::getBlock() const
 	ANKI_ASSERT(m_prog);
 	if(m_blockIdx != -1)
 	{
-		ANKI_ASSERT((PtrSize)m_blockIdx < m_prog->m_blocks.size());
+		ANKI_ASSERT((PtrSize)m_blockIdx < m_prog->m_blocks.getSize());
 	}
 
 	return (m_blockIdx != -1) ? &m_prog->m_blocks[m_blockIdx] : nullptr;
@@ -278,6 +278,7 @@ Error GlProgram::create(GLenum type, const CString& source,
 	Error err = ErrorCode::NONE;
 
 	m_type = type;
+	m_alloc = alloc;
 
 	// 1) Append some things in the source string
 	//
@@ -341,9 +342,16 @@ Error GlProgram::create(GLenum type, const CString& source,
 
 		File file;
 		err = file.open(fname.toCString(), File::OpenFlag::WRITE);
-		ANKI_ASSERT(!err);
-		err = file.writeText("%s", &fullSrc[0]);
-		ANKI_ASSERT(!err);
+		
+		if(!err)
+		{
+			err = file.writeText("%s", &fullSrc[0]);
+		}
+
+		if(err)
+		{
+			ANKI_LOGW("Failed to open file %s", &fname[0]);
+		}
 	}
 #endif
 	
@@ -399,13 +407,6 @@ Error GlProgram::populateVariablesAndBlock(GlAllocator<U8>& alloc)
 {
 	Error err = ErrorCode::NONE;
 
-	m_variables = ProgramVector<GlProgramVariable>(alloc);
-	m_variablesDict = ProgramDictionary<GlProgramVariable*>(
-		10, DictionaryHasher(), DictionaryEqual(), alloc);
-	m_blocks = ProgramVector<GlProgramBlock>(alloc);
-	m_blocksDict = ProgramDictionary<GlProgramBlock*>(
-		10, DictionaryHasher(), DictionaryEqual(), alloc);
-
 	static Array<GLenum, 5> interfaces = {{
 		GL_UNIFORM_BLOCK, GL_SHADER_STORAGE_BLOCK, 
 		GL_UNIFORM, GL_BUFFER_VARIABLE, GL_PROGRAM_INPUT}};
@@ -450,16 +451,24 @@ Error GlProgram::populateVariablesAndBlock(GlAllocator<U8>& alloc)
 		}
 	}
 
-	m_names = reinterpret_cast<char*>(alloc.allocate(namesLen));
-	char* namesPtr = m_names;
+	err = m_names.create(alloc, namesLen);
+	char* namesPtr = nullptr;
+
+	if(!err)
+	{
+		namesPtr = &m_names[0];
+	}
 
 	// Populate the blocks
-	if(count[0] + count[1] > 0)
+	if(!err && (count[0] + count[1] > 0))
 	{
-		m_blocks.resize(count[0] + count[1]);
+		err = m_blocks.create(alloc, count[0] + count[1]);
 
-		err = initBlocksOfType(GL_UNIFORM_BLOCK,
-			countReal[0], 0, namesPtr, namesLen);
+		if(!err)
+		{
+			err = initBlocksOfType(GL_UNIFORM_BLOCK,
+				countReal[0], 0, namesPtr, namesLen);
+		}
 
 		if(!err)
 		{
@@ -471,10 +480,13 @@ Error GlProgram::populateVariablesAndBlock(GlAllocator<U8>& alloc)
 	// Populate the variables
 	if(!err && (count[2] + count[3] + count[4] > 0))
 	{
-		m_variables.resize(count[2] + count[3] + count[4]);
+		err = m_variables.create(alloc, count[2] + count[3] + count[4]);
 
-		err = initVariablesOfType(GL_UNIFORM,
-			countReal[2], 0, 0, namesPtr, namesLen);
+		if(!err)
+		{
+			err = initVariablesOfType(GL_UNIFORM,
+				countReal[2], 0, 0, namesPtr, namesLen);
+		}
 
 		if(!err)
 		{
@@ -543,11 +555,9 @@ void GlProgram::destroy()
 		m_glName = 0;
 	}
 
-	if(m_names != nullptr)
-	{
-		auto alloc = m_variables.get_allocator();
-		alloc.deallocate(m_names, 0);
-	}
+	m_variables.destroy(m_alloc);
+	m_blocks.destroy(m_alloc);
+	m_names.destroy(m_alloc);
 }
 
 //==============================================================================
@@ -616,7 +626,7 @@ Error GlProgram::initVariablesOfType(
 		}
 
 		// Create and populate the variable
-		ANKI_ASSERT(index < m_variables.size());
+		ANKI_ASSERT(index < m_variables.getSize());
 		GlProgramVariable& var = m_variables[index++];
 
 		var.m_type = akType;
@@ -650,7 +660,7 @@ Error GlProgram::initVariablesOfType(
 			ANKI_ASSERT(interface != GL_PROGRAM_INPUT);
 
 			U blkIdx = blkIndexOffset + out[6];
-			ANKI_ASSERT(blkIdx < m_blocks.size());
+			ANKI_ASSERT(blkIdx < m_blocks.getSize());
 
 			// Connect block with variable
 			ANKI_ASSERT(m_blocks[blkIdx].m_variablesCount < 255);
@@ -670,11 +680,6 @@ Error GlProgram::initVariablesOfType(
 			var.m_texUnit = unit;
 		}
 
-		// Add to dict
-		ANKI_ASSERT(m_variablesDict.find(var.m_name) 
-			== m_variablesDict.end());
-		m_variablesDict[var.m_name] = &var;
-
 		// Advance
 		namesPtr += len + 1;
 		namesLen -= len + 1;
@@ -746,11 +751,6 @@ Error GlProgram::initBlocksOfType(
 		block.m_bindingPoint = out[0];
 		ANKI_ASSERT(out[0] >= 0);
 
-		// Add to dict
-		ANKI_ASSERT(m_blocksDict.find(block.m_name) 
-			== m_blocksDict.end());
-		m_blocksDict[block.m_name] = &block;
-
 		// Advance
 		namesPtr += len + 1;
 		namesLen -= len + 1;
@@ -763,16 +763,38 @@ Error GlProgram::initBlocksOfType(
 const GlProgramVariable* GlProgram::tryFindVariable(const CString& name) const
 {
 	ANKI_ASSERT(isCreated());
-	auto it = m_variablesDict.find(name);
-	return (it != m_variablesDict.end()) ? it->second : nullptr;
+
+	const GlProgramVariable* out = nullptr;
+
+	auto it = m_variables.begin(); 
+	for(; it != m_variables.end(); it++)
+	{
+		if(it->getName() == name)
+		{
+			out = &(*it);
+		}
+	}
+
+	return out;
 }
 
 //==============================================================================
 const GlProgramBlock* GlProgram::tryFindBlock(const CString& name) const
 {
 	ANKI_ASSERT(isCreated());
-	auto it = m_blocksDict.find(name);
-	return (it != m_blocksDict.end()) ? it->second : nullptr;
+
+	const GlProgramBlock* out = nullptr;
+	
+	auto it = m_blocks.begin();
+	for(; it != m_blocks.end(); it++)
+	{
+		if(it->getName() == name)
+		{
+			out = &(*it);
+		}
+	}
+
+	return out;
 }
 
 } // end namespace anki

+ 18 - 8
src/gl/GlProgramHandle.cpp

@@ -82,21 +82,31 @@ GLenum GlProgramHandle::getType() const
 }
 
 //==============================================================================
-const GlProgram::ProgramVector<GlProgramVariable>& 
-	GlProgramHandle::getVariables() const
+const GlProgramVariable* GlProgramHandle::getVariablesBegin() const
 {
 	Error err = serializeOnGetter();
-	ANKI_ASSERT(!err);
-	return _get().getVariables();
+	const GlProgramVariable* out = nullptr;
+
+	if(!err && _get().getVariables().getSize() != 0)
+	{
+		out = _get().getVariables().begin();
+	}
+
+	return out;
 }
 
 //==============================================================================
-const GlProgram::ProgramVector<GlProgramBlock>& 
-	GlProgramHandle::getBlocks() const
+const GlProgramVariable* GlProgramHandle::getVariablesEnd() const
 {
 	Error err = serializeOnGetter();
-	ANKI_ASSERT(!err);
-	return _get().getBlocks();
+	const GlProgramVariable* out = nullptr;
+
+	if(!err && _get().getVariables().getSize() != 0)
+	{
+		out = _get().getVariables().end();
+	}
+
+	return out;
 }
 
 //==============================================================================

+ 1 - 1
src/gl/GlProgramPipeline.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/gl/GlProgramPipeline.h"
 #include "anki/gl/GlProgram.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 1 - 1
src/gl/GlQueue.cpp

@@ -7,7 +7,7 @@
 #include "anki/gl/GlCommandBuffer.h"
 #include "anki/gl/GlSyncHandles.h"
 #include "anki/gl/GlDevice.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/core/Counters.h"
 
 namespace anki {

+ 1 - 1
src/gl/GlState.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/gl/GlState.h"
 #include "anki/gl/GlBuffer.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include <algorithm>
 #include <cstring>
 

+ 1 - 1
src/gl/GlSync.cpp

@@ -4,7 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/gl/GlSync.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 9 - 7
src/gl/GlTexture.cpp

@@ -6,7 +6,7 @@
 #include "anki/gl/GlTexture.h"
 #include "anki/gl/GlError.h"
 #include "anki/util/Functions.h"
-#include "anki/util/Vector.h"
+#include "anki/util/DArray.h"
 
 namespace anki {
 
@@ -147,14 +147,14 @@ Error GlTexture::create(const Initializer& init,
 				ANKI_ASSERT(m_depth > 0);
 
 				// Gather the data
-				Vector<U8, GlAllocator<U8>> data(alloc);
+				DArray<U8, GlAllocator<U8>> data;
 
 				// Check if there are data
 				if(init.m_data[level][0].m_ptr != nullptr)
 				{
 					PtrSize layerSize = init.m_data[level][0].m_size;
 					ANKI_ASSERT(layerSize > 0);
-					data.resize(layerSize * m_depth);
+					data.create(alloc, layerSize * m_depth);
 
 					for(U d = 0; d < m_depth; d++)
 					{
@@ -179,11 +179,11 @@ Error GlTexture::create(const Initializer& init,
 						0, 
 						m_format, 
 						m_type, 
-						(data.size() > 0) ? &data[0] : nullptr);
+						(data.getSize() > 0) ? &data[0] : nullptr);
 				}
 				else
 				{
-					ANKI_ASSERT(data.size() > 0);
+					ANKI_ASSERT(data.getSize() > 0);
 						
 					glCompressedTexImage3D(
 						m_target, 
@@ -193,9 +193,11 @@ Error GlTexture::create(const Initializer& init,
 						h, 
 						m_depth, 
 						0, 
-						data.size(), 
-						(data.size() > 0) ? &data[0] : nullptr);
+						data.getSize(), 
+						(data.getSize() > 0) ? &data[0] : nullptr);
 				}
+
+				data.destroy(alloc);
 			}
 			break;
 #if ANKI_GL == ANKI_GL_DESKTOP

+ 1 - 1
src/input/InputAndroid.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/input/Input.h"
 #include "anki/core/NativeWindowAndroid.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/core/App.h"
 
 namespace anki {

+ 1 - 1
src/input/InputSdl.cpp

@@ -6,7 +6,7 @@
 #include "anki/input/Input.h"
 #include "anki/input/InputSdl.h"
 #include "anki/core/NativeWindowSdl.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include <SDL.h>
 
 namespace anki {

+ 11 - 10
src/renderer/Dbg.cpp

@@ -9,7 +9,7 @@
 #include "anki/scene/SceneGraph.h"
 #include "anki/scene/Camera.h"
 #include "anki/scene/Light.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/util/Enum.h"
 #include "anki/misc/ConfigSet.h"
 
@@ -38,18 +38,19 @@ void Dbg::init(const ConfigSet& initializer)
 	try
 	{
 		GlDevice& gl = getGlDevice();
-		GlCommandBufferHandle jobs(&gl);
+		GlCommandBufferHandle cmdb;
+		cmdb.create(&gl);
 
 		// Chose the correct color FAI
 		if(m_r->getPps().getEnabled())
 		{
-			m_fb = GlFramebufferHandle(jobs, 
+			m_fb.create(cmdb, 
 				{{m_r->getPps()._getRt(), GL_COLOR_ATTACHMENT0},
 				{m_r->getMs()._getDepthRt(), GL_DEPTH_ATTACHMENT}});
 		}
 		else
 		{
-			m_fb = GlFramebufferHandle(jobs, 
+			m_fb.create(cmdb, 
 				{{m_r->getIs()._getRt(), GL_COLOR_ATTACHMENT0},
 				{m_r->getMs()._getDepthRt(), GL_DEPTH_ATTACHMENT}});
 		}
@@ -57,7 +58,7 @@ void Dbg::init(const ConfigSet& initializer)
 		m_drawer = getAllocator().newInstance<DebugDrawer>(m_r);
 		m_sceneDrawer = getAllocator().newInstance<SceneDebugDrawer>(m_drawer);
 
-		jobs.finish();
+		cmdb.finish();
 	}
 	catch(std::exception& e)
 	{
@@ -66,17 +67,17 @@ void Dbg::init(const ConfigSet& initializer)
 }
 
 //==============================================================================
-void Dbg::run(GlCommandBufferHandle& jobs)
+void Dbg::run(GlCommandBufferHandle& cmdb)
 {
 	ANKI_ASSERT(m_enabled);
 
 	SceneGraph& scene = m_r->getSceneGraph();
 
-	m_fb.bind(jobs, false);
-	jobs.enableDepthTest(m_depthTest);
+	m_fb.bind(cmdb, false);
+	cmdb.enableDepthTest(m_depthTest);
 
 	Camera& cam = scene.getActiveCamera();
-	m_drawer->prepareDraw(jobs);
+	m_drawer->prepareDraw(cmdb);
 	m_drawer->setViewProjectionMatrix(cam.getViewProjectionMatrix());
 	m_drawer->setModelMatrix(Mat4::getIdentity());
 	//drawer->drawGrid();
@@ -412,7 +413,7 @@ void Dbg::run(GlCommandBufferHandle& jobs)
 	m_drawer->flush();
 	m_drawer->finishDraw();
 
-	jobs.enableDepthTest(false);
+	cmdb.enableDepthTest(false);
 }
 
 } // end namespace anki

+ 1 - 1
src/renderer/DebugDrawer.cpp

@@ -10,7 +10,7 @@
 #include "anki/Scene.h"
 #include "anki/resource/TextureResource.h"
 #include "anki/renderer/Renderer.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 4 - 3
src/renderer/Drawer.cpp

@@ -13,7 +13,7 @@
 #include "anki/resource/TextureResource.h"
 #include "anki/renderer/Renderer.h"
 #include "anki/core/Counters.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 
@@ -229,8 +229,9 @@ RenderableDrawer::RenderableDrawer(Renderer* r)
 :	m_r(r)
 {
 	// Create the uniform buffer
-	GlCommandBufferHandle cmdBuff(&m_r->_getGlDevice());
-	m_uniformBuff = GlBufferHandle(cmdBuff, GL_UNIFORM_BUFFER, 
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&m_r->_getGlDevice());
+	m_uniformBuff.create(cmdBuff, GL_UNIFORM_BUFFER, 
 		MAX_UNIFORM_BUFFER_SIZE,
 		GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
 	cmdBuff.flush();

+ 2 - 1
src/renderer/Hdr.cpp

@@ -152,7 +152,8 @@ void Hdr::run(GlCommandBufferHandle& cmdb)
 	{
 		if(i == 0)
 		{
-			cmdb.bindTextures(0, {m_hblurRt, m_vblurRt});
+			Array<GlTextureHandle, 2> arr = {{m_hblurRt, m_vblurRt}};
+			cmdb.bindTextures(0, arr.begin(), arr.getSize());
 		}
 
 		// hpass

+ 20 - 15
src/renderer/Is.cpp

@@ -9,7 +9,7 @@
 #include "anki/scene/Camera.h"
 #include "anki/scene/Light.h"
 #include "anki/core/Counters.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/misc/ConfigSet.h"
 
 namespace anki {
@@ -456,7 +456,8 @@ void Is::initInternal(const ConfigSet& config)
 		m_sm.getPoissonEnabled());
 
 	// point light
-	GlCommandBufferHandle cmdBuff(&getGlDevice()); // Job for initialization
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice()); // Job for initialization
 
 	m_lightVert.loadToCache(&getResourceManager(),
 		"shaders/IsLp.vert.glsl", pps.toCString(), "r_");
@@ -464,7 +465,7 @@ void Is::initInternal(const ConfigSet& config)
 	m_lightFrag.loadToCache(&getResourceManager(),
 		"shaders/IsLp.frag.glsl", pps.toCString(), "r_");
 
-	m_lightPpline = GlProgramPipelineHandle(cmdBuff, 
+	m_lightPpline.create(cmdBuff, 
 		{m_lightVert->getGlProgram(), m_lightFrag->getGlProgram()});
 
 	//
@@ -474,7 +475,7 @@ void Is::initInternal(const ConfigSet& config)
 	m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), GL_RGB8,
 			GL_RGB, GL_UNSIGNED_BYTE, 1, m_rt);
 
-	m_fb = GlFramebufferHandle(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}});
+	m_fb.create(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}});
 
 	//
 	// Init the quad
@@ -482,24 +483,24 @@ void Is::initInternal(const ConfigSet& config)
 	static const F32 quadVertCoords[][2] = {{1.0, 1.0}, {0.0, 1.0},
 		{1.0, 0.0}, {0.0, 0.0}};
 
-	GlClientBufferHandle tempBuff(cmdBuff, sizeof(quadVertCoords), 
+	GlClientBufferHandle tempBuff;
+	tempBuff.create(cmdBuff, sizeof(quadVertCoords), 
 		(void*)&quadVertCoords[0][0]);
 
-	m_quadPositionsVertBuff = GlBufferHandle(cmdBuff, GL_ARRAY_BUFFER,
-		tempBuff, 0);
+	m_quadPositionsVertBuff.create(cmdBuff, GL_ARRAY_BUFFER, tempBuff, 0);
 
 	//
 	// Create UBOs
 	//
 	const GLbitfield bufferBits = GL_DYNAMIC_STORAGE_BIT;
 
-	m_commonBuff = GlBufferHandle(cmdBuff, GL_UNIFORM_BUFFER, 
+	m_commonBuff.create(cmdBuff, GL_UNIFORM_BUFFER, 
 		sizeof(shader::CommonUniforms), bufferBits);
 
-	m_lightsBuff = GlBufferHandle(cmdBuff, GL_SHADER_STORAGE_BUFFER, 
+	m_lightsBuff.create(cmdBuff, GL_SHADER_STORAGE_BUFFER, 
 		calcLightsBufferSize(), bufferBits);
 
-	m_tilesBuff = GlBufferHandle(cmdBuff, GL_SHADER_STORAGE_BUFFER,
+	m_tilesBuff.create(cmdBuff, GL_SHADER_STORAGE_BUFFER,
 		m_r->getTilesCount().x() * m_r->getTilesCount().y() * m_tileSize,
 		bufferBits);
 
@@ -593,11 +594,12 @@ void Is::lightPass(GlCommandBufferHandle& cmdBuff)
 	GlClientBufferHandle lightsClientBuff;
 	if(totalLightsCount > 0)
 	{
-		lightsClientBuff = GlClientBufferHandle(
+		lightsClientBuff.create(
 			cmdBuff, spotTexLightsOffset + spotTexLightsSize, nullptr);
 	}
 
-	GlClientBufferHandle tilesClientBuff(cmdBuff, m_tilesBuff.getSize(), nullptr);
+	GlClientBufferHandle tilesClientBuff;
+	tilesClientBuff.create(cmdBuff, m_tilesBuff.getSize(), nullptr);
 
 	AtomicU32 pointLightsAtomicCount(0);
 	AtomicU32 spotLightsAtomicCount(0);
@@ -735,11 +737,13 @@ void Is::lightPass(GlCommandBufferHandle& cmdBuff)
 	m_tilesBuff.bindShaderBuffer(cmdBuff, TILES_BLOCK_BINDING); 
 
 	// The binding points should much the shader
-	cmdBuff.bindTextures(0, {
+	Array<GlTextureHandle, 4> tarr = {{
 		m_r->getMs()._getRt0(), 
 		m_r->getMs()._getRt1(), 
 		m_r->getMs()._getDepthRt(),
-		m_sm.m_sm2DArrayTex});
+		m_sm.m_sm2DArrayTex}};
+
+	cmdBuff.bindTextures(0, tarr.begin(), tarr.getSize());
 
 	//
 	// Draw
@@ -787,7 +791,8 @@ void Is::updateCommonBlock(GlCommandBufferHandle& cmdBuff)
 {
 	SceneGraph& scene = m_r->getSceneGraph();
 
-	GlClientBufferHandle cbuff(cmdBuff, sizeof(shader::CommonUniforms), nullptr);
+	GlClientBufferHandle cbuff;
+	cbuff.create(cmdBuff, sizeof(shader::CommonUniforms), nullptr);
 	shader::CommonUniforms& blk = 
 		*(shader::CommonUniforms*)cbuff.getBaseAddress();
 

+ 17 - 14
src/renderer/Lf.cpp

@@ -77,7 +77,8 @@ void Lf::initInternal(const ConfigSet& config)
 		return;
 	}
 
-	GlCommandBufferHandle cmdBuff(&getGlDevice());
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice());
 
 	m_maxFlaresPerLight = config.get("pps.lf.maxFlaresPerLight");
 	m_maxLightsWithFlares = config.get("pps.lf.maxLightsWithFlares");
@@ -85,8 +86,8 @@ void Lf::initInternal(const ConfigSet& config)
 	// Load program 1
 	String pps(getAllocator());
 	pps.sprintf("#define TEX_DIMENSIONS vec2(%u.0, %u.0)\n", 
-		m_r->getPps().getHdr()._getRt().getWidth(),
-		m_r->getPps().getHdr()._getRt().getHeight());
+		m_r->getPps().getHdr()._getWidth(),
+		m_r->getPps().getHdr()._getHeight());
 
 	m_pseudoFrag.loadToCache(&getResourceManager(), 
 		"shaders/PpsLfPseudoPass.frag.glsl", pps.toCString(), "r_");
@@ -103,7 +104,7 @@ void Lf::initInternal(const ConfigSet& config)
 	m_realFrag.loadToCache(&getResourceManager(), 
 		"shaders/PpsLfSpritePass.frag.glsl", pps.toCString(), "r_");
 
-	m_realPpline = GlProgramPipelineHandle(cmdBuff,
+	m_realPpline.create(cmdBuff,
 		{m_realVert->getGlProgram(), m_realFrag->getGlProgram()});
 
 	PtrSize blockSize = 
@@ -115,15 +116,15 @@ void Lf::initInternal(const ConfigSet& config)
 	}
 
 	// Init buffer
-	m_flareDataBuff = GlBufferHandle(
+	m_flareDataBuff.create(
 		cmdBuff, GL_UNIFORM_BUFFER, blockSize, GL_DYNAMIC_STORAGE_BIT);
 
 	// Create the render target
-	m_r->createRenderTarget(m_r->getPps().getHdr()._getRt().getWidth(), 
-		m_r->getPps().getHdr()._getRt().getHeight(), 
+	m_r->createRenderTarget(m_r->getPps().getHdr()._getWidth(), 
+		m_r->getPps().getHdr()._getHeight(), 
 		GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, 1, m_rt);
 
-	m_fb = GlFramebufferHandle(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}}); 
+	m_fb.create(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}}); 
 	
 	// Textures
 	m_lensDirtTex.load("engine_data/lens_dirt.ankitex", &getResourceManager());
@@ -147,14 +148,15 @@ void Lf::run(GlCommandBufferHandle& cmdBuff)
 
 	// Set the common state
 	m_fb.bind(cmdBuff, true);
-	cmdBuff.setViewport(0, 0, m_r->getPps().getHdr()._getRt().getWidth(), 
-		m_r->getPps().getHdr()._getRt().getHeight());
+	cmdBuff.setViewport(0, 0, m_r->getPps().getHdr()._getWidth(), 
+		m_r->getPps().getHdr()._getHeight());
 
 	m_pseudoPpline.bind(cmdBuff);
 
-	cmdBuff.bindTextures(0, {
+	Array<GlTextureHandle, 2> tarr = {{
 		m_r->getPps().getHdr()._getRt(), 
-		m_lensDirtTex->getGlTexture()});
+		m_lensDirtTex->getGlTexture()}};
+	cmdBuff.bindTextures(0, tarr.begin(), tarr.getSize());
 
 	m_r->drawQuad(cmdBuff);
 
@@ -198,7 +200,8 @@ void Lf::run(GlCommandBufferHandle& cmdBuff)
 
 		// Write the UBO and get the groups
 		//
-		GlClientBufferHandle flaresCBuff(cmdBuff,
+		GlClientBufferHandle flaresCBuff;
+		flaresCBuff.create(cmdBuff,
 			sizeof(Flare) * lightsCount * m_maxFlaresPerLight, nullptr);
 		Flare* flares = (Flare*)flaresCBuff.getBaseAddress();
 		U flaresCount = 0;
@@ -216,7 +219,7 @@ void Lf::run(GlCommandBufferHandle& cmdBuff)
 		{
 			Light& light = *lights[lightsCount];
 			const GlTextureHandle& tex = light.getLensFlareTexture();
-			const U depth = tex.getDepth();
+			const U depth = light.getLensFlareTextureDepth();
 
 			// Transform
 			Vec3 posWorld = light.getWorldTransform().getOrigin().xyz();

+ 4 - 3
src/renderer/MainRenderer.cpp

@@ -4,7 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/renderer/MainRenderer.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/renderer/Deformer.h"
 #include "anki/util/File.h"
 #include "anki/util/Filesystem.h"
@@ -65,7 +65,7 @@ void MainRenderer::render(SceneGraph& scene)
 
 	for(U i = 0; i < JOB_CHAINS_COUNT; i++)
 	{
-		jobs[i] = GlCommandBufferHandle(&gl, m_jobsInitHints[i]);
+		jobs[i].create(&gl, m_jobsInitHints[i]);
 	}
 
 	Renderer::render(scene, jobs);
@@ -118,7 +118,8 @@ void MainRenderer::initGl()
 {
 	// get max texture units
 	GlDevice& gl = _getGlDevice();
-	GlCommandBufferHandle jobs(&gl);
+	GlCommandBufferHandle jobs;
+	jobs.create(&gl);
 
 	jobs.enableCulling(true);
 	jobs.setCullFace(GL_BACK);

+ 15 - 10
src/renderer/Ms.cpp

@@ -7,7 +7,7 @@
 #include "anki/renderer/Ez.h"
 #include "anki/renderer/Renderer.h"
 
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/scene/Camera.h"
 #include "anki/scene/SceneGraph.h"
 #include "anki/misc/ConfigSet.h"
@@ -34,9 +34,10 @@ void Ms::createRt(U32 index, U32 samples)
 		GL_RGBA, GL_UNSIGNED_BYTE, samples, plane.m_rt1);
 
 	GlDevice& gl = getGlDevice();
-	GlCommandBufferHandle cmdb(&gl);
+	GlCommandBufferHandle cmdb;
+	cmdb.create(&gl);
 
-	plane.m_fb = GlFramebufferHandle(
+	plane.m_fb.create(
 		cmdb,
 		{{plane.m_rt0, GL_COLOR_ATTACHMENT0}, 
 		{plane.m_rt1, GL_COLOR_ATTACHMENT1},
@@ -58,18 +59,23 @@ void Ms::init(const ConfigSet& initializer)
 
 		// Init small depth 
 		{
+			m_smallDepthSize = UVec2(
+				getAlignedRoundDown(16, m_r->getWidth() / 3),
+				getAlignedRoundDown(16, m_r->getHeight() / 3));
+
 			m_r->createRenderTarget(
-				getAlignedRoundDown(16, m_r->getWidth() / 3) , 
-				getAlignedRoundDown(16, m_r->getHeight() / 3),
+				m_smallDepthSize.x(), 
+				m_smallDepthSize.y(),
 				GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT,
 				GL_UNSIGNED_INT, 1, m_smallDepthRt);
 
 			GlDevice& gl = getGlDevice();
-			GlCommandBufferHandle cmdb(&gl);
+			GlCommandBufferHandle cmdb;
+			cmdb.create(&gl);
 
 			m_smallDepthRt.setFilter(cmdb, GlTextureHandle::Filter::LINEAR);
 
-			m_smallDepthFb = GlFramebufferHandle(
+			m_smallDepthFb.create(
 				cmdb,
 				{{m_smallDepthRt, GL_DEPTH_ATTACHMENT}});
 
@@ -147,9 +153,8 @@ void Ms::run(GlCommandBufferHandle& cmdb)
 
 	// Blit big depth buffer to small one
 	m_smallDepthFb.blit(cmdb, m_planes[1].m_fb, 
-		{{0, 0, m_planes[1].m_depthRt.getWidth(), 
-			m_planes[1].m_depthRt.getHeight()}},
-		{{0, 0, m_smallDepthRt.getWidth(), m_smallDepthRt.getHeight()}},
+		{{0, 0, m_r->getWidth(), m_r->getHeight()}},
+		{{0, 0, m_smallDepthSize.x(), m_smallDepthSize.y()}},
 		GL_DEPTH_BUFFER_BIT, false);
 
 	cmdb.enableDepthTest(false);

+ 4 - 3
src/renderer/Pps.cpp

@@ -7,7 +7,7 @@
 #include "anki/renderer/Renderer.h"
 #include "anki/renderer/Hdr.h"
 #include "anki/renderer/Ssao.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/misc/ConfigSet.h"
 
 namespace anki {
@@ -43,12 +43,13 @@ void Pps::initInternal(const ConfigSet& config)
 	m_sslr.init(config);
 
 	// FBO
-	GlCommandBufferHandle cmdBuff(&getGlDevice());
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice());
 
 	m_r->createRenderTarget(m_r->getWidth(), m_r->getHeight(), GL_RGB8, GL_RGB,
 		GL_UNSIGNED_BYTE, 1, m_rt);
 
-	m_fb = GlFramebufferHandle(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}});
+	m_fb.create(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}});
 
 	// SProg
 	String pps(getAllocator());

+ 14 - 10
src/renderer/Renderer.cpp

@@ -69,13 +69,14 @@ void Renderer::init(const ConfigSet& config)
 	static const F32 quadVertCoords[][2] = {{1.0, 1.0}, {-1.0, 1.0}, 
 		{1.0, -1.0}, {-1.0, -1.0}};
 
-	GlCommandBufferHandle cmdBuff(m_gl);
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(m_gl);
 
-	GlClientBufferHandle tmpBuff = GlClientBufferHandle(cmdBuff, 
-		sizeof(quadVertCoords), (void*)&quadVertCoords[0][0]);
+	GlClientBufferHandle tmpBuff;
+	tmpBuff.create(
+		cmdBuff, sizeof(quadVertCoords), (void*)&quadVertCoords[0][0]);
 
-	m_quadPositionsBuff = GlBufferHandle(cmdBuff, GL_ARRAY_BUFFER, 
-		tmpBuff, 0);
+	m_quadPositionsBuff.create(cmdBuff, GL_ARRAY_BUFFER, tmpBuff, 0);
 
 	m_drawQuadVert.load("shaders/Quad.vert.glsl", m_resources);
 
@@ -89,7 +90,7 @@ void Renderer::init(const ConfigSet& config)
 	m_dbg.init(config);
 
 	// Default FB
-	m_defaultFb = GlFramebufferHandle(cmdBuff, {});
+	m_defaultFb.create(cmdBuff, {});
 
 	cmdBuff.finish();
 
@@ -235,8 +236,9 @@ void Renderer::createRenderTarget(U32 w, U32 h, GLenum internalFormat,
 	init.m_genMipmaps = false;
 	init.m_samples = samples;
 
-	GlCommandBufferHandle cmdBuff(m_gl);
-	rt = GlTextureHandle(cmdBuff, init);
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(m_gl);
+	rt.create(cmdBuff, init);
 	cmdBuff.finish();
 }
 
@@ -244,11 +246,13 @@ void Renderer::createRenderTarget(U32 w, U32 h, GLenum internalFormat,
 GlProgramPipelineHandle Renderer::createDrawQuadProgramPipeline(
 	GlProgramHandle frag)
 {
-	GlCommandBufferHandle cmdBuff(m_gl);
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(m_gl);
 
 	Array<GlProgramHandle, 2> progs = {{m_drawQuadVert->getGlProgram(), frag}};
 
-	GlProgramPipelineHandle ppline(cmdBuff, &progs[0], &progs[0] + 2);
+	GlProgramPipelineHandle ppline;
+	ppline.create(cmdBuff, &progs[0], &progs[0] + 2);
 	cmdBuff.finish();
 
 	return ppline;

+ 16 - 14
src/renderer/RenderingPass.cpp

@@ -38,7 +38,8 @@ void BlurringRenderingPass::initBlurring(
 	Renderer& r, U width, U height, U samples, F32 blurringDistance)
 {
 	GlDevice& gl = getGlDevice();
-	GlCommandBufferHandle jobs(&gl);
+	GlCommandBufferHandle cmdb;
+	cmdb.create(&gl);
 
 	Array<String, 2> pps = {{String(getAllocator()), String(getAllocator())}};
 
@@ -65,11 +66,11 @@ void BlurringRenderingPass::initBlurring(
 
 		// Set to bilinear because the blurring techniques take advantage of 
 		// that
-		dir.m_rt.setFilter(jobs, GlTextureHandle::Filter::LINEAR);
+		dir.m_rt.setFilter(cmdb, GlTextureHandle::Filter::LINEAR);
 
 		// Create FB
-		dir.m_fb = GlFramebufferHandle(
-			jobs, {{dir.m_rt, GL_COLOR_ATTACHMENT0}});
+		dir.m_fb.create(
+			cmdb, {{dir.m_rt, GL_COLOR_ATTACHMENT0}});
 
 		dir.m_frag.loadToCache(&getResourceManager(),
 			"shaders/VariableSamplingBlurGeneric.frag.glsl", 
@@ -79,29 +80,30 @@ void BlurringRenderingPass::initBlurring(
 			r.createDrawQuadProgramPipeline(dir.m_frag->getGlProgram());
 	}
 
-	jobs.finish();
+	cmdb.finish();
 }
 
 //==============================================================================
-void BlurringRenderingPass::runBlurring(Renderer& r, GlCommandBufferHandle& jobs)
+void BlurringRenderingPass::runBlurring(
+	Renderer& r, GlCommandBufferHandle& cmdb)
 {
 	// H pass input
-	m_dirs[enumToValue(DirectionEnum::VERTICAL)].m_rt.bind(jobs, 1); 
+	m_dirs[enumToValue(DirectionEnum::VERTICAL)].m_rt.bind(cmdb, 1); 
 
 	// V pass input
-	m_dirs[enumToValue(DirectionEnum::HORIZONTAL)].m_rt.bind(jobs, 0); 
+	m_dirs[enumToValue(DirectionEnum::HORIZONTAL)].m_rt.bind(cmdb, 0); 
 
 	for(U32 i = 0; i < m_blurringIterationsCount; i++)
 	{
 		// hpass
-		m_dirs[enumToValue(DirectionEnum::HORIZONTAL)].m_fb.bind(jobs, true);
-		m_dirs[enumToValue(DirectionEnum::HORIZONTAL)].m_ppline.bind(jobs);
-		r.drawQuad(jobs);
+		m_dirs[enumToValue(DirectionEnum::HORIZONTAL)].m_fb.bind(cmdb, true);
+		m_dirs[enumToValue(DirectionEnum::HORIZONTAL)].m_ppline.bind(cmdb);
+		r.drawQuad(cmdb);
 
 		// vpass
-		m_dirs[enumToValue(DirectionEnum::VERTICAL)].m_fb.bind(jobs, true);
-		m_dirs[enumToValue(DirectionEnum::VERTICAL)].m_ppline.bind(jobs);
-		r.drawQuad(jobs);
+		m_dirs[enumToValue(DirectionEnum::VERTICAL)].m_fb.bind(cmdb, true);
+		m_dirs[enumToValue(DirectionEnum::VERTICAL)].m_ppline.bind(cmdb);
+		r.drawQuad(cmdb);
 	}
 }
 

+ 4 - 3
src/renderer/Sm.cpp

@@ -55,9 +55,10 @@ void Sm::init(const ConfigSet& initializer)
 		sminit.m_filterType = GlTextureHandle::Filter::NEAREST;
 	}
 
-	GlCommandBufferHandle cmdBuff(&getGlDevice());
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice());
 
-	m_sm2DArrayTex = GlTextureHandle(cmdBuff, sminit);
+	m_sm2DArrayTex.create(cmdBuff, sminit);
 
 	m_sm2DArrayTex.setParameter(cmdBuff, 
 		GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
@@ -69,7 +70,7 @@ void Sm::init(const ConfigSet& initializer)
 	for(Shadowmap& sm : m_sms)
 	{
 		sm.m_layerId = layer;
-		sm.m_fb = GlFramebufferHandle(cmdBuff, 
+		sm.m_fb.create(cmdBuff, 
 			{{m_sm2DArrayTex, GL_DEPTH_ATTACHMENT, (U32)layer}});
 
 		++layer;

+ 32 - 26
src/renderer/Ssao.cpp

@@ -67,17 +67,18 @@ public:
 //==============================================================================
 
 //==============================================================================
-void Ssao::createFb(GlFramebufferHandle & fb, GlTextureHandle& rt)
+void Ssao::createFb(GlFramebufferHandle& fb, GlTextureHandle& rt)
 {
 	m_r->createRenderTarget(m_width, m_height, GL_RED, GL_RED, 
 		GL_UNSIGNED_BYTE, 1, rt);
 
 	// Set to bilinear because the blurring techniques take advantage of that
-	GlCommandBufferHandle cmdBuff(&getGlDevice());
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice());
 	rt.setFilter(cmdBuff, GlTextureHandle::Filter::LINEAR);
 
 	// create FB
-	fb = GlFramebufferHandle(cmdBuff, {{rt, GL_COLOR_ATTACHMENT0}});
+	fb.create(cmdBuff, {{rt, GL_COLOR_ATTACHMENT0}});
 
 	cmdBuff.flush();
 }
@@ -114,10 +115,12 @@ void Ssao::initInternal(const ConfigSet& config)
 	//
 	// noise texture
 	//
-	GlCommandBufferHandle jobs(&getGlDevice());
+	GlCommandBufferHandle cmdb;
+	cmdb.create(&getGlDevice());
 
-	GlClientBufferHandle noise(
-		jobs, sizeof(Vec3) * NOISE_TEX_SIZE * NOISE_TEX_SIZE, nullptr);
+	GlClientBufferHandle noise;
+	noise.create(
+		cmdb, sizeof(Vec3) * NOISE_TEX_SIZE * NOISE_TEX_SIZE, nullptr);
 
 	genNoise((Vec3*)noise.getBaseAddress(), 
 		(Vec3*)((U8*)noise.getBaseAddress() + noise.getSize()));
@@ -134,7 +137,7 @@ void Ssao::initInternal(const ConfigSet& config)
 	tinit.m_mipmapsCount = 1;
 	tinit.m_data[0][0] = noise;
 
-	m_noiseTex = GlTextureHandle(jobs, tinit);
+	m_noiseTex.create(cmdb, tinit);
 
 	//
 	// Kernel
@@ -158,7 +161,7 @@ void Ssao::initInternal(const ConfigSet& config)
 	//
 	// Shaders
 	//
-	m_uniformsBuff = GlBufferHandle(jobs, GL_SHADER_STORAGE_BUFFER, 
+	m_uniformsBuff.create(cmdb, GL_SHADER_STORAGE_BUFFER, 
 		sizeof(ShaderCommonUniforms), GL_DYNAMIC_STORAGE_BIT);
 
 	String pps(getAllocator());
@@ -209,7 +212,7 @@ void Ssao::initInternal(const ConfigSet& config)
 	m_vblurPpline = m_r->createDrawQuadProgramPipeline(
 		m_vblurFrag->getGlProgram());
 
-	jobs.flush();
+	cmdb.flush();
 }
 
 //==============================================================================
@@ -226,25 +229,26 @@ void Ssao::init(const ConfigSet& config)
 }
 
 //==============================================================================
-void Ssao::run(GlCommandBufferHandle& jobs)
+void Ssao::run(GlCommandBufferHandle& cmdb)
 {
 	ANKI_ASSERT(m_enabled);
 
 	const Camera& cam = m_r->getSceneGraph().getActiveCamera();
 
-	jobs.setViewport(0, 0, m_width, m_height);
+	cmdb.setViewport(0, 0, m_width, m_height);
 
 	// 1st pass
 	//
-	m_vblurFb.bind(jobs, true);
-	m_ssaoPpline.bind(jobs);
+	m_vblurFb.bind(cmdb, true);
+	m_ssaoPpline.bind(cmdb);
 
-	m_uniformsBuff.bindShaderBuffer(jobs, 0);
+	m_uniformsBuff.bindShaderBuffer(cmdb, 0);
 
-	jobs.bindTextures(0, {
+	Array<GlTextureHandle, 3> tarr = {{
 		m_r->getMs()._getSmallDepthRt(),
 		m_r->getMs()._getRt1(),
-		m_noiseTex});
+		m_noiseTex}};
+	cmdb.bindTextures(0, tarr.begin(), tarr.getSize());
 
 	// Write common block
 	if(m_commonUboUpdateTimestamp 
@@ -252,7 +256,8 @@ void Ssao::run(GlCommandBufferHandle& jobs)
 		|| m_commonUboUpdateTimestamp < cam.FrustumComponent::getTimestamp()
 		|| m_commonUboUpdateTimestamp == 1)
 	{
-		GlClientBufferHandle tmpBuff(jobs, sizeof(ShaderCommonUniforms),
+		GlClientBufferHandle tmpBuff;
+		tmpBuff.create(cmdb, sizeof(ShaderCommonUniforms),
 			nullptr);
 
 		ShaderCommonUniforms& blk = 
@@ -262,12 +267,12 @@ void Ssao::run(GlCommandBufferHandle& jobs)
 
 		blk.m_projectionMatrix = cam.getProjectionMatrix().getTransposed();
 
-		m_uniformsBuff.write(jobs, tmpBuff, 0, 0, tmpBuff.getSize());
+		m_uniformsBuff.write(cmdb, tmpBuff, 0, 0, tmpBuff.getSize());
 		m_commonUboUpdateTimestamp = getGlobTimestamp();
 	}
 
 	// Draw
-	m_r->drawQuad(jobs);
+	m_r->drawQuad(cmdb);
 
 	// Blurring passes
 	//
@@ -275,18 +280,19 @@ void Ssao::run(GlCommandBufferHandle& jobs)
 	{
 		if(i == 0)
 		{
-			jobs.bindTextures(0, {m_hblurRt, m_vblurRt});
+			Array<GlTextureHandle, 2> tarr = {{m_hblurRt, m_vblurRt}};
+			cmdb.bindTextures(0, tarr.begin(), tarr.getSize());
 		}
 
 		// hpass
-		m_hblurFb.bind(jobs, true);
-		m_hblurPpline.bind(jobs);
-		m_r->drawQuad(jobs);
+		m_hblurFb.bind(cmdb, true);
+		m_hblurPpline.bind(cmdb);
+		m_r->drawQuad(cmdb);
 
 		// vpass
-		m_vblurFb.bind(jobs, true);
-		m_vblurPpline.bind(jobs);
-		m_r->drawQuad(jobs);
+		m_vblurFb.bind(cmdb, true);
+		m_vblurPpline.bind(cmdb);
+		m_r->drawQuad(cmdb);
 	}
 }
 

+ 9 - 8
src/renderer/Sslr.cpp

@@ -44,8 +44,9 @@ void Sslr::init(const ConfigSet& config)
 		m_reflectionFrag->getGlProgram());
 
 	// Sampler
-	GlCommandBufferHandle cmdBuff(&getGlDevice());
-	m_depthMapSampler = GlSamplerHandle(cmdBuff);
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice());
+	m_depthMapSampler.create(cmdBuff);
 	m_depthMapSampler.setFilter(cmdBuff, GlSamplerHandle::Filter::NEAREST);
 
 	// Blit
@@ -70,8 +71,7 @@ void Sslr::init(const ConfigSet& config)
 		dir.m_rt.setFilter(cmdBuff, GlTextureHandle::Filter::LINEAR);
 
 		// Create FB
-		dir.m_fb = GlFramebufferHandle(
-			cmdBuff, {{dir.m_rt, GL_COLOR_ATTACHMENT0}});
+		dir.m_fb.create(cmdBuff, {{dir.m_rt, GL_COLOR_ATTACHMENT0}});
 	}
 
 	cmdBuff.finish();
@@ -89,10 +89,11 @@ void Sslr::run(GlCommandBufferHandle& cmdBuff)
 
 	m_reflectionPpline.bind(cmdBuff);
 
-	cmdBuff.bindTextures(0	, {
-		m_r->getIs()._getRt(), // 0 
-		m_r->getMs()._getSmallDepthRt(), // 1
-		m_r->getMs()._getRt1()}); // 2
+	Array<GlTextureHandle, 3> tarr = {{
+		m_r->getIs()._getRt(),
+		m_r->getMs()._getSmallDepthRt(),
+		m_r->getMs()._getRt1()}};
+	cmdBuff.bindTextures(0	, tarr.begin(), tarr.getSize()); 
 
 	m_depthMapSampler.bind(cmdBuff, 1);
 	m_r->getPps().getSsao().m_uniformsBuff.bindShaderBuffer(cmdBuff, 0);

+ 4 - 3
src/renderer/Tiler.cpp

@@ -245,15 +245,16 @@ void Tiler::initInternal()
 	m_r->createRenderTarget(m_r->getTilesCount().x(), m_r->getTilesCount().y(),
 		GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, 1, m_rt);
 
-	GlCommandBufferHandle cmdBuff(&getGlDevice());
+	GlCommandBufferHandle cmdBuff;
+	cmdBuff.create(&getGlDevice());
 
-	m_fb = GlFramebufferHandle(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}});
+	m_fb.create(cmdBuff, {{m_rt, GL_COLOR_ATTACHMENT0}});
 
 	// Create PBO
 	U pixelBuffSize = m_r->getTilesCount().x() * m_r->getTilesCount().y();
 	pixelBuffSize *= 2 * sizeof(F32); // The pixel size
 	pixelBuffSize *= 4; // Because it will be always mapped
-	m_pixelBuff = GlBufferHandle(cmdBuff, GL_PIXEL_PACK_BUFFER, pixelBuffSize,
+	m_pixelBuff.create(cmdBuff, GL_PIXEL_PACK_BUFFER, pixelBuffSize,
 		GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
 
 	// Init planes. One plane for each direction, plus near/far plus the world

+ 1 - 1
src/resource/AsyncLoader.cpp

@@ -4,7 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/resource/AsyncLoader.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 247 - 106
src/resource/Image.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/resource/Image.h"
 #include "anki/util/Exception.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/util/File.h"
 #include "anki/util/Filesystem.h"
 #include "anki/util/Assert.h"
@@ -23,12 +23,20 @@ static U8 tgaHeaderUncompressed[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static U8 tgaHeaderCompressed[12] = {0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 //==============================================================================
-static void loadUncompressedTga(
-	File& fs, U32& width, U32& height, U32& bpp, ResourceVector<U8>& data)
+static ANKI_USE_RESULT Error loadUncompressedTga(
+	File& fs, U32& width, U32& height, U32& bpp, ResourceDArray<U8>& data,
+	ResourceAllocator<U8>& alloc)
 {
-	// read the info from header
 	U8 header6[6];
-	fs.read((char*)&header6[0], sizeof(header6));
+	I bytesPerPxl;
+	I imageSize;
+
+	// read the info from header
+	Error err = fs.read((char*)&header6[0], sizeof(header6));
+	if(err)
+	{
+		goto cleanup;
+	}
 
 	width  = header6[1] * 256 + header6[0];
 	height = header6[3] * 256 + header6[2];
@@ -36,31 +44,63 @@ static void loadUncompressedTga(
 
 	if((width <= 0) || (height <= 0) || ((bpp != 24) && (bpp != 32)))
 	{
-		throw ANKI_EXCEPTION("Invalid image information");
+		ANKI_LOGE("Invalid image information");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	// read the data
-	I bytesPerPxl	= (bpp / 8);
-	I imageSize = bytesPerPxl * width * height;
-	data.resize(imageSize);
+	bytesPerPxl = (bpp / 8);
+	imageSize = bytesPerPxl * width * height;
+	err = data.create(alloc, imageSize);
+	if(err)
+	{
+		goto cleanup;
+	}
 
-	fs.read(reinterpret_cast<char*>(&data[0]), imageSize);
+	err = fs.read(reinterpret_cast<char*>(&data[0]), imageSize);
+	if(err)
+	{
+		goto cleanup;
+	}
 
 	// swap red with blue
-	for(int i = 0; i < int(imageSize); i += bytesPerPxl)
+	for(I i = 0; i < imageSize; i += bytesPerPxl)
 	{
 		U32 temp = data[i];
 		data[i] = data[i + 2];
 		data[i + 2] = temp;
 	}
+
+cleanup:
+	if(err)
+	{
+		data.destroy(alloc);
+	}
+
+	return err;
 }
 
 //==============================================================================
-static void loadCompressedTga(
-	File& fs, U32& width, U32& height, U32& bpp, ResourceVector<U8>& data)
+static ANKI_USE_RESULT Error loadCompressedTga(
+	File& fs, U32& width, U32& height, U32& bpp, ResourceDArray<U8>& data,
+	ResourceAllocator<U8>& alloc)
 {
 	U8 header6[6];
-	fs.read(reinterpret_cast<char*>(&header6[0]), sizeof(header6));
+	
+	I bytesPerPxl;
+	I imageSize;
+
+	U32 pixelcount;
+	U32 currentpixel;
+	U32 currentbyte;
+	U8 colorbuffer[4];
+
+	Error err = fs.read(reinterpret_cast<char*>(&header6[0]), sizeof(header6));
+	if(err)
+	{
+		goto cleanup;
+	}
 
 	width  = header6[1] * 256 + header6[0];
 	height = header6[3] * 256 + header6[2];
@@ -68,30 +108,43 @@ static void loadCompressedTga(
 
 	if((width <= 0) || (height <= 0) || ((bpp != 24) && (bpp != 32)))
 	{
-		throw ANKI_EXCEPTION("Invalid texture information");
+		ANKI_LOGE("Invalid texture information");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
-	I bytesPerPxl = (bpp / 8);
-	I imageSize = bytesPerPxl * width * height;
-	data.resize(imageSize);
+	bytesPerPxl = (bpp / 8);
+	imageSize = bytesPerPxl * width * height;
+	err = data.create(alloc, imageSize);
+	if(err)
+	{
+		goto cleanup;
+	}
 
-	U32 pixelcount = height * width;
-	U32 currentpixel = 0;
-	U32 currentbyte = 0;
-	U8 colorbuffer[4];
+	pixelcount = height * width;
+	currentpixel = 0;
+	currentbyte = 0;
 
 	do
 	{
 		U8 chunkheader = 0;
 
-		fs.read((char*)&chunkheader, sizeof(U8));
+		err = fs.read((char*)&chunkheader, sizeof(U8));
+		if(err)
+		{
+			goto cleanup;
+		}
 
 		if(chunkheader < 128)
 		{
 			chunkheader++;
 			for(int counter = 0; counter < chunkheader; counter++)
 			{
-				fs.read((char*)&colorbuffer[0], bytesPerPxl);
+				err = fs.read((char*)&colorbuffer[0], bytesPerPxl);
+				if(err)
+				{
+					goto cleanup;
+				}
 
 				data[currentbyte] = colorbuffer[2];
 				data[currentbyte + 1] = colorbuffer[1];
@@ -107,14 +160,20 @@ static void loadCompressedTga(
 
 				if(currentpixel > pixelcount)
 				{
-					throw ANKI_EXCEPTION("Too many pixels read");
+					ANKI_LOGE("Too many pixels read");
+					err = ErrorCode::USER_DATA;
+					goto cleanup;
 				}
 			}
 		}
 		else
 		{
 			chunkheader -= 127;
-			fs.read((char*)&colorbuffer[0], bytesPerPxl);
+			err = fs.read((char*)&colorbuffer[0], bytesPerPxl);
+			if(err)
+			{
+				goto cleanup;
+			}
 
 			for(int counter = 0; counter < chunkheader; counter++)
 			{
@@ -132,42 +191,65 @@ static void loadCompressedTga(
 
 				if(currentpixel > pixelcount)
 				{
-					throw ANKI_EXCEPTION("Too many pixels read");
+					ANKI_LOGE("Too many pixels read");
+					err = ErrorCode::USER_DATA;
+					goto cleanup;
 				}
 			}
 		}
 	} while(currentpixel < pixelcount);
+
+cleanup:
+	if(err)
+	{
+		data.destroy(alloc);
+	}
+
+	return err;
 }
 
 //==============================================================================
-static void loadTga(const CString& filename, 
-	U32& width, U32& height, U32& bpp, ResourceVector<U8>& data)
+static ANKI_USE_RESULT Error loadTga(const CString& filename, 
+	U32& width, U32& height, U32& bpp, ResourceDArray<U8>& data,
+	ResourceAllocator<U8>& alloc)
 {
 	File fs;
-	fs.open(filename, File::OpenFlag::READ | File::OpenFlag::BINARY);
 	char myTgaHeader[12];
 
-	fs.read(&myTgaHeader[0], sizeof(myTgaHeader));
+	Error err = fs.open(filename, 
+		File::OpenFlag::READ | File::OpenFlag::BINARY);
 
-	if(std::memcmp(
-		tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
+	if(!err)
 	{
-		loadUncompressedTga(fs, width, height, bpp, data);
+		err = fs.read(&myTgaHeader[0], sizeof(myTgaHeader));
 	}
-	else if(std::memcmp(tgaHeaderCompressed, &myTgaHeader[0],
-		sizeof(myTgaHeader)) == 0)
-	{
-		loadCompressedTga(fs, width, height, bpp, data);
-	}
-	else
+
+	if(!err)
 	{
-		throw ANKI_EXCEPTION("Invalid image header");
+		if(std::memcmp(
+			tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
+		{
+			err = loadUncompressedTga(fs, width, height, bpp, data, alloc);
+		}
+		else if(std::memcmp(tgaHeaderCompressed, &myTgaHeader[0],
+			sizeof(myTgaHeader)) == 0)
+		{
+			err = loadCompressedTga(fs, width, height, bpp, data, alloc);
+		}
+		else
+		{
+			ANKI_LOGE("Invalid image header");
+			err = ErrorCode::USER_DATA;
+		}
 	}
 
-	if(bpp != 32 && bpp != 24)
+	if(!err && bpp != 32 && bpp != 24)
 	{
-		throw ANKI_EXCEPTION("Invalid bpp");
+		ANKI_LOGE("Invalid bpp");
+		err = ErrorCode::USER_DATA;
 	}
+
+	return err;
 }
 
 //==============================================================================
@@ -269,30 +351,50 @@ static PtrSize calcSizeOfSegment(const AnkiTextureHeader& header,
 }
 
 //==============================================================================
-static void loadAnkiTexture(
+static ANKI_USE_RESULT Error loadAnkiTexture(
 	const CString& filename, 
 	U32 maxTextureSize,
 	Image::DataCompression& preferredCompression,
-	ResourceVector<Image::Surface>& surfaces, 
+	ResourceDArray<Image::Surface>& surfaces,
+	ResourceAllocator<U8>& alloc,
 	U8& depth, 
 	U8& mipLevels, 
 	Image::TextureType& textureType,
 	Image::ColorFormat& colorFormat)
 {
+	Error err = ErrorCode::NONE;
 	File file;
-	file.open(filename, 
+
+	U mipWidth;
+	U mipHeight;
+
+	U size;
+	U maxsize;
+	U tmpMipLevels;
+
+	err = file.open(filename, 
 		File::OpenFlag::READ | File::OpenFlag::BINARY 
 		| File::OpenFlag::LITTLE_ENDIAN);
+	if(err)
+	{
+		goto cleanup;
+	}
 
 	//
 	// Read and check the header
 	//
 	AnkiTextureHeader header;
-	file.read(&header, sizeof(AnkiTextureHeader));
+	err = file.read(&header, sizeof(AnkiTextureHeader));
+	if(err)
+	{
+		goto cleanup;
+	}
 
 	if(std::memcmp(&header.m_magic[0], "ANKITEX1", 8) != 0)
 	{
-		throw ANKI_EXCEPTION("Wrong magic word");
+		ANKI_LOGE("Wrong magic word");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	if(header.m_width == 0 
@@ -302,42 +404,54 @@ static void loadAnkiTexture(
 		|| !isPowerOfTwo(header.m_height) 
 		|| header.m_height > 4096)
 	{
-		throw ANKI_EXCEPTION("Incorrect width/height value");
+		ANKI_LOGE("Incorrect width/height value");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	if(header.m_depth < 1 || header.m_depth > 16)
 	{
-		throw ANKI_EXCEPTION("Zero or too big depth");
+		ANKI_LOGE("Zero or too big depth");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	if(header.m_type < Image::TextureType::_2D 
 		|| header.m_type > Image::TextureType::_2D_ARRAY)
 	{
-		throw ANKI_EXCEPTION("Incorrect header: texture type");
+		ANKI_LOGE("Incorrect header: texture type");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	if(header.m_colorFormat < Image::ColorFormat::RGB8 
 		|| header.m_colorFormat > Image::ColorFormat::RGBA8)
 	{
-		throw ANKI_EXCEPTION("Incorrect header: color format");
+		ANKI_LOGE("Incorrect header: color format");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	if((header.m_compressionFormats & preferredCompression) 
 		== Image::DataCompression::NONE)
 	{
-		throw ANKI_EXCEPTION("File does not contain the wanted compression");
+		ANKI_LOGE("File does not contain the wanted compression");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	if(header.m_normal != 0 && header.m_normal != 1)
 	{
-		throw ANKI_EXCEPTION("Incorrect header: normal");
+		ANKI_LOGE("Incorrect header: normal");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	// Check mip levels
-	U size = std::min(header.m_width, header.m_height);
-	U maxsize = std::max(header.m_width, header.m_height);
+	size = std::min(header.m_width, header.m_height);
+	maxsize = std::max(header.m_width, header.m_height);
 	mipLevels = 0;
-	U tmpMipLevels = 0;
+	tmpMipLevels = 0;
 	while(size >= 4) // The minimum size is 4x4
 	{
 		++tmpMipLevels;
@@ -353,7 +467,9 @@ static void loadAnkiTexture(
 
 	if(tmpMipLevels != header.m_mipLevels)
 	{
-		throw ANKI_EXCEPTION("Incorrect number of mip levels");
+		ANKI_LOGE("Incorrect number of mip levels");
+		err = ErrorCode::USER_DATA;
+		goto cleanup;
 	}
 
 	colorFormat = header.m_colorFormat;
@@ -390,10 +506,9 @@ static void loadAnkiTexture(
 			!= Image::DataCompression::NONE)
 		{
 			// If raw compression is present then skip it
-			Error err = file.seek(
+			err = file.seek(
 				calcSizeOfSegment(header, Image::DataCompression::RAW), 
 				File::SeekOrigin::CURRENT);
-			ANKI_ASSERT(!err && "handle_error");
 		}
 	}
 	else if(preferredCompression == Image::DataCompression::ETC)
@@ -402,37 +517,43 @@ static void loadAnkiTexture(
 			!= Image::DataCompression::NONE)
 		{
 			// If raw compression is present then skip it
-			Error err = file.seek(
+			err = file.seek(
 				calcSizeOfSegment(header, Image::DataCompression::RAW), 
 				File::SeekOrigin::CURRENT);
-			ANKI_ASSERT(!err && "handle_error");
 		}
 
 		if((header.m_compressionFormats & Image::DataCompression::S3TC)
 			!= Image::DataCompression::NONE)
 		{
 			// If s3tc compression is present then skip it
-			Error err = file.seek(
+			err = file.seek(
 				calcSizeOfSegment(header, Image::DataCompression::S3TC), 
 				File::SeekOrigin::CURRENT);
-			ANKI_ASSERT(!err && "handle_error");
 		}
 	}
 
+	if(err)
+	{
+		goto cleanup;
+	}
+
 	//
 	// It's time to read
 	//
 
-	// Allocate the surfaces
-	ResourceAllocator<U8> alloc = surfaces.get_allocator(); 
-	surfaces.resize(mipLevels * depth, Image::Surface(alloc));
+	// Allocate the surfaces 
+	err = surfaces.create(alloc, mipLevels * depth);
+	if(err)
+	{
+		goto cleanup;
+	}
 
 	// Read all surfaces
-	U mipWidth = header.m_width;
-	U mipHeight = header.m_height;
-	for(U mip = 0; mip < header.m_mipLevels; mip++)
+	mipWidth = header.m_width;
+	mipHeight = header.m_height;
+	for(U mip = 0; mip < header.m_mipLevels && !err; mip++)
 	{
-		for(U d = 0; d < depth; d++)
+		for(U d = 0; d < depth && !err; d++)
 		{
 			U dataSize = calcSurfaceSize(
 				mipWidth, mipHeight, preferredCompression, 
@@ -442,24 +563,41 @@ static void loadAnkiTexture(
 			if(std::max(mipWidth, mipHeight) <= maxTextureSize)
 			{
 				U index = (mip - tmpMipLevels + mipLevels) * depth + d;
-				ANKI_ASSERT(index < surfaces.size());
+				ANKI_ASSERT(index < surfaces.getSize());
 				Image::Surface& surf = surfaces[index];
 				surf.m_width = mipWidth;
 				surf.m_height = mipHeight;
 
-				surf.m_data.resize(dataSize);
-				file.read(&surf.m_data[0], dataSize);
+				err = surf.m_data.create(alloc, dataSize);
+
+				if(!err)
+				{
+					err = file.read(&surf.m_data[0], dataSize);
+				}
 			}
 			else
 			{
-				Error err = file.seek(dataSize, File::SeekOrigin::CURRENT);
-				ANKI_ASSERT(!err && "handle_error");
+				err = file.seek(dataSize, File::SeekOrigin::CURRENT);
 			}
 		}
 
 		mipWidth /= 2;
 		mipHeight /= 2;
 	}
+
+cleanup:
+	// Cleanup
+	if(err)
+	{
+		for(Image::Surface& surf : surfaces)
+		{
+			surf.m_data.destroy(alloc);
+		}
+
+		surfaces.destroy(alloc);
+	}
+
+	return err;
 }
 
 //==============================================================================
@@ -467,33 +605,38 @@ static void loadAnkiTexture(
 //==============================================================================
 
 //==============================================================================
-void Image::load(const CString& filename, U32 maxTextureSize)
+Error Image::load(const CString& filename, U32 maxTextureSize)
 {
+	Error err = ErrorCode::NONE;
+
 	// get the extension
-	HeapAllocator<U8> alloc = m_surfaces.get_allocator();
-	String ext = getFileExtension(filename, alloc);
+	String ext = getFileExtension(filename, m_alloc);
 	
 	if(ext.isEmpty())
 	{
-		throw ANKI_EXCEPTION("Failed to get filename extension");
+		ANKI_LOGE("Failed to get filename extension");
+		return ErrorCode::USER_DATA;
 	}
 
 	// load from this extension
-	try
+	U32 bpp;
+	m_textureType = TextureType::_2D;
+	m_compression = DataCompression::RAW;
+
+	if(ext == "tga")
 	{
-		U32 bpp;
-		m_textureType = TextureType::_2D;
-		m_compression = DataCompression::RAW;
+		err = m_surfaces.create(m_alloc, 1);
 
-		if(ext == "tga")
+		if(!err)
 		{
-			ResourceAllocator<U8> alloc = m_surfaces.get_allocator(); 
-			m_surfaces.resize(1, Surface(alloc));
 			m_mipLevels = 1;
 			m_depth = 1;
-			loadTga(filename, m_surfaces[0].m_width, m_surfaces[0].m_height, 
-				bpp, m_surfaces[0].m_data);
+			err = loadTga(filename, m_surfaces[0].m_width, 
+				m_surfaces[0].m_height, bpp, m_surfaces[0].m_data, m_alloc);
+		}
 
+		if(!err)
+		{
 			if(bpp == 32)
 			{
 				m_colorFormat = ColorFormat::RGBA8;
@@ -507,30 +650,29 @@ void Image::load(const CString& filename, U32 maxTextureSize)
 				ANKI_ASSERT(0);
 			}
 		}
-		else if(ext == "ankitex")
-		{
+	}
+	else if(ext == "ankitex")
+	{
 #if 0
-			compression = Image::DataCompression::RAW;
+		compression = Image::DataCompression::RAW;
 #elif ANKI_GL == ANKI_GL_DESKTOP
-			m_compression = Image::DataCompression::S3TC;
+		m_compression = Image::DataCompression::S3TC;
 #else
-			m_compression = Image::DataCompression::ETC;
+		m_compression = Image::DataCompression::ETC;
 #endif
 
-			loadAnkiTexture(filename, maxTextureSize, 
-				m_compression, m_surfaces, m_depth, 
-				m_mipLevels, m_textureType, m_colorFormat);
+		err = loadAnkiTexture(filename, maxTextureSize, 
+			m_compression, m_surfaces, m_alloc, m_depth, 
+			m_mipLevels, m_textureType, m_colorFormat);
 
-		}
-		else
-		{
-			throw ANKI_EXCEPTION("Unsupported extension");
-		}
 	}
-	catch(std::exception& e)
+	else
 	{
-		throw ANKI_EXCEPTION("Failed to load image") << e;
+		ANKI_LOGE("Unsupported extension");
+		err = ErrorCode::USER_DATA;
 	}
+
+	return err;
 }
 
 //==============================================================================
@@ -556,11 +698,10 @@ const Image::Surface& Image::getSurface(U mipLevel, U layer) const
 		ANKI_ASSERT(0);
 	}
 
-
 	// [mip][depthFace]
 	U index = mipLevel * layers + layer;
 	
-	ANKI_ASSERT(index < m_surfaces.size());
+	ANKI_ASSERT(index < m_surfaces.getSize());
 
 	return m_surfaces[index];
 }

+ 1 - 1
src/resource/Material.cpp

@@ -6,7 +6,7 @@
 #include "anki/resource/Material.h"
 #include "anki/resource/MaterialProgramCreator.h"
 #include "anki/core/App.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/resource/ProgramResource.h"
 #include "anki/resource/TextureResource.h"
 #include "anki/util/Hash.h"

+ 1 - 1
src/resource/MaterialProgramCreator.cpp

@@ -7,7 +7,7 @@
 #include "anki/util/Assert.h"
 #include "anki/util/Exception.h"
 #include "anki/misc/Xml.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 #include <algorithm>
 #include <sstream>

+ 1 - 1
src/resource/MeshLoader.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/resource/MeshLoader.h"
 #include "anki/util/File.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include <cstring>
 #include <unordered_map>
 

+ 1 - 1
src/resource/Model.cpp

@@ -8,7 +8,7 @@
 #include "anki/resource/Mesh.h"
 #include "anki/resource/ProgramResource.h"
 #include "anki/misc/Xml.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 1 - 1
src/resource/ResourceManager.cpp

@@ -13,7 +13,7 @@
 #include "anki/resource/ProgramResource.h"
 #include "anki/resource/ParticleEmitterResource.h"
 #include "anki/resource/TextureResource.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/misc/ConfigSet.h"
 
 namespace anki {

+ 2 - 0
src/resource/TextureResource.cpp

@@ -217,6 +217,8 @@ void TextureResource::loadInternal(const CString& filename,
 
 	// Finaly enque the GL job chain
 	cmdb.flush();
+
+	m_size = UVec3(init.m_width, init.m_height, init.m_depth);
 }
 
 } // end namespace anki

+ 1 - 1
src/scene/Octree.cpp

@@ -10,7 +10,7 @@
 #include "anki/scene/Sector.h"
 #include "anki/scene/SceneGraph.h"
 #include "anki/util/Exception.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/scene/RenderComponent.h"
 
 namespace anki {

+ 1 - 1
src/scene/RenderComponent.cpp

@@ -6,7 +6,7 @@
 #include "anki/scene/RenderComponent.h"
 #include "anki/scene/SceneNode.h"
 #include "anki/resource/TextureResource.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 1 - 1
src/scene/Sector.cpp

@@ -11,7 +11,7 @@
 #include "anki/scene/Visibility.h"
 #include "anki/scene/FrustumComponent.h"
 #include "anki/scene/SceneGraph.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/renderer/Renderer.h"
 
 namespace anki {

+ 1 - 1
src/scene/Visibility.cpp

@@ -8,7 +8,7 @@
 #include "anki/scene/FrustumComponent.h"
 #include "anki/scene/Light.h"
 #include "anki/renderer/Renderer.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 1 - 1
src/script/LuaBinder.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/script/LuaBinder.h"
 #include "anki/util/Exception.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include <iostream>
 #include <cstring>
 

+ 1 - 1
src/script/ScriptManager.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/script/ScriptManager.h"
 #include "anki/util/Exception.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/script/Common.h"
 
 namespace anki {

+ 1 - 1
src/ui/UiFtFontLoader.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/ui/UiFtFontLoader.h"
 #include "anki/util/Exception.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 
 namespace anki {
 

+ 1 - 1
src/ui/UiPainter.cpp

@@ -6,7 +6,7 @@
 #include "anki/ui/UiPainter.h"
 #include "anki/gl/GlState.h"
 #include "anki/resource/TextureResource.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/ui/UiFont.h"
 #include <cstdarg>
 #include <cstdio>

+ 1 - 1
src/util/CMakeLists.txt

@@ -1,4 +1,4 @@
-set(ANKI_UTIL_SOURCES Assert.cpp Exception.cpp Functions.cpp File.cpp Filesystem.cpp Memory.cpp System.cpp HighRezTimer.cpp Thread.cpp Hash.cpp)
+set(ANKI_UTIL_SOURCES Assert.cpp Exception.cpp Functions.cpp File.cpp Filesystem.cpp Memory.cpp System.cpp HighRezTimer.cpp Thread.cpp Hash.cpp Logger.cpp)
 
 if(LINUX OR ANDROID OR MACOS)
 	set(ANKI_UTIL_SOURCES ${ANKI_UTIL_SOURCES} HighRezTimerPosix.cpp FilesystemPosix.cpp ThreadPosix.cpp)

+ 12 - 12
src/util/File.cpp

@@ -5,7 +5,7 @@
 
 #include "anki/util/File.h"
 #include "anki/util/Filesystem.h"
-#include "anki/util/Exception.h"
+#include "anki/util/Logger.h"
 #include "anki/util/Assert.h"
 #include <cstring>
 #include <cstdarg>
@@ -145,7 +145,7 @@ Error File::openCFile(const CString& filename, OpenFlag flags)
 	m_file = reinterpret_cast<FILE*>(fopen(filename.get(), openMode));
 	if(m_file == nullptr)
 	{
-		// Failed to open file
+		ANKI_LOGE("Failed to open file %s", &filename[0]);
 		err = ErrorCode::FILE_ACCESS;
 	}
 	else
@@ -291,7 +291,7 @@ Error File::flush()
 			I ierr = fflush(ANKI_CFILE);
 			if(ierr)
 			{
-				// fflush() failed
+				ANKI_LOGE("fflush() failed");
 				err = ErrorCode::FUNCTION_FAILED;
 			}
 		}
@@ -344,7 +344,7 @@ Error File::read(void* buff, PtrSize size)
 	Error err = ErrorCode::NONE;
 	if(static_cast<I64>(size) != readSize)
 	{
-		// File read failed
+		ANKI_LOGE("File read failed");
 		err = ErrorCode::FILE_ACCESS;
 	}
 
@@ -365,7 +365,7 @@ PtrSize File::getSize()
 		I64 size = ftell(ANKI_CFILE);
 		if(size < 1)
 		{
-			// ftell() failed
+			ANKI_LOGE("ftell() failed");
 		}
 		else
 		{
@@ -475,7 +475,7 @@ Error File::write(void* buff, PtrSize size)
 #endif
 		)
 	{
-		// Writting to archives is not supported
+		ANKI_LOGE("Writting to archives is not supported");
 		err = ErrorCode::FILE_ACCESS;
 	}
 	else
@@ -508,7 +508,7 @@ Error File::writeText(CString format, ...)
 #endif
 		)
 	{
-		// Writting to archives is not supported
+		ANKI_LOGE("Writting to archives is not supported");
 		err = ErrorCode::FILE_ACCESS;
 	}
 	else
@@ -531,7 +531,7 @@ Error File::seek(PtrSize offset, SeekOrigin origin)
 	{
 		if(fseek(ANKI_CFILE, offset, (I)origin) != 0)
 		{
-			// fseek() failed
+			ANKI_LOGE("fseek() failed");
 			err = ErrorCode::FUNCTION_FAILED;
 		}
 	}
@@ -543,7 +543,7 @@ Error File::seek(PtrSize offset, SeekOrigin origin)
 			if(unzCloseCurrentFile(m_file)
 				|| unzOpenCurrentFile(m_file))
 			{
-				// Rewind failed
+				ANKI_LOGE("Rewind failed");
 				err = ErrorCode::FUNCTION_FAILED;
 			}
 		}
@@ -565,7 +565,7 @@ Error File::seek(PtrSize offset, SeekOrigin origin)
 	{
 		if(AAsset_seek(ANKI_AFILE, offset, origin) == (off_t)-1)
 		{
-			// AAsset_seek() failed
+			ANKI_LOGE("AAsset_seek() failed");
 			err = ErrorCode::FUNCTION_FAILED;
 		}
 	}
@@ -611,13 +611,13 @@ Error File::identifyFile(const CString& filename,
 
 			if(archLen + 1 >= fnameLen)
 			{
-				// Too sort archived filename
+				ANKI_LOGE("Too sort archived filename");
 				err = ErrorCode::FILE_NOT_FOUND;
 			}
 
 			if(archiveFilenameLength > archLen)
 			{
-				// Using too long paths
+				ANKI_LOGE("Using too long paths");
 				err = ErrorCode::FILE_NOT_FOUND;
 			}
 

+ 51 - 75
src/core/Logger.cpp → src/util/Logger.cpp

@@ -3,10 +3,11 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#include "anki/core/Logger.h"
-#include "anki/core/App.h"
+#include "anki/util/Logger.h"
+#include "anki/util/File.h"
 #include <cstring>
 #include <cstdarg>
+#include <cstdio>
 #if ANKI_OS == ANKI_OS_ANDROID
 #	include <android/log.h>
 #endif
@@ -14,38 +15,23 @@
 namespace anki {
 
 //==============================================================================
-Logger::Logger(InitFlags flags, HeapAllocator<U8>& alloc, const char* cacheDir)
-:	m_handlers(alloc)
-{
-	if((flags & InitFlags::WITH_SYSTEM_MESSAGE_HANDLER) != InitFlags::NONE)
-	{
-		addMessageHandler(this, &defaultSystemMessageHandler);
-	}
-
-	if((flags & InitFlags::WITH_LOG_FILE_MESSAGE_HANDLER) != InitFlags::NONE)
-	{
-		U size = std::strlen(cacheDir) + 1;
-		m_cacheDir = reinterpret_cast<char*>(alloc.allocate(size));
-		std::memcpy(m_cacheDir, cacheDir, size);
+static const Array<const char*, static_cast<U>(Logger::MessageType::COUNT)> 
+	MSG_TEXT = {{"Info", "Error", "Warning", "Fatal"}};
 
-		addMessageHandler(this, &logfileMessageHandler);
-	}
+//==============================================================================
+Logger::Logger()
+{
+	addMessageHandler(this, &defaultSystemMessageHandler);
 }
 
 //==============================================================================
 Logger::~Logger()
-{
-	if(m_cacheDir != nullptr)
-	{
-		HeapAllocator<char> alloc = m_handlers.get_allocator();
-		alloc.deallocate(m_cacheDir, 0);
-	}
-}
+{}
 
 //==============================================================================
 void Logger::addMessageHandler(void* data, MessageHandlerCallback callback)
 {
-	m_handlers.push_back(Handler{data, callback});
+	m_handlers[m_handlersCount++] =  Handler(data, callback);
 }
 
 //==============================================================================
@@ -56,12 +42,18 @@ void Logger::write(const char* file, int line, const char* func,
 
 	Info inf = {file, line, func, type, msg};
 
-	for(Handler& handler : m_handlers)
+	U count = m_handlersCount;
+	while(count-- != 0)
 	{
-		handler.m_callback(handler.m_data, inf);
+		m_handlers[count].m_callback(m_handlers[count].m_data, inf);
 	}
 
 	m_mutex.unlock();
+
+	if(type == MessageType::FATAL)
+	{
+		abort();
+	}
 }
 
 //==============================================================================
@@ -81,32 +73,32 @@ void Logger::writeFormated(const char* file, int line, const char* func,
 void Logger::defaultSystemMessageHandler(void*, const Info& info)
 {
 #if ANKI_OS == ANKI_OS_LINUX
-	std::ostream* out = NULL;
-	const char* x = NULL;
+	FILE* out = nullptr;
 	const char* terminalColor = nullptr;
 
 	switch(info.m_type)
 	{
 	case Logger::MessageType::NORMAL:
-		out = &std::cout;
-		x = "Info";
+		out = stdout;
 		terminalColor = "\033[0;32m";
 		break;
 	case Logger::MessageType::ERROR:
-		out = &std::cerr;
-		x = "Error";
+		out = stderr;
 		terminalColor = "\033[0;31m";
 		break;
 	case Logger::MessageType::WARNING:
-		out = &std::cerr;
-		x = "Warn";
+		out = stderr;
 		terminalColor = "\033[0;33m";
 		break;
+	case Logger::MessageType::FATAL:
+		out = stderr;
+		terminalColor = "\033[0;31m";
+		break;
 	}
 
-	(*out) << terminalColor << "(" << info.m_file << ":" << info.m_line << " "
-		<< info.m_func << ") " << x << ": " << info.m_msg 
-		<< "\033[0m" << std::endl;
+	fprintf(out, "%s(%s:%d %s) %s: %s\033[0m\n", terminalColor, info.m_file,
+		info.m_line, info.m_func, MSG_TEXT[static_cast<U>(info.m_type)], 
+		info.m_msg);
 #elif ANKI_OS == ANKI_OS_ANDROID
 	U32 andMsgType = ANDROID_LOG_INFO;
 
@@ -121,6 +113,9 @@ void Logger::defaultSystemMessageHandler(void*, const Info& info)
 	case Logger::MessageType::WARNING:
 		andMsgType = ANDROID_LOG_WARN;
 		break;
+	case Logger::MessageType::FATAL:
+		andMsgType = ANDROID_LOG_ERROR;
+		break;
 	}
 
 	std::stringstream ss;
@@ -128,63 +123,44 @@ void Logger::defaultSystemMessageHandler(void*, const Info& info)
 	__android_log_print(andMsgType, "AnKi", "(%s:%d %s) %s", info.m_file,
 		info.m_line, info.m_func, info.m_msg);
 #else
-	std::ostream* out = NULL;
-	const char* x = NULL;
+	FILE* out = NULL;
 
 	switch(info.m_type)
 	{
 	case Logger::MessageType::NORMAL:
-		out = &std::cout;
-		x = "Info";
+		out = stdout;
 		break;
 	case Logger::MessageType::ERROR:
-		out = &std::cerr;
-		x = "Error";
+		out = stderr;
 		break;
 	case Logger::MessageType::WARNING:
-		out = &std::cerr;
-		x = "Warn";
+		out = stderr;
+		break;
+	case Logger::MessageType::FATAL:
+		out = stderr;
 		break;
 	}
 
-	(*out) << "(" << info.m_file << ":" << info.m_line << " "
-		<< info.m_func << ") " << x << ": " << info.m_msg << std::endl;
+	fprintf(out, "(%s:%d %s) %s: %s\n", info.m_file,
+		info.m_line, info.m_func, MSG_TEXT[static_cast<U>(info.m_type)], 
+		info.m_msg);
 #endif
 }
 
 //==============================================================================
-void Logger::logfileMessageHandler(void* vlogger, const Info& info)
+void Logger::fileMessageHandler(void* pfile, const Info& info)
 {
-	Logger* logger = (Logger*)vlogger;
+	File* file = reinterpret_cast<File*>(pfile);
 
-	// Init the file
-	if(!logger->m_logfile.isOpen())
-	{
-		String filename(logger->m_handlers.get_allocator());
-		filename = logger->m_cacheDir;
-		filename += "/anki.log";
-
-		logger->m_logfile.open(filename.toCString(), File::OpenFlag::WRITE);
-	}
+	Error err = file->writeText("(%s:%d %s) %s: %s\n", 
+		info.m_file, info.m_line, info.m_func, 
+		MSG_TEXT[static_cast<U>(info.m_type)], info.m_msg);
 
-	const char* x = nullptr;
-	switch(info.m_type)
+	if(!err)
 	{
-	case Logger::MessageType::NORMAL:
-		x = "Info";
-		break;
-	case Logger::MessageType::ERROR:
-		x = "Error";
-		break;
-	case Logger::MessageType::WARNING:
-		x = "Warn";
-		break;
+		err = file->flush();
+		(void)err;
 	}
-
-	logger->m_logfile.writeText("(%s:%d %s) %s: %s\n", 
-		info.m_file, info.m_line, info.m_func, x, info.m_msg);
-
-	logger->m_logfile.flush();
 }
 
 } // end namespace anki

+ 0 - 1
src/util/Memory.cpp

@@ -4,7 +4,6 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/util/Memory.h"
-#include "anki/util/Exception.h"
 #include "anki/util/Functions.h"
 #include "anki/util/Assert.h"
 #include "anki/util/NonCopyable.h"

+ 1 - 1
testapp/Main.cpp

@@ -14,7 +14,7 @@
 #include "anki/script/ScriptManager.h"
 #include "anki/core/StdinListener.h"
 #include "anki/resource/Model.h"
-#include "anki/core/Logger.h"
+#include "anki/util/Logger.h"
 #include "anki/Util.h"
 #include "anki/resource/Skin.h"
 #include "anki/event/EventManager.h"