|
@@ -6,6 +6,8 @@
|
|
|
#pragma once
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <anki/gr/Common.h>
|
|
#include <anki/gr/Common.h>
|
|
|
|
|
+#include <anki/gr/GrObjectCache.h>
|
|
|
|
|
+#include <anki/gr/GrObject.h>
|
|
|
#include <anki/util/String.h>
|
|
#include <anki/util/String.h>
|
|
|
|
|
|
|
|
namespace anki
|
|
namespace anki
|
|
@@ -47,6 +49,9 @@ class GrManager
|
|
|
{
|
|
{
|
|
|
friend class GrManagerImpl;
|
|
friend class GrManagerImpl;
|
|
|
|
|
|
|
|
|
|
+ template<typename>
|
|
|
|
|
+ friend class GrObjectPtrDeleter;
|
|
|
|
|
+
|
|
|
public:
|
|
public:
|
|
|
/// Default constructor
|
|
/// Default constructor
|
|
|
GrManager();
|
|
GrManager();
|
|
@@ -64,10 +69,15 @@ public:
|
|
|
|
|
|
|
|
/// Create a new graphics object.
|
|
/// Create a new graphics object.
|
|
|
template<typename T, typename... Args>
|
|
template<typename T, typename... Args>
|
|
|
- IntrusivePtr<T> newInstance(Args&&... args);
|
|
|
|
|
|
|
+ GrObjectPtr<T> newInstance(Args&&... args);
|
|
|
|
|
+
|
|
|
|
|
+ /// Create a new graphics object and use the cache to avoid duplication.
|
|
|
|
|
+ /// It's thread safe.
|
|
|
|
|
+ template<typename T, typename TArg>
|
|
|
|
|
+ GrObjectPtr<T> newInstanceCached(const TArg& arg);
|
|
|
|
|
|
|
|
/// Allocate memory for dynamic buffers. The memory will be reclaimed at
|
|
/// Allocate memory for dynamic buffers. The memory will be reclaimed at
|
|
|
- /// the begining of the next frame.
|
|
|
|
|
|
|
+ /// the begining of the N-(MAX_FRAMES_IN_FLIGHT-1) frame.
|
|
|
void* allocateFrameHostVisibleMemory(
|
|
void* allocateFrameHostVisibleMemory(
|
|
|
PtrSize size, BufferUsage usage, DynamicBufferToken& token);
|
|
PtrSize size, BufferUsage usage, DynamicBufferToken& token);
|
|
|
|
|
|
|
@@ -97,20 +107,59 @@ anki_internal:
|
|
|
return m_uuidIndex;
|
|
return m_uuidIndex;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ void unregisterCachedObject(GrObject* ptr)
|
|
|
|
|
+ {
|
|
|
|
|
+ ANKI_ASSERT(ptr);
|
|
|
|
|
+ if(ptr->getHash() != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ GrObjectCache& cache = m_caches[ptr->getType()];
|
|
|
|
|
+ LockGuard<Mutex> lock(cache.getMutex());
|
|
|
|
|
+ cache.unregisterObject(ptr);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private:
|
|
private:
|
|
|
GrAllocator<U8> m_alloc; ///< Keep it first to get deleted last
|
|
GrAllocator<U8> m_alloc; ///< Keep it first to get deleted last
|
|
|
UniquePtr<GrManagerImpl> m_impl;
|
|
UniquePtr<GrManagerImpl> m_impl;
|
|
|
String m_cacheDir;
|
|
String m_cacheDir;
|
|
|
U64 m_uuidIndex = 1;
|
|
U64 m_uuidIndex = 1;
|
|
|
|
|
+ Array<GrObjectCache, U(GrObjectType::COUNT)> m_caches;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+//==============================================================================
|
|
|
template<typename T, typename... Args>
|
|
template<typename T, typename... Args>
|
|
|
-IntrusivePtr<T> GrManager::newInstance(Args&&... args)
|
|
|
|
|
|
|
+GrObjectPtr<T> GrManager::newInstance(Args&&... args)
|
|
|
{
|
|
{
|
|
|
- IntrusivePtr<T> ptr(m_alloc.newInstance<T>(this));
|
|
|
|
|
|
|
+ const U64 hash = 0;
|
|
|
|
|
+ GrObjectPtr<T> ptr(m_alloc.newInstance<T>(this, hash));
|
|
|
ptr->init(args...);
|
|
ptr->init(args...);
|
|
|
return ptr;
|
|
return ptr;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+//==============================================================================
|
|
|
|
|
+template<typename T, typename TArg>
|
|
|
|
|
+GrObjectPtr<T> GrManager::newInstanceCached(const TArg& arg)
|
|
|
|
|
+{
|
|
|
|
|
+ GrObjectCache& cache = m_caches[T::CLASS_TYPE];
|
|
|
|
|
+ U64 hash = arg.computeHash();
|
|
|
|
|
+ ANKI_ASSERT(hash != 0);
|
|
|
|
|
+
|
|
|
|
|
+ LockGuard<Mutex> lock(cache.getMutex());
|
|
|
|
|
+ GrObject* ptr = cache.tryFind(hash);
|
|
|
|
|
+ if(ptr == nullptr)
|
|
|
|
|
+ {
|
|
|
|
|
+ T* tptr = m_alloc.newInstance<T>(this, hash);
|
|
|
|
|
+ tptr->init(arg);
|
|
|
|
|
+ ptr = tptr;
|
|
|
|
|
+ cache.registerObject(ptr);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ANKI_ASSERT(ptr->getType() == T::CLASS_TYPE);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return GrObjectPtr<T>(static_cast<T*>(ptr));
|
|
|
|
|
+}
|
|
|
/// @}
|
|
/// @}
|
|
|
|
|
|
|
|
} // end namespace anki
|
|
} // end namespace anki
|