From bcb131262c3ad8872612c07fccd515c13b92374d Mon Sep 17 00:00:00 2001 From: minggo Date: Wed, 27 Nov 2013 16:49:07 +0800 Subject: [PATCH] add helper funcion to invoke a function in gl thread --- cocos/2d/CCDirector.cpp | 6 +- cocos/2d/CCTextureCache.cpp | 7 ++- cocos/2d/platform/CCThread.cpp | 55 ++++++++++++++++--- cocos/2d/platform/CCThread.h | 38 ++++++++++--- cocos/2d/platform/apple/CCThread.mm | 49 +++++++++++++++-- .../cocostudio/CCDataReaderHelper.cpp | 5 +- 6 files changed, 132 insertions(+), 28 deletions(-) diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index 7e90fe92d8..36f72c81c5 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -1026,9 +1026,6 @@ void DisplayLinkDirector::startAnimation() } _invalid = false; -#ifndef EMSCRIPTEN - Application::getInstance()->setAnimationInterval(_animationInterval); -#endif // EMSCRIPTEN } void DisplayLinkDirector::mainLoop() @@ -1040,6 +1037,9 @@ void DisplayLinkDirector::mainLoop() } else if (! _invalid) { + // invoke call back from other thread + ThreadHelper::doCallback(); + drawScene(); // release the objects diff --git a/cocos/2d/CCTextureCache.cpp b/cocos/2d/CCTextureCache.cpp index 15b30ccb6a..6f4c521d3a 100644 --- a/cocos/2d/CCTextureCache.cpp +++ b/cocos/2d/CCTextureCache.cpp @@ -163,9 +163,8 @@ void TextureCache::loadImage() while (true) { // create autorelease pool for iOS - Thread thread; - thread.createAutoreleasePool(); - + auto autolreasePool = ThreadHelper::createAutoreleasePool(); + std::queue *pQueue = _asyncStructQueue; _asyncStructQueueMutex.lock(); if (pQueue->empty()) @@ -207,6 +206,8 @@ void TextureCache::loadImage() _imageInfoMutex.lock(); _imageInfoQueue->push(imageInfo); _imageInfoMutex.unlock(); + + ThreadHelper::releaseAutoreleasePool(autolreasePool); } if(_asyncStructQueue != nullptr) diff --git a/cocos/2d/platform/CCThread.cpp b/cocos/2d/platform/CCThread.cpp index d3f5b15999..7d4a23a216 100644 --- a/cocos/2d/platform/CCThread.cpp +++ b/cocos/2d/platform/CCThread.cpp @@ -24,23 +24,62 @@ THE SOFTWARE. #include "CCThread.h" +NS_CC_BEGIN + // iOS and Mac already has a Thread.mm #if (CC_TARGET_PLATFORM != CC_PLATFORM_IOS && CC_TARGET_PLATFORM != CC_PLATFORM_MAC) -NS_CC_BEGIN +std::list>* ThreadHelper::_callbackList = new std::list>(); +std::mutex* ThreadHelper::_mutex = new std::mutex; +long ThreadHelper::_callbackNumberPerFrame = 5; -Thread::~Thread() + +void* ThreadHelper::createAutoreleasePool() { - // To prevent warning: private field '_autoreasePool' is not - // used [-Wunused-private-field] by CLANG. - _autoReleasePool = nullptr; + return nullptr; } -void Thread::createAutoreleasePool() +void ThreadHelper::releaseAutoreleasePool(void* autoreleasePool) { - + } -NS_CC_END +void ThreadHelper::runOnGLThread(std::function f) +{ + // Insert call back function + _mutex->lock(); + _callbackList->push_back(f); + _mutex->unlock(); +} + +void ThreadHelper::doCallback() +{ + _mutex->lock(); + auto iter = _callbackList->begin(); + long i = 0; + while (iter != _callbackList->end()) + { + auto f = *iter; + f(); + + ++i; + if (i >= _callbackNumberPerFrame) + { + break; + } + else + { + iter = _callbackList->erase(iter); + } + } + _mutex->unlock(); +} + +void ThreadHelper::setCallbackNumberPerFrame(long callbackNumberPerFrame) +{ + _callbackNumberPerFrame = callbackNumberPerFrame; +} #endif + +NS_CC_END diff --git a/cocos/2d/platform/CCThread.h b/cocos/2d/platform/CCThread.h index 46936642eb..b0998eeb59 100644 --- a/cocos/2d/platform/CCThread.h +++ b/cocos/2d/platform/CCThread.h @@ -25,8 +25,12 @@ THE SOFTWARE. #ifndef __CC_PLATFORM_THREAD_H__ #define __CC_PLATFORM_THREAD_H__ +#include +#include +#include #include "platform/CCCommon.h" #include "CCPlatformMacros.h" +#include "CCDirector.h" NS_CC_BEGIN @@ -39,27 +43,45 @@ NS_CC_BEGIN * and release it when the thread end. */ -class CC_DLL Thread +class CC_DLL ThreadHelper { public: - /** + friend DisplayLinkDirector; + + /** Create an autorelease pool for objective-c codes. * @js NA * @lua NA */ - Thread() : _autoReleasePool(nullptr) {} + static void* createAutoreleasePool(); + /** * @js NA * @lua NA - */ - ~Thread(); - /** + */ + static void releaseAutoreleasePool(void *autoreleasePool); + + /** To run a function in gl thread. * @js NA * @lua NA + @since v3.0 */ - void createAutoreleasePool(); + static void runOnGLThread(std::function f); + + /** Set how many callback functions being invoked per frame. Default value is 5. + * @js NA + * @lua NA + @since v3.0 + */ + static void setCallbackNumberPerFrame(long callbackNumberPerFrame); private: - void *_autoReleasePool; + // This function will be call by Director to call some call back function on gl thread + static void doCallback(); + + static std::list> *_callbackList; + static std::mutex *_mutex; + // How many callback functions invoked per frame + static long _callbackNumberPerFrame; }; // end of platform group diff --git a/cocos/2d/platform/apple/CCThread.mm b/cocos/2d/platform/apple/CCThread.mm index 80b319bae4..4e138fb889 100644 --- a/cocos/2d/platform/apple/CCThread.mm +++ b/cocos/2d/platform/apple/CCThread.mm @@ -26,14 +26,55 @@ THE SOFTWARE. NS_CC_BEGIN -Thread::~Thread() +std::list>* ThreadHelper::_callbackList = new std::list>(); +std::mutex* ThreadHelper::_mutex = new std::mutex; +long ThreadHelper::_callbackNumberPerFrame = 5; + +void* ThreadHelper::createAutoreleasePool() { - [(id)_autoReleasePool release]; + id pool = [[NSAutoreleasePool alloc] init]; + return pool; } -void Thread::createAutoreleasePool() +void ThreadHelper::releaseAutoreleasePool(void *autoreleasePool) { - _autoReleasePool = [[NSAutoreleasePool alloc] init]; + [(NSAutoreleasePool*)autoreleasePool release]; +} + +void ThreadHelper::runOnGLThread(std::function f) +{ + // Insert call back function + _mutex->lock(); + _callbackList->push_back(f); + _mutex->unlock(); +} + +void ThreadHelper::doCallback() +{ + _mutex->lock(); + auto iter = _callbackList->begin(); + long i = 0; + while (iter != _callbackList->end()) + { + auto f = *iter; + f(); + + ++i; + if (i >= _callbackNumberPerFrame) + { + break; + } + else + { + iter = _callbackList->erase(iter); + } + } + _mutex->unlock(); +} + +void ThreadHelper::setCallbackNumberPerFrame(long callbackNumberPerFrame) +{ + _callbackNumberPerFrame = callbackNumberPerFrame; } NS_CC_END diff --git a/cocos/editor-support/cocostudio/CCDataReaderHelper.cpp b/cocos/editor-support/cocostudio/CCDataReaderHelper.cpp index 27b0a70bb8..b2c2e22295 100644 --- a/cocos/editor-support/cocostudio/CCDataReaderHelper.cpp +++ b/cocos/editor-support/cocostudio/CCDataReaderHelper.cpp @@ -155,8 +155,7 @@ void DataReaderHelper::loadData() while (true) { // create autorelease pool for iOS - Thread thread; - thread.createAutoreleasePool(); + auto autoreleasePool = ThreadHelper::createAutoreleasePool(); std::queue *pQueue = _asyncStructQueue; _asyncStructQueueMutex.lock(); // get async struct from queue @@ -200,6 +199,8 @@ void DataReaderHelper::loadData() _dataInfoMutex.lock(); _dataQueue->push(pDataInfo); _dataInfoMutex.unlock(); + + ThreadHelper::releaseAutoreleasePool(autoreleasePool); } if( _asyncStructQueue != nullptr )