Browse Source

core: add Allocator::reallocate()

Daniele Bartolini 4 năm trước cách đây
mục cha
commit
dc0219acc7

+ 1 - 0
docs/changelog.rst

@@ -14,6 +14,7 @@ Changelog
 
 * Added --pumped mode to skip rendering of frames unless explicitly requested.
 * Fixed the creation of uniforms with ``matrix4x4`` type.
+* Fixed crashes when loading shaders in some circumnstances.
 
 **Tools**
 

+ 3 - 0
src/core/memory/allocator.h

@@ -37,6 +37,9 @@ struct Allocator
 	/// Deallocates a previously allocated block of memory pointed by @a data.
 	virtual void deallocate(void* data) = 0;
 
+	/// See: realloc().
+	virtual void* reallocate(void* data, u32 size, u32 align = DEFAULT_ALIGN);
+
 	/// Returns the size of the memory block pointed by @a ptr or SIZE_NOT_TRACKED
 	/// if the allocator does not support memory tracking.
 	/// @a ptr must be a pointer returned by Allocator::allocate().

+ 33 - 0
src/core/memory/globals.cpp

@@ -9,6 +9,7 @@
 #include "core/memory/memory.inl"
 #include "core/thread/scoped_mutex.inl"
 #include <stdlib.h> // malloc
+#include <string.h> // memcpy
 
 // void* operator new(size_t) throw (std::bad_alloc)
 // {
@@ -36,6 +37,15 @@
 
 namespace crown
 {
+void* Allocator::reallocate(void* data, u32 size, u32 align)
+{
+	CE_UNUSED(data);
+	CE_UNUSED(size);
+	CE_UNUSED(align);
+	CE_FATAL("reallocate() not supported.");
+	return NULL;
+}
+
 namespace memory
 {
 	// Header stored at the beginning of a memory allocation to indicate the
@@ -148,6 +158,29 @@ namespace memory
 			free(h);
 		}
 
+		void* reallocate(void* data, u32 size, u32 align)
+		{
+			if (!data)
+				return allocate((u32)size, (u32)align == 0 ? 16 : (u32)align);
+
+			if (size == 0)
+			{
+				deallocate(data);
+				return NULL;
+			}
+
+			// Figure out the size of data.
+			const Header* data_header = header(data);
+			const char* data_end      = (char*)data_header + data_header->size;
+			const u32 data_size       = u32(data_end - (char*)data);
+
+			// Simulate realloc().
+			void* p = allocate((u32)size, (u32)align == 0 ? 16 : (u32)align);
+			memcpy(p, data, min(data_size, size));
+			deallocate(data);
+			return p;
+		}
+
 		/// @copydoc Allocator::allocated_size()
 		u32 allocated_size(const void* ptr)
 		{

+ 22 - 0
src/core/memory/proxy_allocator.cpp

@@ -29,6 +29,28 @@ void ProxyAllocator::deallocate(void* data)
 	_allocator.deallocate(data);
 }
 
+void* ProxyAllocator::reallocate(void* data, u32 size, u32 align)
+{
+	if (!data)
+	{
+		void* ptr = _allocator.reallocate(data, size, align);
+		ALLOCATE_MEMORY(_name, _allocator.allocated_size(ptr));
+		return ptr;
+	}
+
+	if (size == 0)
+	{
+		DEALLOCATE_MEMORY(_name, _allocator.allocated_size(data));
+		return _allocator.reallocate(data, size, align);
+	}
+
+	const u32 data_size = _allocator.allocated_size(data);
+	void* ptr = _allocator.reallocate(data, size, align);
+	ALLOCATE_MEMORY(_name, _allocator.allocated_size(ptr));
+	DEALLOCATE_MEMORY(_name, data_size);
+	return ptr;
+}
+
 const char* ProxyAllocator::name() const
 {
 	return _name;

+ 3 - 0
src/core/memory/proxy_allocator.h

@@ -26,6 +26,9 @@ struct ProxyAllocator : public Allocator
 	/// @copydoc Allocator::deallocate()
 	void deallocate(void* data);
 
+	/// @copydoc Allocator::reallocate().
+	virtual void* reallocate(void* data, u32 size, u32 align = DEFAULT_ALIGN);
+
 	/// @copydoc Allocator::allocated_size()
 	u32 allocated_size(const void* ptr) { return _allocator.allocated_size(ptr); }
 

+ 5 - 13
src/device/device.cpp

@@ -150,21 +150,13 @@ struct BgfxAllocator : public bx::AllocatorI
 	{
 	}
 
-	virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* /*_file*/, u32 /*_line*/)
+	~BgfxAllocator()
 	{
-		if (!_ptr)
-			return _allocator.allocate((u32)_size, (u32)_align == 0 ? 16 : (u32)_align);
-
-		if (_size == 0)
-		{
-			_allocator.deallocate(_ptr);
-			return NULL;
-		}
+	}
 
-		// Realloc
-		void* p = _allocator.allocate((u32)_size, (u32)_align == 0 ? 16 : (u32)_align);
-		_allocator.deallocate(_ptr);
-		return p;
+	virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* /*_file*/, u32 /*_line*/)
+	{
+		return _allocator.reallocate(_ptr, _size, _align);
 	}
 };