Make addThreadedLoadTexture thread safe

This commit is contained in:
Benau 2017-03-14 11:35:26 +08:00
parent abfb402acb
commit eedc7f55c9
5 changed files with 25 additions and 3 deletions

View File

@ -206,6 +206,8 @@ public:
virtual void threadedSubImage(void* ptr) const {} virtual void threadedSubImage(void* ptr) const {}
virtual void cleanThreadedLoader() {} virtual void cleanThreadedLoader() {}
virtual int getThreadedLoadTextureCounter() const { return 0; }
protected: protected:
//! Helper function, helps to get the desired texture creation format from the flags. //! Helper function, helps to get the desired texture creation format from the flags.

View File

@ -29,7 +29,8 @@
#include <algorithm> #include <algorithm>
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
STKTexManager::STKTexManager() : m_pbo(0), m_thread_size(0) STKTexManager::STKTexManager() : m_pbo(0), m_thread_size(0),
m_threaded_load_textures_counter(0)
{ {
#if !(defined(SERVER_ONLY) || defined(USE_GLES2)) #if !(defined(SERVER_ONLY) || defined(USE_GLES2))
if (CVS->supportsThreadedTextureLoading()) if (CVS->supportsThreadedTextureLoading())
@ -362,7 +363,7 @@ void STKTexManager::checkThreadedLoadTextures(bool util_queue_empty)
while (true) while (true)
{ {
pthread_mutex_lock(&m_threaded_load_textures_mutex); pthread_mutex_lock(&m_threaded_load_textures_mutex);
empty_queue = m_threaded_load_textures.empty(); empty_queue = m_threaded_load_textures_counter == 0;
pthread_mutex_unlock(&m_threaded_load_textures_mutex); pthread_mutex_unlock(&m_threaded_load_textures_mutex);
if (empty_queue) if (empty_queue)
{ {

View File

@ -23,8 +23,10 @@
#include "utils/singleton.hpp" #include "utils/singleton.hpp"
#include "irrString.h" #include "irrString.h"
#include "ITexture.h"
#include <pthread.h> #include <pthread.h>
#include <cassert>
#include <string> #include <string>
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
@ -34,7 +36,7 @@ class STKTexture;
class ThreadedTexLoader; class ThreadedTexLoader;
namespace irr namespace irr
{ {
namespace video { class ITexture; class SColor; } namespace video { class SColor; }
} }
class STKTexManager : public Singleton<STKTexManager>, NoCopy class STKTexManager : public Singleton<STKTexManager>, NoCopy
@ -62,6 +64,8 @@ private:
std::vector<irr::video::ITexture*>, SmallestTexture> std::vector<irr::video::ITexture*>, SmallestTexture>
m_threaded_load_textures; m_threaded_load_textures;
int m_threaded_load_textures_counter;
pthread_mutex_t m_threaded_load_textures_mutex; pthread_mutex_t m_threaded_load_textures_mutex;
pthread_cond_t m_cond_request; pthread_cond_t m_cond_request;
@ -156,10 +160,17 @@ public:
irr::video::ITexture* getThreadedLoadTexture() irr::video::ITexture* getThreadedLoadTexture()
{ return m_threaded_load_textures.top(); } { return m_threaded_load_textures.top(); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setThreadedLoadTextureCounter(int val)
{
m_threaded_load_textures_counter += val;
assert(m_threaded_load_textures_counter >= 0);
}
// ------------------------------------------------------------------------
void addThreadedLoadTexture(irr::video::ITexture* t) void addThreadedLoadTexture(irr::video::ITexture* t)
{ {
pthread_mutex_lock(&m_threaded_load_textures_mutex); pthread_mutex_lock(&m_threaded_load_textures_mutex);
m_threaded_load_textures.push(t); m_threaded_load_textures.push(t);
setThreadedLoadTextureCounter(t->getThreadedLoadTextureCounter());
pthread_cond_signal(&m_cond_request); pthread_cond_signal(&m_cond_request);
pthread_mutex_unlock(&m_threaded_load_textures_mutex); pthread_mutex_unlock(&m_threaded_load_textures_mutex);
} }

View File

@ -153,6 +153,11 @@ public:
virtual void threadedSubImage(void* ptr) const; virtual void threadedSubImage(void* ptr) const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void cleanThreadedLoader(); virtual void cleanThreadedLoader();
// ------------------------------------------------------------------------
virtual int getThreadedLoadTextureCounter() const
{
return useHQMipmap() ? 2 : 1;
}
}; // STKTexture }; // STKTexture

View File

@ -72,6 +72,9 @@ void* ThreadedTexLoader::startRoutine(void *obj)
target_tex->cleanThreadedLoader(); target_tex->cleanThreadedLoader();
ttl->m_tex_size_loaded += target_tex->getTextureSize(); ttl->m_tex_size_loaded += target_tex->getTextureSize();
ttl->m_completed_textures.push_back(target_tex); ttl->m_completed_textures.push_back(target_tex);
pthread_mutex_lock(ttl->m_texture_queue_mutex);
ttl->m_stktm->setThreadedLoadTextureCounter(-1);
pthread_mutex_unlock(ttl->m_texture_queue_mutex);
} }
return NULL; return NULL;
} // startRoutine } // startRoutine