diff --git a/cocos/renderer/CCTextureCache.cpp b/cocos/renderer/CCTextureCache.cpp index 958a5eba45..7afca3874e 100644 --- a/cocos/renderer/CCTextureCache.cpp +++ b/cocos/renderer/CCTextureCache.cpp @@ -115,8 +115,8 @@ void TextureCache::addImageAsync(const std::string &path, const std::function(); - _imageInfoQueue = new deque(); + _asyncStructQueue = new (std::nothrow) deque(); + _imageInfoQueue = new (std::nothrow) deque(); // create a new thread to load images _loadingThread = new std::thread(&TextureCache::loadImage, this); @@ -135,36 +135,62 @@ void TextureCache::addImageAsync(const std::string &path, const std::functionpush(data); - _asyncStructQueueMutex.unlock(); + _asyncMutex.lock(); + _asyncStructQueue->push_back(data); + _asyncMutex.unlock(); _sleepCondition.notify_one(); } void TextureCache::unbindImageAsync(const std::string& filename) { - _imageInfoMutex.lock(); - if (_imageInfoQueue && !_imageInfoQueue->empty()) + std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filename); + + _asyncMutex.lock(); + + if (_asyncStructQueue && !_asyncStructQueue->empty()) { - std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filename); - auto found = std::find_if(_imageInfoQueue->begin(), _imageInfoQueue->end(), [&fullpath](ImageInfo* ptr)->bool{ return ptr->asyncStruct->filename == fullpath; }); - if (found != _imageInfoQueue->end()) + for (auto it = _asyncStructQueue->begin(); it != _asyncStructQueue->end(); ++it) { - (*found)->asyncStruct->callback = nullptr; + if ((*it)->filename == fullpath) + { + (*it)->callback = nullptr; + } } } - _imageInfoMutex.unlock(); + + if (_imageInfoQueue && !_imageInfoQueue->empty()) + { + for (auto it = _imageInfoQueue->begin(); it != _imageInfoQueue->end(); ++it) + { + if ((*it)->asyncStruct->filename == fullpath) + { + (*it)->asyncStruct->callback = nullptr; + } + } + } + + _asyncMutex.unlock(); } void TextureCache::unbindAllImageAsync() { - _imageInfoMutex.lock(); + _asyncMutex.lock(); + if (_asyncStructQueue && !_asyncStructQueue->empty()) + { + for (auto it = _asyncStructQueue->begin(); it != _asyncStructQueue->end(); ++it) + { + (*it)->callback = nullptr; + } + } if (_imageInfoQueue && !_imageInfoQueue->empty()) { - std::for_each(_imageInfoQueue->begin(), _imageInfoQueue->end(), [](ImageInfo* ptr) { ptr->asyncStruct->callback = nullptr; }); + for (auto it = _imageInfoQueue->begin(); it != _imageInfoQueue->end(); ++it) + { + (*it)->asyncStruct->callback = nullptr; + } } - _imageInfoMutex.unlock(); + _asyncMutex.unlock(); } void TextureCache::loadImage() @@ -173,11 +199,10 @@ void TextureCache::loadImage() while (true) { - std::queue *pQueue = _asyncStructQueue; - _asyncStructQueueMutex.lock(); - if (pQueue->empty()) + _asyncMutex.lock(); + if (_asyncStructQueue->empty()) { - _asyncStructQueueMutex.unlock(); + _asyncMutex.unlock(); if (_needQuit) { break; } @@ -189,9 +214,8 @@ void TextureCache::loadImage() } else { - asyncStruct = pQueue->front(); - pQueue->pop(); - _asyncStructQueueMutex.unlock(); + asyncStruct = _asyncStructQueue->front(); + _asyncMutex.unlock(); } Image *image = nullptr; @@ -200,9 +224,9 @@ void TextureCache::loadImage() auto it = _textures.find(asyncStruct->filename); if( it == _textures.end() ) { - _imageInfoMutex.lock(); ImageInfo *imageInfo; size_t pos = 0; + _asyncMutex.lock(); size_t infoSize = _imageInfoQueue->size(); for (; pos < infoSize; pos++) { @@ -210,7 +234,7 @@ void TextureCache::loadImage() if(imageInfo->asyncStruct->filename.compare(asyncStruct->filename) == 0) break; } - _imageInfoMutex.unlock(); + _asyncMutex.unlock(); if(infoSize == 0 || pos == infoSize) generateImage = true; } @@ -224,6 +248,9 @@ void TextureCache::loadImage() { CC_SAFE_RELEASE(image); CCLOG("can not load %s", filename.c_str()); + _asyncMutex.lock(); + _asyncStructQueue->pop_front(); + _asyncMutex.unlock(); continue; } } @@ -234,9 +261,10 @@ void TextureCache::loadImage() imageInfo->image = image; // put the image info into the queue - _imageInfoMutex.lock(); + _asyncMutex.lock(); + _asyncStructQueue->pop_front(); _imageInfoQueue->push_back(imageInfo); - _imageInfoMutex.unlock(); + _asyncMutex.unlock(); } if(_asyncStructQueue != nullptr) @@ -253,16 +281,16 @@ void TextureCache::addImageAsyncCallBack(float dt) // the image is generated in loading thread std::deque *imagesQueue = _imageInfoQueue; - _imageInfoMutex.lock(); + _asyncMutex.lock(); if (imagesQueue->empty()) { - _imageInfoMutex.unlock(); + _asyncMutex.unlock(); } else { ImageInfo *imageInfo = imagesQueue->front(); imagesQueue->pop_front(); - _imageInfoMutex.unlock(); + _asyncMutex.unlock(); AsyncStruct *asyncStruct = imageInfo->asyncStruct; Image *image = imageInfo->image; diff --git a/cocos/renderer/CCTextureCache.h b/cocos/renderer/CCTextureCache.h index ffcad0b66a..e393c8593c 100644 --- a/cocos/renderer/CCTextureCache.h +++ b/cocos/renderer/CCTextureCache.h @@ -227,11 +227,10 @@ protected: std::thread* _loadingThread; - std::queue* _asyncStructQueue; + std::deque* _asyncStructQueue; std::deque* _imageInfoQueue; - std::mutex _asyncStructQueueMutex; - std::mutex _imageInfoMutex; + std::mutex _asyncMutex; std::mutex _sleepMutex; std::condition_variable _sleepCondition;