From eedc7f55c9490c7ce3c74566da5a605f0adfbffe Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 14 Mar 2017 11:35:26 +0800 Subject: [PATCH] Make addThreadedLoadTexture thread safe --- lib/irrlicht/include/ITexture.h | 2 ++ src/graphics/stk_tex_manager.cpp | 5 +++-- src/graphics/stk_tex_manager.hpp | 13 ++++++++++++- src/graphics/stk_texture.hpp | 5 +++++ src/graphics/threaded_tex_loader.cpp | 3 +++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/irrlicht/include/ITexture.h b/lib/irrlicht/include/ITexture.h index eb7940fde..950544ce5 100644 --- a/lib/irrlicht/include/ITexture.h +++ b/lib/irrlicht/include/ITexture.h @@ -206,6 +206,8 @@ public: virtual void threadedSubImage(void* ptr) const {} virtual void cleanThreadedLoader() {} + + virtual int getThreadedLoadTextureCounter() const { return 0; } protected: //! Helper function, helps to get the desired texture creation format from the flags. diff --git a/src/graphics/stk_tex_manager.cpp b/src/graphics/stk_tex_manager.cpp index 02c4fef52..bab9e7861 100644 --- a/src/graphics/stk_tex_manager.cpp +++ b/src/graphics/stk_tex_manager.cpp @@ -29,7 +29,8 @@ #include // ---------------------------------------------------------------------------- -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 (CVS->supportsThreadedTextureLoading()) @@ -362,7 +363,7 @@ void STKTexManager::checkThreadedLoadTextures(bool util_queue_empty) while (true) { 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); if (empty_queue) { diff --git a/src/graphics/stk_tex_manager.hpp b/src/graphics/stk_tex_manager.hpp index 578f9e5f5..55a221138 100644 --- a/src/graphics/stk_tex_manager.hpp +++ b/src/graphics/stk_tex_manager.hpp @@ -23,8 +23,10 @@ #include "utils/singleton.hpp" #include "irrString.h" +#include "ITexture.h" #include +#include #include #include #include @@ -34,7 +36,7 @@ class STKTexture; class ThreadedTexLoader; namespace irr { - namespace video { class ITexture; class SColor; } + namespace video { class SColor; } } class STKTexManager : public Singleton, NoCopy @@ -62,6 +64,8 @@ private: std::vector, SmallestTexture> m_threaded_load_textures; + int m_threaded_load_textures_counter; + pthread_mutex_t m_threaded_load_textures_mutex; pthread_cond_t m_cond_request; @@ -156,10 +160,17 @@ public: irr::video::ITexture* getThreadedLoadTexture() { 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) { pthread_mutex_lock(&m_threaded_load_textures_mutex); m_threaded_load_textures.push(t); + setThreadedLoadTextureCounter(t->getThreadedLoadTextureCounter()); pthread_cond_signal(&m_cond_request); pthread_mutex_unlock(&m_threaded_load_textures_mutex); } diff --git a/src/graphics/stk_texture.hpp b/src/graphics/stk_texture.hpp index 652a41e8b..5e389bcf3 100644 --- a/src/graphics/stk_texture.hpp +++ b/src/graphics/stk_texture.hpp @@ -153,6 +153,11 @@ public: virtual void threadedSubImage(void* ptr) const; // ------------------------------------------------------------------------ virtual void cleanThreadedLoader(); + // ------------------------------------------------------------------------ + virtual int getThreadedLoadTextureCounter() const + { + return useHQMipmap() ? 2 : 1; + } }; // STKTexture diff --git a/src/graphics/threaded_tex_loader.cpp b/src/graphics/threaded_tex_loader.cpp index ffefeb9af..e48efe867 100644 --- a/src/graphics/threaded_tex_loader.cpp +++ b/src/graphics/threaded_tex_loader.cpp @@ -72,6 +72,9 @@ void* ThreadedTexLoader::startRoutine(void *obj) target_tex->cleanThreadedLoader(); ttl->m_tex_size_loaded += target_tex->getTextureSize(); 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; } // startRoutine