refactored ResourceManager to use ObjectPool for multi-threaded accessible resources.

This commit is contained in:
rachytski 2011-06-25 16:59:10 +03:00 committed by Alex Zolotarev
parent 5b8c7eb503
commit 495060a1cd
8 changed files with 116 additions and 185 deletions

View file

@ -44,7 +44,8 @@ UNIT_TEST(ObjectPool)
list<int> l;
list<int> res;
ObjectPool<int> p(l);
ObjectPool<int> p;
p.Add(l);
threads::Thread t0;
t0.Create(new ProcessorThread(&p, &res, 0));

View file

@ -18,9 +18,32 @@ private:
public:
ObjectPool(list<T> const & l) : m_List(l), m_IsCancelled(false)
ObjectPool() : m_IsCancelled(false)
{}
void Add(list<T> const & l)
{
for (typename list<T>::const_iterator it = l.begin(); it != l.end(); ++it)
Free(*it);
}
size_t Size()
{
threads::ConditionGuard Guard(m_Cond);
return m_List.size();
}
void Add(T const & t)
{
Free(t);
}
void Clear()
{
threads::ConditionGuard Guard(m_Cond);
m_List.clear();
}
T const Reserve()
{
threads::ConditionGuard Guard(m_Cond);

View file

@ -425,7 +425,7 @@ void FrameWork<TModel>::AddRedrawCommandSure()
template <typename TModel>
void FrameWork<TModel>::SaveBenchmarkResults()
{
ofstream fout(GetPlatform().WritablePathForFile("benchmarks\\results.txt").c_str(), ios::app);
ofstream fout(GetPlatform().WritablePathForFile("benchmarks/results.txt").c_str(), ios::app);
for (size_t i = 0; i < m_benchmarkResults.size(); ++i)
{
@ -446,7 +446,7 @@ void FrameWork<TModel>::AddRedrawCommandSure()
template <typename TModel>
void FrameWork<TModel>::SendBenchmarkResults()
{
// ofstream fout(GetPlatform().WritablePathForFile("benchmarks\\results.txt").c_str(), ios::app);
// ofstream fout(GetPlatform().WritablePathForFile("benchmarks/results.txt").c_str(), ios::app);
// fout << "[COMPLETED]";
// fout.close();
/// send to server for adding to statistics graphics
@ -456,14 +456,14 @@ void FrameWork<TModel>::AddRedrawCommandSure()
template <typename TModel>
void FrameWork<TModel>::MarkBenchmarkResultsEnd()
{
ofstream fout(GetPlatform().WritablePathForFile("benchmarks\\results.txt").c_str(), ios::app);
ofstream fout(GetPlatform().WritablePathForFile("benchmarks/results.txt").c_str(), ios::app);
fout << "END " << m_startTime << endl;
}
template <typename TModel>
void FrameWork<TModel>::MarkBenchmarkResultsStart()
{
ofstream fout(GetPlatform().WritablePathForFile("benchmarks\\results.txt").c_str(), ios::app);
ofstream fout(GetPlatform().WritablePathForFile("benchmarks/results.txt").c_str(), ios::app);
fout << "START " << m_startTime << endl;
}
@ -532,7 +532,7 @@ void FrameWork<TModel>::AddRedrawCommandSure()
void FrameWork<TModel>::EnumBenchmarkMaps(Platform::FilesList & filesList)
{
set<string> files;
ifstream fin(GetPlatform().WritablePathForFile("benchmarks\\config.info").c_str());
ifstream fin(GetPlatform().WritablePathForFile("benchmarks/config.info").c_str());
filesList.clear();
char buf[256];
@ -564,7 +564,7 @@ void FrameWork<TModel>::AddRedrawCommandSure()
//m2::RectD r(wr.Center().x, wr.Center().y + wr.SizeY() / 8, wr.Center().x + wr.SizeX() / 8, wr.Center().y + wr.SizeY() / 4);
set<string> files;
ifstream fin(GetPlatform().WritablePathForFile("benchmarks\\config.info").c_str());
ifstream fin(GetPlatform().WritablePathForFile("benchmarks/config.info").c_str());
while (true)
{
string name;

View file

@ -168,7 +168,7 @@ namespace yg
yg::Color const & color,
bool hasColor)
{
m_blitStorage = resourceManager()->reserveBlitStorage();
m_blitStorage = resourceManager()->blitStorages().Reserve();
AuxVertex * pointsData = (AuxVertex*)m_blitStorage.m_vertices->lock();
@ -203,7 +203,7 @@ namespace yg
/// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone.
OGLCHECK(glFinish());
resourceManager()->freeBlitStorage(m_blitStorage);
resourceManager()->blitStorages().Free(m_blitStorage);
m_blitStorage = yg::gl::Storage();
}
}

View file

@ -76,7 +76,7 @@ namespace yg
{
if (!m_hasStorage)
{
m_storage = usage != SkinPage::EStaticUsage ? resourceManager->reserveStorage() : resourceManager->reserveSmallStorage();
m_storage = usage != SkinPage::EStaticUsage ? resourceManager->storages().Reserve() : resourceManager->smallStorages().Reserve();
m_maxVertices = m_storage.m_vertices->size() / sizeof(Vertex);
m_maxIndices = m_storage.m_indices->size() / sizeof(unsigned short);
@ -220,9 +220,9 @@ namespace yg
renderedData = true;
if (skinPage->usage() != SkinPage::EStaticUsage)
resourceManager()->freeStorage(pipeline.m_storage);
resourceManager()->storages().Free(pipeline.m_storage);
else
resourceManager()->freeSmallStorage(pipeline.m_storage);
resourceManager()->smallStorages().Free(pipeline.m_storage);
pipeline.m_hasStorage = false;
pipeline.m_storage = Storage();

View file

@ -50,25 +50,26 @@ namespace yg
}
for (size_t i = 0; i < storagesCount; ++i)
m_storages.push_back(gl::Storage(vbSize, ibSize, m_useVA));
m_storages.Add(gl::Storage(vbSize, ibSize, m_useVA));
LOG(LINFO, ("allocating ", (vbSize + ibSize) * storagesCount, " bytes for main storage"));
for (size_t i = 0; i < smallStoragesCount; ++i)
m_smallStorages.push_back(gl::Storage(smallVBSize, smallIBSize, m_useVA));
m_smallStorages.Add(gl::Storage(smallVBSize, smallIBSize, m_useVA));
LOG(LINFO, ("allocating ", (smallVBSize + smallIBSize) * smallStoragesCount, " bytes for small storage"));
for (size_t i = 0; i < blitStoragesCount; ++i)
m_blitStorages.push_back(gl::Storage(blitVBSize, blitIBSize, m_useVA));
m_blitStorages.Add(gl::Storage(blitVBSize, blitIBSize, m_useVA));
LOG(LINFO, ("allocating ", (blitVBSize + blitIBSize) * blitStoragesCount, " bytes for blit storage"));
for (size_t i = 0; i < dynamicTexCount; ++i)
{
m_dynamicTextures.push_back(shared_ptr<gl::BaseTexture>(new TDynamicTexture(dynamicTexWidth, dynamicTexHeight)));
shared_ptr<gl::BaseTexture> t(new TDynamicTexture(dynamicTexWidth, dynamicTexHeight));
m_dynamicTextures.Add(t);
#ifdef DEBUG
static_cast<TDynamicTexture*>(m_dynamicTextures.back().get())->randomize();
static_cast<TDynamicTexture*>(t.get())->randomize();
#endif
}
@ -76,9 +77,10 @@ namespace yg
for (size_t i = 0; i < fontTexCount; ++i)
{
m_fontTextures.push_back(shared_ptr<gl::BaseTexture>(new TDynamicTexture(fontTexWidth, fontTexHeight)));
shared_ptr<gl::BaseTexture> t(new TDynamicTexture(fontTexWidth, fontTexHeight));
m_fontTextures.Add(t);
#ifdef DEBUG
static_cast<TDynamicTexture*>(m_fontTextures.back().get())->randomize();
static_cast<TDynamicTexture*>(t.get())->randomize();
#endif
}
@ -113,110 +115,6 @@ namespace yg
return loader.skin();
}
gl::Storage const ResourceManager::reserveStorageImpl(bool doWait, list<gl::Storage> & l)
{
threads::MutexGuard guard(m_mutex);
if (l.empty())
{
if (doWait)
{
/// somehow wait
}
}
gl::Storage res = l.front();
l.pop_front();
return res;
}
void ResourceManager::freeStorageImpl(gl::Storage const & storage, bool doSignal, list<gl::Storage> & l)
{
threads::MutexGuard guard(m_mutex);
bool needToSignal = l.empty();
l.push_back(storage);
if ((needToSignal) && (doSignal))
{
/// somehow signal
}
}
gl::Storage const ResourceManager::reserveSmallStorage(bool doWait)
{
return reserveStorageImpl(doWait, m_smallStorages);
}
void ResourceManager::freeSmallStorage(gl::Storage const & storage, bool doSignal)
{
return freeStorageImpl(storage, doSignal, m_smallStorages);
}
gl::Storage const ResourceManager::reserveBlitStorage(bool doWait)
{
return reserveStorageImpl(doWait, m_blitStorages);
}
void ResourceManager::freeBlitStorage(gl::Storage const & storage, bool doSignal)
{
return freeStorageImpl(storage, doSignal, m_blitStorages);
}
gl::Storage const ResourceManager::reserveStorage(bool doWait)
{
return reserveStorageImpl(doWait, m_storages);
}
void ResourceManager::freeStorage(gl::Storage const & storage, bool doSignal)
{
return freeStorageImpl(storage, doSignal, m_storages);
}
shared_ptr<gl::BaseTexture> const ResourceManager::reserveTextureImpl(bool doWait, list<shared_ptr<gl::BaseTexture> > & l)
{
threads::MutexGuard guard(m_mutex);
if (l.empty())
{
if (doWait)
{
/// somehow wait
}
}
shared_ptr<gl::BaseTexture> res = l.front();
l.pop_front();
return res;
}
void ResourceManager::freeTextureImpl(shared_ptr<gl::BaseTexture> const & texture, bool doSignal, list<shared_ptr<gl::BaseTexture> > & l)
{
threads::MutexGuard guard(m_mutex);
bool needToSignal = l.empty();
l.push_back(texture);
if ((needToSignal) && (doSignal))
{
/// somehow signal
}
}
shared_ptr<gl::BaseTexture> const ResourceManager::reserveDynamicTexture(bool doWait)
{
return reserveTextureImpl(doWait, m_dynamicTextures);
}
void ResourceManager::freeDynamicTexture(shared_ptr<gl::BaseTexture> const & texture, bool doSignal)
{
freeTextureImpl(texture, doSignal, m_dynamicTextures);
}
size_t ResourceManager::dynamicTextureWidth() const
{
return m_dynamicTextureWidth;
@ -227,16 +125,6 @@ namespace yg
return m_dynamicTextureHeight;
}
shared_ptr<gl::BaseTexture> const ResourceManager::reserveFontTexture(bool doWait)
{
return reserveTextureImpl(doWait, m_fontTextures);
}
void ResourceManager::freeFontTexture(shared_ptr<gl::BaseTexture> const & texture, bool doSignal)
{
freeTextureImpl(texture, doSignal, m_fontTextures);
}
size_t ResourceManager::fontTextureWidth() const
{
return m_fontTextureWidth;
@ -267,37 +155,36 @@ namespace yg
{
threads::MutexGuard guard(m_mutex);
for (list<gl::Storage>::iterator it = m_storages.begin(); it != m_storages.end(); ++it)
*it = gl::Storage();
for (list<gl::Storage>::iterator it = m_smallStorages.begin(); it != m_smallStorages.end(); ++it)
*it = gl::Storage();
for (list<gl::Storage>::iterator it = m_blitStorages.begin(); it != m_blitStorages.end(); ++it)
*it = gl::Storage();
m_storagesCount = m_storages.Size();
m_smallStoragesCount = m_smallStorages.Size();
m_blitStoragesCount = m_blitStorages.Size();
m_dynamicTexturesCount = m_dynamicTextures.Size();
m_fontTexturesCount = m_fontTextures.Size();
for (list<shared_ptr<gl::BaseTexture> >::iterator it = m_dynamicTextures.begin(); it != m_dynamicTextures.end(); ++it)
it->reset();
m_storages.Clear();
m_smallStorages.Clear();
m_blitStorages.Clear();
m_dynamicTextures.Clear();
m_fontTextures.Clear();
for (list<shared_ptr<gl::BaseTexture> >::iterator it = m_fontTextures.begin(); it != m_fontTextures.end(); ++it)
it->reset();
LOG(LINFO, ("freed ", m_storages.size(), " storages, ", m_smallStorages.size(), " small storages, ", m_blitStorages.size(), " blit storages, ", m_dynamicTextures.size(), " dynamic textures and ", m_fontTextures.size(), " font textures"));
LOG(LINFO, ("freed ", m_storagesCount, " storages, ", m_smallStoragesCount, " small storages, ", m_blitStoragesCount, " blit storages, ", m_dynamicTexturesCount, " dynamic textures and ", m_fontTexturesCount, " font textures"));
}
void ResourceManager::enterForeground()
{
threads::MutexGuard guard(m_mutex);
for (list<gl::Storage>::iterator it = m_storages.begin(); it != m_storages.end(); ++it)
*it = gl::Storage(m_vbSize, m_ibSize, m_useVA);
for (list<gl::Storage>::iterator it = m_smallStorages.begin(); it != m_smallStorages.end(); ++it)
*it = gl::Storage(m_smallVBSize, m_smallIBSize, m_useVA);
for (list<gl::Storage>::iterator it = m_blitStorages.begin(); it != m_blitStorages.end(); ++it)
*it = gl::Storage(m_blitVBSize, m_blitIBSize, m_useVA);
for (size_t i = 0; i < m_storagesCount; ++i)
m_storages.Add(gl::Storage(m_vbSize, m_ibSize, m_useVA));
for (size_t i = 0; i < m_smallStoragesCount; ++i)
m_smallStorages.Add(gl::Storage(m_smallVBSize, m_smallIBSize, m_useVA));
for (size_t i = 0; i < m_blitStoragesCount; ++i)
m_blitStorages.Add(gl::Storage(m_blitVBSize, m_blitIBSize, m_useVA));
for (list<shared_ptr<gl::BaseTexture> >::iterator it = m_dynamicTextures.begin(); it != m_dynamicTextures.end(); ++it)
*it = shared_ptr<gl::BaseTexture>(new TDynamicTexture(m_dynamicTextureWidth, m_dynamicTextureHeight));
for (list<shared_ptr<gl::BaseTexture> >::iterator it = m_fontTextures.begin(); it != m_fontTextures.end(); ++it)
*it = shared_ptr<gl::BaseTexture>(new TDynamicTexture(m_fontTextureWidth, m_fontTextureHeight));
for (size_t i = 0; i < m_dynamicTexturesCount; ++i)
m_dynamicTextures.Add(shared_ptr<gl::BaseTexture>(new TDynamicTexture(m_dynamicTextureWidth, m_dynamicTextureHeight)));
for (size_t i = 0; i < m_fontTexturesCount; ++i)
m_fontTextures.Add(shared_ptr<gl::BaseTexture>(new TDynamicTexture(m_fontTextureWidth, m_fontTextureHeight)));
}
shared_ptr<yg::gl::BaseTexture> ResourceManager::createRenderTarget(unsigned w, unsigned h)
@ -327,4 +214,30 @@ namespace yg
{
return 1;
}
ObjectPool<gl::Storage> & ResourceManager::storages()
{
return m_storages;
}
ObjectPool<gl::Storage> & ResourceManager::smallStorages()
{
return m_smallStorages;
}
ObjectPool<gl::Storage> & ResourceManager::blitStorages()
{
return m_blitStorages;
}
ObjectPool<shared_ptr<gl::BaseTexture> > & ResourceManager::dynamicTextures()
{
return m_dynamicTextures;
}
ObjectPool<shared_ptr<gl::BaseTexture> > & ResourceManager::fontTextures()
{
return m_fontTextures;
}
}

View file

@ -6,6 +6,7 @@
#include "../std/list.hpp"
#include "../base/mutex.hpp"
#include "../base/object_pool.hpp"
#include "storage.hpp"
#include "glyph_cache.hpp"
@ -41,12 +42,12 @@ namespace yg
size_t m_dynamicTextureWidth;
size_t m_dynamicTextureHeight;
list<shared_ptr<gl::BaseTexture> > m_dynamicTextures;
ObjectPool<shared_ptr<gl::BaseTexture> > m_dynamicTextures;
size_t m_fontTextureWidth;
size_t m_fontTextureHeight;
list<shared_ptr<gl::BaseTexture> > m_fontTextures;
ObjectPool<shared_ptr<gl::BaseTexture> > m_fontTextures;
size_t m_vbSize;
size_t m_ibSize;
@ -57,15 +58,9 @@ namespace yg
size_t m_blitVBSize;
size_t m_blitIBSize;
list<gl::Storage> m_storages;
list<gl::Storage> m_smallStorages;
list<gl::Storage> m_blitStorages;
gl::Storage const reserveStorageImpl(bool doWait, list<gl::Storage> & l);
void freeStorageImpl(gl::Storage const & storage, bool doSignal, list<gl::Storage> & l);
shared_ptr<gl::BaseTexture> const reserveTextureImpl(bool doWait, list<shared_ptr<gl::BaseTexture> > & l);
void freeTextureImpl(shared_ptr<gl::BaseTexture> const & texture, bool doSignal, list<shared_ptr<gl::BaseTexture> > & l);
ObjectPool<gl::Storage> m_storages;
ObjectPool<gl::Storage> m_smallStorages;
ObjectPool<gl::Storage> m_blitStorages;
vector<GlyphCache> m_glyphCaches;
@ -74,6 +69,12 @@ namespace yg
bool m_useVA;
bool m_fillSkinAlpha;
size_t m_storagesCount;
size_t m_smallStoragesCount;
size_t m_blitStoragesCount;
size_t m_dynamicTexturesCount;
size_t m_fontTexturesCount;
public:
ResourceManager(size_t vbSize, size_t ibSize, size_t storagesCount,
@ -90,24 +91,15 @@ namespace yg
shared_ptr<gl::BaseTexture> const & getTexture(string const & fileName);
gl::Storage const reserveStorage(bool doWait = false);
void freeStorage(gl::Storage const & storage, bool doSignal = false);
gl::Storage const reserveSmallStorage(bool doWait = false);
void freeSmallStorage(gl::Storage const & storage, bool doSignal = false);
gl::Storage const reserveBlitStorage(bool doWait = false);
void freeBlitStorage(gl::Storage const & storage, bool doSignal = false);
shared_ptr<gl::BaseTexture> const reserveDynamicTexture(bool doWait = false);
void freeDynamicTexture(shared_ptr<gl::BaseTexture> const & texture, bool doSignal = false);
ObjectPool<gl::Storage> & storages();
ObjectPool<gl::Storage> & smallStorages();
ObjectPool<gl::Storage> & blitStorages();
ObjectPool<shared_ptr<gl::BaseTexture> > & dynamicTextures();
ObjectPool<shared_ptr<gl::BaseTexture> > & fontTextures();
size_t dynamicTextureWidth() const;
size_t dynamicTextureHeight() const;
shared_ptr<gl::BaseTexture> const reserveFontTexture(bool doWait = false);
void freeFontTexture(shared_ptr<gl::BaseTexture> const & texture, bool doSignal = false);
size_t fontTextureWidth() const;
size_t fontTextureHeight() const;

View file

@ -750,10 +750,10 @@ namespace yg
switch (m_usage)
{
case EDynamicUsage:
m_resourceManager->freeDynamicTexture(m_texture);
m_resourceManager->dynamicTextures().Free(m_texture);
break;
case EFontsUsage:
m_resourceManager->freeFontTexture(m_texture);
m_resourceManager->fontTextures().Free(m_texture);
break;
default:
LOG(LINFO, ("freeTexture call for with invalid usage param"));
@ -768,10 +768,10 @@ namespace yg
switch (m_usage)
{
case EDynamicUsage:
m_texture = m_resourceManager->reserveDynamicTexture();
m_texture = m_resourceManager->dynamicTextures().Reserve();
break;
case EFontsUsage:
m_texture = m_resourceManager->reserveFontTexture();
m_texture = m_resourceManager->fontTextures().Reserve();
break;
default:
LOG(LINFO, ("freeTexture call for with invalid usage param"));
@ -792,6 +792,8 @@ namespace yg
m_resourceManager->fontTextureHeight(),
0x00FFFFFF - 1);
break;
default:
LOG(LINFO, ("createPacker call for invalid usage param"));
}
}
}