forked from organicmaps/organicmaps
locking and unlocking GL buffers on the main thread to support GL buffers in PartialRenderPolicy.
This commit is contained in:
parent
4fcc52f3aa
commit
fca2a020cb
12 changed files with 238 additions and 53 deletions
|
@ -3,6 +3,7 @@
|
|||
#include "threaded_list.hpp"
|
||||
#include "logging.hpp"
|
||||
#include "../std/bind.hpp"
|
||||
#include "../std/scoped_ptr.hpp"
|
||||
|
||||
struct BasePoolElemFactory
|
||||
{
|
||||
|
@ -14,24 +15,88 @@ struct BasePoolElemFactory
|
|||
size_t ElemSize() const;
|
||||
};
|
||||
|
||||
/// basic traits maintains a list of free resources.
|
||||
template <typename TElem, typename TElemFactory>
|
||||
struct BasePoolTraits
|
||||
{
|
||||
TElemFactory m_factory;
|
||||
ThreadedList<TElem> m_pool;
|
||||
|
||||
BasePoolTraits(TElemFactory const & factory) : m_factory(factory)
|
||||
typedef TElem elem_t;
|
||||
|
||||
BasePoolTraits(TElemFactory const & factory)
|
||||
: m_factory(factory)
|
||||
{}
|
||||
|
||||
void Free(ThreadedList<TElem> & elems, TElem const & elem)
|
||||
void Free(TElem const & elem)
|
||||
{
|
||||
elems.PushBack(elem);
|
||||
m_pool.PushBack(elem);
|
||||
}
|
||||
|
||||
size_t Size() const
|
||||
{
|
||||
return m_pool.Size();
|
||||
}
|
||||
|
||||
void Cancel()
|
||||
{
|
||||
m_pool.Cancel();
|
||||
}
|
||||
|
||||
bool IsCancelled() const
|
||||
{
|
||||
return m_pool.IsCancelled();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TElem, typename TElemFactory>
|
||||
struct FixedSizePoolTraits : BasePoolTraits<TElem, TElemFactory>
|
||||
/// This traits stores the free elements in a separate pool and has
|
||||
/// a separate method to merge them all into a main pool.
|
||||
/// For example should be used for resources where a certain preparation operation
|
||||
/// should be performed on main thread before returning resource
|
||||
/// to a free pool(p.e. @see resource_manager.cpp StorageFactory)
|
||||
template <typename TElemFactory, typename TBase>
|
||||
struct SeparateFreePoolTraits : TBase
|
||||
{
|
||||
typedef BasePoolTraits<TElem, TElemFactory> base_t;
|
||||
typedef TBase base_t;
|
||||
typedef typename base_t::elem_t elem_t;
|
||||
|
||||
ThreadedList<elem_t> m_freePool;
|
||||
|
||||
SeparateFreePoolTraits(TElemFactory const & factory)
|
||||
: base_t(factory)
|
||||
{}
|
||||
|
||||
void Free(elem_t const & elem)
|
||||
{
|
||||
m_freePool.PushBack(elem);
|
||||
}
|
||||
|
||||
void MergeImpl(list<elem_t> & l)
|
||||
{
|
||||
for (typename list<elem_t>::const_iterator it = l.begin();
|
||||
it != l.end();
|
||||
++it)
|
||||
{
|
||||
base_t::m_factory.BeforeMerge(*it);
|
||||
base_t::m_pool.PushBack(*it);
|
||||
}
|
||||
|
||||
l.clear();
|
||||
}
|
||||
|
||||
void Merge()
|
||||
{
|
||||
m_freePool.ProcessList(bind(&SeparateFreePoolTraits<TElemFactory, TBase>::MergeImpl, this, _1));
|
||||
}
|
||||
};
|
||||
|
||||
/// This traits maintains a fixed-size of pre-allocated resources.
|
||||
template <typename TElemFactory, typename TBase >
|
||||
struct FixedSizePoolTraits : TBase
|
||||
{
|
||||
typedef TBase base_t;
|
||||
typedef typename base_t::elem_t elem_t;
|
||||
|
||||
size_t m_count;
|
||||
bool m_isAllocated;
|
||||
|
||||
|
@ -41,7 +106,7 @@ struct FixedSizePoolTraits : BasePoolTraits<TElem, TElemFactory>
|
|||
m_isAllocated(false)
|
||||
{}
|
||||
|
||||
TElem const Reserve(ThreadedList<TElem> & elems)
|
||||
elem_t const Reserve()
|
||||
{
|
||||
if (!m_isAllocated)
|
||||
{
|
||||
|
@ -50,17 +115,19 @@ struct FixedSizePoolTraits : BasePoolTraits<TElem, TElemFactory>
|
|||
LOG(LDEBUG, ("allocating ", base_t::m_factory.ElemSize() * m_count, "bytes for ", base_t::m_factory.ResName()));
|
||||
|
||||
for (size_t i = 0; i < m_count; ++i)
|
||||
elems.PushBack(base_t::m_factory.Create());
|
||||
base_t::m_pool.PushBack(base_t::m_factory.Create());
|
||||
}
|
||||
|
||||
return elems.Front(true);
|
||||
return base_t::m_pool.Front(true);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TElem, typename TElemFactory>
|
||||
struct AllocateOnDemandPoolTraits : BasePoolTraits<TElem, TElemFactory>
|
||||
/// This traits allocates resources on demand.
|
||||
template <typename TElemFactory, typename TBase>
|
||||
struct AllocateOnDemandPoolTraits : TBase
|
||||
{
|
||||
typedef BasePoolTraits<TElem, TElemFactory> base_t;
|
||||
typedef TBase base_t;
|
||||
typedef typename base_t::elem_t elem_t;
|
||||
|
||||
size_t m_poolSize;
|
||||
AllocateOnDemandPoolTraits(TElemFactory const & factory, size_t )
|
||||
|
@ -68,7 +135,7 @@ struct AllocateOnDemandPoolTraits : BasePoolTraits<TElem, TElemFactory>
|
|||
m_poolSize(0)
|
||||
{}
|
||||
|
||||
void ReserveImpl(list<TElem> & l, TElem & elem)
|
||||
void ReserveImpl(list<elem_t> & l, elem_t & elem)
|
||||
{
|
||||
if (l.empty())
|
||||
{
|
||||
|
@ -82,27 +149,28 @@ struct AllocateOnDemandPoolTraits : BasePoolTraits<TElem, TElemFactory>
|
|||
l.pop_back();
|
||||
}
|
||||
|
||||
TElem const Reserve(ThreadedList<TElem> & elems)
|
||||
elem_t const Reserve()
|
||||
{
|
||||
TElem elem;
|
||||
elems.ProcessList(bind(&AllocateOnDemandPoolTraits<TElem, TElemFactory>::ReserveImpl, this, _1, ref(elem)));
|
||||
elem_t elem;
|
||||
base_t::m_pool.ProcessList(bind(&AllocateOnDemandPoolTraits<elem_t, TElemFactory>::ReserveImpl, this, _1, ref(elem)));
|
||||
return elem;
|
||||
}
|
||||
};
|
||||
|
||||
// This class tracks OpenGL resources allocation in
|
||||
// a multithreaded environment.
|
||||
template <typename TElem, typename TPoolTraits>
|
||||
template <typename TPoolTraits>
|
||||
class ResourcePool
|
||||
{
|
||||
private:
|
||||
|
||||
TPoolTraits m_traits;
|
||||
ThreadedList<TElem> m_pool;
|
||||
scoped_ptr<TPoolTraits> m_traits;
|
||||
|
||||
public:
|
||||
|
||||
ResourcePool(TPoolTraits const & traits)
|
||||
typedef typename TPoolTraits::elem_t elem_t;
|
||||
|
||||
ResourcePool(TPoolTraits * traits)
|
||||
: m_traits(traits)
|
||||
{
|
||||
/// quick trick to perform lazy initialization
|
||||
|
@ -110,19 +178,19 @@ public:
|
|||
Free(Reserve());
|
||||
}
|
||||
|
||||
TElem const Reserve()
|
||||
elem_t const Reserve()
|
||||
{
|
||||
return m_traits.Reserve(m_pool);
|
||||
return m_traits->Reserve();
|
||||
}
|
||||
|
||||
void Free(TElem const & elem)
|
||||
void Free(elem_t const & elem)
|
||||
{
|
||||
m_traits.Free(m_pool, elem);
|
||||
m_traits->Free(elem);
|
||||
}
|
||||
|
||||
size_t Size() const
|
||||
{
|
||||
return m_pool.Size();
|
||||
return m_traits->Size();
|
||||
}
|
||||
|
||||
void EnterForeground()
|
||||
|
@ -133,11 +201,16 @@ public:
|
|||
|
||||
void Cancel()
|
||||
{
|
||||
m_pool.Cancel();
|
||||
return m_traits->Cancel();
|
||||
}
|
||||
|
||||
bool IsCancelled() const
|
||||
{
|
||||
return m_pool.IsCancelled();
|
||||
return m_traits->IsCancelled();
|
||||
}
|
||||
|
||||
void Merge()
|
||||
{
|
||||
m_traits->Merge();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -32,6 +32,7 @@ void PartialRenderPolicy::ProcessRenderQueue(list<yg::gl::Renderer::Packet> & re
|
|||
void PartialRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
|
||||
ScreenBase const & screenBase)
|
||||
{
|
||||
m_resourceManager->mergeFreeResources();
|
||||
/// blitting from the current surface onto screen
|
||||
// RenderPolicyMT::DrawFrame(paintEvent, screenBase);
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ void RenderPolicyMT::EndFrame(shared_ptr<PaintEvent> const & e,
|
|||
void RenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e,
|
||||
ScreenBase const & s)
|
||||
{
|
||||
m_resourceManager->mergeFreeResources();
|
||||
|
||||
if (m_DoAddCommand && (s != m_renderQueue->renderState().m_actualScreen))
|
||||
m_renderQueue->AddCommand(m_renderFn, s);
|
||||
|
||||
|
|
|
@ -318,7 +318,7 @@ namespace yg
|
|||
LOG(LINFO, ("performing IMMDrawTexturedPrimitives command"));
|
||||
yg::gl::Storage blitStorage = m_resourceManager->blitStorages()->Reserve();
|
||||
|
||||
AuxVertex * pointsData = (AuxVertex*)blitStorage.m_vertices->lock();
|
||||
AuxVertex * pointsData = (AuxVertex*)blitStorage.m_vertices->data();
|
||||
|
||||
for (size_t i = 0; i < m_ptsCount; ++i)
|
||||
{
|
||||
|
@ -338,7 +338,7 @@ namespace yg
|
|||
m_texture->makeCurrent();
|
||||
|
||||
unsigned short idxData[4] = {0, 1, 2, 3};
|
||||
memcpy(blitStorage.m_indices->lock(), idxData, sizeof(idxData));
|
||||
memcpy(blitStorage.m_indices->data(), idxData, sizeof(idxData));
|
||||
blitStorage.m_indices->unlock();
|
||||
blitStorage.m_indices->makeCurrent();
|
||||
|
||||
|
|
|
@ -69,8 +69,8 @@ namespace yg
|
|||
m_maxVertices = m_storage.m_vertices->size() / sizeof(Vertex);
|
||||
m_maxIndices = m_storage.m_indices->size() / sizeof(unsigned short);
|
||||
|
||||
m_vertices = (Vertex*)m_storage.m_vertices->lock();
|
||||
m_indices = (unsigned short *)m_storage.m_indices->lock();
|
||||
m_vertices = (Vertex*)m_storage.m_vertices->data();
|
||||
m_indices = (unsigned short *)m_storage.m_indices->data();
|
||||
m_hasStorage = true;
|
||||
}
|
||||
}
|
||||
|
@ -315,6 +315,26 @@ namespace yg
|
|||
}
|
||||
}
|
||||
|
||||
void GeometryBatcher::UnlockStorage::perform()
|
||||
{
|
||||
if (isDebugging())
|
||||
LOG(LINFO, ("performing UnlockPipeline command"));
|
||||
m_storage.m_vertices->unlock();
|
||||
m_storage.m_indices->unlock();
|
||||
}
|
||||
|
||||
void GeometryBatcher::unlockPipeline(int pipelineID)
|
||||
{
|
||||
GeometryPipeline & pipeline = m_pipelines[pipelineID];
|
||||
|
||||
Storage storage = pipeline.m_storage;
|
||||
|
||||
shared_ptr<UnlockStorage> command(new UnlockStorage());
|
||||
command->m_storage = storage;
|
||||
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void GeometryBatcher::flushPipeline(shared_ptr<SkinPage> const & skinPage,
|
||||
int pipelineID)
|
||||
{
|
||||
|
@ -323,8 +343,7 @@ namespace yg
|
|||
{
|
||||
uploadData(skinPage);
|
||||
|
||||
pipeline.m_storage.m_vertices->unlock();
|
||||
pipeline.m_storage.m_indices->unlock();
|
||||
unlockPipeline(pipelineID);
|
||||
|
||||
// base_t::applyStates(m_isAntiAliased);
|
||||
|
||||
|
|
|
@ -100,6 +100,13 @@ namespace yg
|
|||
void perform();
|
||||
};
|
||||
|
||||
struct UnlockStorage : public Command
|
||||
{
|
||||
Storage m_storage;
|
||||
|
||||
void perform();
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// INTERNAL API! USE WITH CAUTION
|
||||
|
@ -127,6 +134,7 @@ namespace yg
|
|||
void uploadData(shared_ptr<SkinPage> const & skinPage);
|
||||
|
||||
void flushPipeline(shared_ptr<SkinPage> const & skinPage, int pipelineID);
|
||||
void unlockPipeline(int pipelineID);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -21,14 +21,14 @@ namespace yg
|
|||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA), m_isLocked(false)
|
||||
{
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(size_t size, bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA), m_isLocked(false)
|
||||
{
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
|
@ -37,6 +37,7 @@ namespace yg
|
|||
|
||||
void IndexBuffer::resize(size_t size)
|
||||
{
|
||||
ASSERT(!m_isLocked, ());
|
||||
if (size != m_size)
|
||||
{
|
||||
m_size = size;
|
||||
|
@ -62,8 +63,22 @@ namespace yg
|
|||
OGLCHECK(glDeleteBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
bool IndexBuffer::isLocked() const
|
||||
{
|
||||
return m_isLocked;
|
||||
}
|
||||
|
||||
void * IndexBuffer::data()
|
||||
{
|
||||
ASSERT(m_isLocked, ("IndexBuffer is not locked"));
|
||||
return m_gpuData;
|
||||
}
|
||||
|
||||
void * IndexBuffer::lock()
|
||||
{
|
||||
ASSERT(!m_isLocked, ());
|
||||
m_isLocked = true;
|
||||
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
|
||||
|
@ -84,6 +99,9 @@ namespace yg
|
|||
|
||||
void IndexBuffer::unlock()
|
||||
{
|
||||
ASSERT(m_isLocked, ());
|
||||
m_isLocked = false;
|
||||
|
||||
if (m_useVA)
|
||||
return;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace yg
|
|||
unsigned int m_size;
|
||||
void * m_gpuData;
|
||||
bool m_useVA;
|
||||
bool m_isLocked;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -27,6 +28,8 @@ namespace yg
|
|||
void unlock();
|
||||
|
||||
void * glPtr();
|
||||
void * data();
|
||||
bool isLocked() const;
|
||||
|
||||
static int current();
|
||||
};
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "skin_loader.hpp"
|
||||
#include "storage.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "vertexbuffer.hpp"
|
||||
#include "indexbuffer.hpp"
|
||||
|
||||
#include "../coding/file_reader.hpp"
|
||||
#include "../coding/parse_xml.hpp"
|
||||
|
@ -36,7 +38,25 @@ namespace yg
|
|||
|
||||
gl::Storage const TStorageFactory::Create()
|
||||
{
|
||||
return gl::Storage(m_vbSize, m_ibSize, m_useVA);
|
||||
gl::Storage res(m_vbSize, m_ibSize, m_useVA);
|
||||
|
||||
res.m_indices->lock();
|
||||
res.m_vertices->lock();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void TStorageFactory::BeforeMerge(gl::Storage const & e)
|
||||
{
|
||||
if (e.m_indices->isLocked())
|
||||
e.m_indices->unlock();
|
||||
|
||||
e.m_indices->lock();
|
||||
|
||||
if (e.m_vertices->isLocked())
|
||||
e.m_vertices->unlock();
|
||||
|
||||
e.m_vertices->lock();
|
||||
}
|
||||
|
||||
ResourceManager::ResourceManager(size_t vbSize, size_t ibSize, size_t storagesCount,
|
||||
|
@ -65,12 +85,12 @@ namespace yg
|
|||
if (useVA)
|
||||
LOG(LINFO, ("buffer objects are unsupported. using client vertex array instead."));
|
||||
|
||||
m_storages.reset(new TStoragePool(TStoragePoolTraits(TStorageFactory(vbSize, ibSize, useVA, "primaryStorage"), storagesCount)));
|
||||
m_smallStorages.reset(new TStoragePool(TStoragePoolTraits(TStorageFactory(smallVBSize, smallIBSize, useVA, "smallStorage"), smallStoragesCount)));
|
||||
m_blitStorages.reset(new TStoragePool(TStoragePoolTraits(TStorageFactory(blitVBSize, blitIBSize, useVA, "blitStorage"), blitStoragesCount)));
|
||||
m_storages.reset(new TStoragePool(new TStoragePoolTraits(TStorageFactory(vbSize, ibSize, useVA, "primaryStorage"), storagesCount)));
|
||||
m_smallStorages.reset(new TStoragePool(new TStoragePoolTraits(TStorageFactory(smallVBSize, smallIBSize, useVA, "smallStorage"), smallStoragesCount)));
|
||||
m_blitStorages.reset(new TStoragePool(new TStoragePoolTraits(TStorageFactory(blitVBSize, blitIBSize, useVA, "blitStorage"), blitStoragesCount)));
|
||||
|
||||
m_dynamicTextures.reset(new TTexturePool(TTexturePoolTraits(TTextureFactory(dynamicTexWidth, dynamicTexHeight, "dynamicTexture"), dynamicTexCount)));
|
||||
m_fontTextures.reset(new TTexturePool(TTexturePoolTraits(TTextureFactory(fontTexWidth, fontTexHeight, "fontTexture"), fontTexCount)));
|
||||
m_dynamicTextures.reset(new TTexturePool(new TTexturePoolTraits(TTextureFactory(dynamicTexWidth, dynamicTexHeight, "dynamicTexture"), dynamicTexCount)));
|
||||
m_fontTextures.reset(new TTexturePool(new TTexturePoolTraits(TTextureFactory(fontTexWidth, fontTexHeight, "fontTexture"), fontTexCount)));
|
||||
}
|
||||
|
||||
void ResourceManager::initMultiBlitStorage(size_t multiBlitVBSize, size_t multiBlitIBSize, size_t multiBlitStoragesCount)
|
||||
|
@ -78,7 +98,7 @@ namespace yg
|
|||
m_multiBlitVBSize = multiBlitVBSize;
|
||||
m_multiBlitIBSize = multiBlitIBSize;
|
||||
|
||||
m_multiBlitStorages.reset(new TStoragePool(TStoragePoolTraits(TStorageFactory(multiBlitVBSize, multiBlitIBSize, m_useVA, "multiBlitStorage"), multiBlitStoragesCount)));
|
||||
m_multiBlitStorages.reset(new TStoragePool(new TStoragePoolTraits(TStorageFactory(multiBlitVBSize, multiBlitIBSize, m_useVA, "multiBlitStorage"), multiBlitStoragesCount)));
|
||||
}
|
||||
|
||||
void ResourceManager::initTinyStorage(size_t tinyVBSize, size_t tinyIBSize, size_t tinyStoragesCount)
|
||||
|
@ -86,7 +106,7 @@ namespace yg
|
|||
m_tinyVBSize = tinyVBSize;
|
||||
m_tinyIBSize = tinyIBSize;
|
||||
|
||||
m_tinyStorages.reset(new TStoragePool(TStoragePoolTraits(TStorageFactory(tinyVBSize, tinyIBSize, m_useVA, "tinyStorage"), tinyStoragesCount)));
|
||||
m_tinyStorages.reset(new TStoragePool(new TStoragePoolTraits(TStorageFactory(tinyVBSize, tinyIBSize, m_useVA, "tinyStorage"), tinyStoragesCount)));
|
||||
}
|
||||
|
||||
void ResourceManager::initRenderTargets(size_t renderTargetWidth, size_t renderTargetHeight, size_t renderTargetsCount)
|
||||
|
@ -94,7 +114,7 @@ namespace yg
|
|||
m_renderTargetWidth = renderTargetWidth;
|
||||
m_renderTargetHeight = renderTargetHeight;
|
||||
|
||||
m_renderTargets.reset(new TTexturePool(TTexturePoolTraits(TTextureFactory(renderTargetWidth, renderTargetHeight, "renderTargets"), renderTargetsCount)));
|
||||
m_renderTargets.reset(new TTexturePool(new TTexturePoolTraits(TTextureFactory(renderTargetWidth, renderTargetHeight, "renderTargets"), renderTargetsCount)));
|
||||
}
|
||||
|
||||
void ResourceManager::initStyleCacheTextures(size_t styleCacheTextureWidth, size_t styleCacheTextureHeight, size_t styleCacheTexturesCount)
|
||||
|
@ -102,7 +122,7 @@ namespace yg
|
|||
m_styleCacheTextureWidth = styleCacheTextureWidth;
|
||||
m_styleCacheTextureHeight = styleCacheTextureHeight;
|
||||
|
||||
m_styleCacheTextures.reset(new TTexturePool(TTexturePoolTraits(TTextureFactory(styleCacheTextureWidth, styleCacheTextureHeight, "styleCacheTextures"), styleCacheTexturesCount)));
|
||||
m_styleCacheTextures.reset(new TTexturePool(new TTexturePoolTraits(TTextureFactory(styleCacheTextureWidth, styleCacheTextureHeight, "styleCacheTextures"), styleCacheTexturesCount)));
|
||||
}
|
||||
|
||||
shared_ptr<gl::BaseTexture> const & ResourceManager::getTexture(string const & fileName)
|
||||
|
@ -323,4 +343,18 @@ namespace yg
|
|||
{
|
||||
return m_styleCacheTextures.get();
|
||||
}
|
||||
|
||||
void ResourceManager::mergeFreeResources()
|
||||
{
|
||||
if (m_tinyStorages.get())
|
||||
m_tinyStorages->Merge();
|
||||
if (m_storages.get())
|
||||
m_storages->Merge();
|
||||
if (m_smallStorages.get())
|
||||
m_smallStorages->Merge();
|
||||
if (m_blitStorages.get())
|
||||
m_blitStorages->Merge();
|
||||
if (m_multiBlitStorages.get())
|
||||
m_multiBlitStorages->Merge();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,17 +45,21 @@ namespace yg
|
|||
bool m_useVA;
|
||||
TStorageFactory(size_t vbSize, size_t ibSize, bool useVA, char const * resName);
|
||||
gl::Storage const Create();
|
||||
void BeforeMerge(gl::Storage const & e);
|
||||
};
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
|
||||
typedef FixedSizePoolTraits<shared_ptr<gl::BaseTexture>, TTextureFactory> TTexturePoolTraits;
|
||||
typedef ResourcePool<shared_ptr<gl::BaseTexture>, TTexturePoolTraits> TTexturePool;
|
||||
typedef BasePoolTraits<shared_ptr<gl::BaseTexture>, TTextureFactory> TBaseTexturePoolTraits;
|
||||
typedef FixedSizePoolTraits<TTextureFactory, TBaseTexturePoolTraits > TTexturePoolTraits;
|
||||
typedef ResourcePool<TTexturePoolTraits> TTexturePool;
|
||||
|
||||
typedef FixedSizePoolTraits<gl::Storage, TStorageFactory> TStoragePoolTraits;
|
||||
typedef ResourcePool<gl::Storage, TStoragePoolTraits> TStoragePool;
|
||||
typedef BasePoolTraits<gl::Storage, TStorageFactory> TBaseStoragePoolTraits;
|
||||
typedef SeparateFreePoolTraits<TStorageFactory, TBaseStoragePoolTraits> TSeparateFreeStoragePoolTraits;
|
||||
typedef FixedSizePoolTraits<TStorageFactory, TSeparateFreeStoragePoolTraits> TStoragePoolTraits;
|
||||
typedef ResourcePool<TStoragePoolTraits> TStoragePool;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -166,6 +170,8 @@ namespace yg
|
|||
void enterBackground();
|
||||
void enterForeground();
|
||||
|
||||
void mergeFreeResources();
|
||||
|
||||
shared_ptr<yg::gl::BaseTexture> createRenderTarget(unsigned w, unsigned h);
|
||||
};
|
||||
|
||||
|
|
|
@ -21,14 +21,14 @@ namespace yg
|
|||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA), m_isLocked(false)
|
||||
{
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(size_t size, bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA), m_isLocked(false)
|
||||
{
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
|
@ -37,6 +37,7 @@ namespace yg
|
|||
|
||||
void VertexBuffer::resize(size_t size)
|
||||
{
|
||||
ASSERT(!m_isLocked, ());
|
||||
if (size != m_size)
|
||||
{
|
||||
m_size = size;
|
||||
|
@ -64,8 +65,17 @@ namespace yg
|
|||
OGLCHECK(glDeleteBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
void * VertexBuffer::data()
|
||||
{
|
||||
ASSERT(m_isLocked, ("IndexBuffer is not locked"));
|
||||
return m_gpuData;
|
||||
}
|
||||
|
||||
void * VertexBuffer::lock()
|
||||
{
|
||||
ASSERT(!m_isLocked, ());
|
||||
m_isLocked = true;
|
||||
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
|
||||
|
@ -86,6 +96,9 @@ namespace yg
|
|||
|
||||
void VertexBuffer::unlock()
|
||||
{
|
||||
ASSERT(m_isLocked, ());
|
||||
m_isLocked = false;
|
||||
|
||||
if (m_useVA)
|
||||
return;
|
||||
|
||||
|
@ -99,13 +112,18 @@ namespace yg
|
|||
m_gpuData = 0;
|
||||
}
|
||||
|
||||
void * VertexBuffer::glPtr() const
|
||||
void * VertexBuffer::glPtr()
|
||||
{
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool VertexBuffer::isLocked() const
|
||||
{
|
||||
return m_isLocked;
|
||||
}
|
||||
|
||||
void VertexBuffer::makeCurrent()
|
||||
{
|
||||
if (m_useVA)
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace yg
|
|||
|
||||
/// using VA instead of buffer objects on some old GPU's
|
||||
bool m_useVA;
|
||||
bool m_isLocked;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -27,7 +28,9 @@ namespace yg
|
|||
void makeCurrent();
|
||||
void * lock();
|
||||
void unlock();
|
||||
void * glPtr() const;
|
||||
void * glPtr();
|
||||
void * data();
|
||||
bool isLocked() const;
|
||||
|
||||
static unsigned current();
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue