| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #pragma once
- #include "BsPrerequisitesUtil.h"
- namespace BansheeEngine
- {
- /**
- * @brief Frame allocator. Performs very fast allocations but can only free all of its memory at once.
- * Perfect for allocations that last just a single frame.
- *
- * @note Not thread safe with an exception. "alloc" and "clear" methods need to be called from the same thread.
- * "dealloc" is thread safe and can be called from any thread.
- */
- class BS_UTILITY_EXPORT FrameAlloc
- {
- private:
- class MemBlock
- {
- public:
- MemBlock(UINT32 size);
- ~MemBlock();
- UINT8* alloc(UINT8 amount);
- void clear();
- UINT8* mData;
- UINT32 mFreePtr;
- UINT32 mSize;
- };
- public:
- FrameAlloc(UINT32 blockSize = 1024 * 1024);
- ~FrameAlloc();
- /**
- * @brief Allocates a new block of memory of the specified size.
- *
- * @param amount Amount of memory to allocate, in bytes.
- *
- * @note Not thread safe.
- */
- UINT8* alloc(UINT32 amount);
- /**
- * @brief Deallocates a previously allocated block of memory.
- *
- * @note No deallocation is actually done here. This method is only used for debug purposes
- * so it is easier to track down memory leaks and corruption.
- *
- * Thread safe.
- */
- void dealloc(UINT8* data);
- /**
- * @brief Deallocates all allocated memory.
- *
- * @note Not thread safe.
- */
- void clear();
- private:
- UINT32 mBlockSize;
- Vector<MemBlock*> mBlocks;
- MemBlock* mFreeBlock;
- std::atomic<UINT32> mTotalAllocBytes;
- MemBlock* allocBlock(UINT32 wantedSize);
- void deallocBlock(MemBlock* block);
- };
- /**
- * @brief Allocator for the standard library that internally uses a
- * frame allocator.
- */
- template <class T>
- class StdFrameAlloc
- {
- public:
- // Type definitions
- typedef T value_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- /**
- * @brief Rebind allocator to type U
- */
- template <class U>
- struct rebind
- {
- typedef StdFrameAlloc<U> other;
- };
- StdFrameAlloc() throw()
- :mFrameAlloc(nullptr)
- { }
- StdFrameAlloc(FrameAlloc* frameAlloc) throw()
- :mFrameAlloc(frameAlloc)
- { }
- StdFrameAlloc(const StdFrameAlloc&) throw()
- { }
- template <class U>
- StdFrameAlloc(const StdFrameAlloc<U>&) throw()
- { }
- ~StdFrameAlloc() throw()
- { }
- /**
- * @brief Return address of value.
- */
- pointer address(reference value) const
- {
- return &value;
- }
- /**
- * @brief Return address of value.
- */
- const_pointer address(const_reference value) const
- {
- return &value;
- }
- /**
- * @brief Return maximum number of elements that can be allocated.
- */
- size_type max_size() const throw()
- {
- return std::numeric_limits<std::size_t>::max() / sizeof(T);
- }
- /**
- * @brief Allocate but don't initialize number elements of type T.
- */
- pointer allocate(size_type num, const void* = 0)
- {
- pointer ret = (pointer)(mFrameAlloc->alloc((UINT32)num*sizeof(T)));
- return ret;
- }
- /**
- * @brief Initialize elements of allocated storage p with value "value".
- */
- void construct(pointer p, const T& value)
- {
- new((void*)p)T(value);
- }
- /**
- * @brief Destroy elements of initialized storage p.
- */
- void destroy(pointer p)
- {
- p->~T();
- }
- /**
- * @brief Deallocate storage p of deleted elements.
- */
- void deallocate(pointer p, size_type num)
- {
- mFrameAlloc->dealloc((UINT8*)p);
- }
- private:
- FrameAlloc* mFrameAlloc;
- };
- /**
- * @brief Return that all specializations of this allocator are interchangeable.
- */
- template <class T1, class T2>
- bool operator== (const StdFrameAlloc<T1>&,
- const StdFrameAlloc<T2>&) throw() {
- return true;
- }
- /**
- * @brief Return that all specializations of this allocator are interchangeable.
- */
- template <class T1, class T2>
- bool operator!= (const StdFrameAlloc<T1>&,
- const StdFrameAlloc<T2>&) throw() {
- return false;
- }
- }
|