diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 496a2b75d0..e9a80d99ff 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1067,6 +1067,10 @@ 3E26D40518ACB5D100834404 /* CCImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E26D40418ACB5D100834404 /* CCImage.cpp */; }; 3E26D40618ACB5D100834404 /* CCImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E26D40418ACB5D100834404 /* CCImage.cpp */; }; 3E26D40818ACB63900834404 /* CCDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E26D40718ACB63900834404 /* CCDevice.mm */; }; + 3E9C7E5C191C61EB00429574 /* CCGLProgramStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9C7E5A191C61EB00429574 /* CCGLProgramStateCache.cpp */; }; + 3E9C7E5D191C61EB00429574 /* CCGLProgramStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9C7E5A191C61EB00429574 /* CCGLProgramStateCache.cpp */; }; + 3E9C7E5E191C61EB00429574 /* CCGLProgramStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9C7E5B191C61EB00429574 /* CCGLProgramStateCache.h */; }; + 3E9C7E5F191C61EB00429574 /* CCGLProgramStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9C7E5B191C61EB00429574 /* CCGLProgramStateCache.h */; }; 3EA0FB5B191B92CC00B170C8 /* UIVideoWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA0FB59191B92CC00B170C8 /* UIVideoWidget.h */; }; 3EA0FB5C191B92CC00B170C8 /* UIVideoWidgetIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3EA0FB5A191B92CC00B170C8 /* UIVideoWidgetIOS.mm */; }; 460E468118080832000CDD6D /* cocos-ext.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A167D21807AF4D005B8026 /* cocos-ext.h */; }; @@ -2292,6 +2296,8 @@ 37936A3E1869B76800E974DD /* writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = writer.h; sourceTree = ""; }; 3E26D40418ACB5D100834404 /* CCImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCImage.cpp; sourceTree = ""; }; 3E26D40718ACB63900834404 /* CCDevice.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CCDevice.mm; sourceTree = ""; }; + 3E9C7E5A191C61EB00429574 /* CCGLProgramStateCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCGLProgramStateCache.cpp; sourceTree = ""; }; + 3E9C7E5B191C61EB00429574 /* CCGLProgramStateCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGLProgramStateCache.h; sourceTree = ""; }; 3EA0FB59191B92CC00B170C8 /* UIVideoWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIVideoWidget.h; sourceTree = ""; }; 3EA0FB5A191B92CC00B170C8 /* UIVideoWidgetIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIVideoWidgetIOS.mm; sourceTree = ""; }; 46A15FCC1807A544005B8026 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; name = AUTHORS; path = ../AUTHORS; sourceTree = ""; }; @@ -4609,6 +4615,8 @@ 500DC89819105D41007B91BF /* renderer */ = { isa = PBXGroup; children = ( + 3E9C7E5A191C61EB00429574 /* CCGLProgramStateCache.cpp */, + 3E9C7E5B191C61EB00429574 /* CCGLProgramStateCache.h */, 5034C9F4191C5D6800CE6051 /* Shaders */, 5034C993191C5D4500CE6051 /* ccShaders.h */, 5034C994191C5D4500CE6051 /* ccShaders.cpp */, @@ -4923,6 +4931,7 @@ 2905FA4818CF08D100240AA3 /* UIButton.h in Headers */, 46A170EB1807CECA005B8026 /* CCPhysicsJoint.h in Headers */, 46A170241807CBFC005B8026 /* CCSAXParser.h in Headers */, + 3E9C7E5E191C61EB00429574 /* CCGLProgramStateCache.h in Headers */, 46A1701A1807CBFC005B8026 /* CCDevice.h in Headers */, B2AF2F9F18EBAEAE00C5807C /* Quaternion.h in Headers */, 46A170161807CBFC005B8026 /* CCLock.h in Headers */, @@ -5590,6 +5599,7 @@ 1A570332180BCFD50088DEC7 /* CCUserDefault.h in Headers */, 500DC94319106300007B91BF /* CCData.h in Headers */, 1A57034E180BD09B0088DEC7 /* tinyxml2.h in Headers */, + 3E9C7E5F191C61EB00429574 /* CCGLProgramStateCache.h in Headers */, 1A570357180BD0B00088DEC7 /* ioapi.h in Headers */, 1A01C69B18F57BE800EFE3A6 /* CCSet.h in Headers */, 1A57035B180BD0B00088DEC7 /* unzip.h in Headers */, @@ -6271,6 +6281,7 @@ 1AD71DCD180E26E600808F54 /* CCControlLoader.cpp in Sources */, 50FCEBC718C72017004AD434 /* WidgetReader.cpp in Sources */, 1AD71DD1180E26E600808F54 /* CCLabelBMFontLoader.cpp in Sources */, + 3E9C7E5C191C61EB00429574 /* CCGLProgramStateCache.cpp in Sources */, 1AD71DD5180E26E600808F54 /* CCLabelTTFLoader.cpp in Sources */, 1AD71DD9180E26E600808F54 /* CCLayerColorLoader.cpp in Sources */, 500DC94C19106300007B91BF /* CCEvent.cpp in Sources */, @@ -6576,6 +6587,7 @@ 50FCEB9818C72017004AD434 /* CheckBoxReader.cpp in Sources */, 1A570076180BC5A10088DEC7 /* CCActionGrid3D.cpp in Sources */, 500DC99D19106300007B91BF /* CCValue.cpp in Sources */, + 3E9C7E5D191C61EB00429574 /* CCGLProgramStateCache.cpp in Sources */, 3EA0FB5C191B92CC00B170C8 /* UIVideoWidgetIOS.mm in Sources */, B37510851823ACA100B3BA6A /* CCPhysicsWorldInfo_chipmunk.cpp in Sources */, 1A57007A180BC5A10088DEC7 /* CCActionInstant.cpp in Sources */, diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 273b3427fe..268995e87d 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -644,14 +644,12 @@ void Node::setGLProgramState(cocos2d::GLProgramState *glProgramState) void Node::setGLProgram(GLProgram *glProgram) { - if(_glProgramState == nullptr) { + if (_glProgramState == nullptr || (_glProgramState && _glProgramState->getGLProgram() != glProgram)) + { + CC_SAFE_RELEASE(_glProgramState); _glProgramState = GLProgramState::create(glProgram); _glProgramState->retain(); } - else - { - _glProgramState->setGLProgram(glProgram); - } } GLProgram * Node::getGLProgram() diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index 6bdb2aaab0..ef212b98bf 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -29,6 +29,7 @@ THE SOFTWARE. #include "renderer/CCGLProgramState.h" #include "renderer/CCGLProgram.h" #include "renderer/ccGLStateCache.h" +#include "renderer/CCGLProgramStateCache.h" NS_CC_BEGIN @@ -203,15 +204,21 @@ void VertexAttribValue::setPointer(GLint size, GLenum type, GLboolean normalized // // -GLProgramState* GLProgramState::create(GLProgram *glprogram) +GLProgramState* GLProgramState::create(GLProgram *glprogram, bool useCache) { - auto ret = new (std::nothrow) GLProgramState; - if(ret && ret->init(glprogram)) { - ret->autorelease(); - return ret; + GLProgramState* ret = nullptr; + if (useCache) + { + ret = GLProgramStateCache::getInstance()->getProgramState(glprogram); } - CC_SAFE_RELEASE(ret); - return nullptr; + else + { + ret = new (std::nothrow) GLProgramState; + if(!ret || !ret->init(glprogram)) + CC_SAFE_RELEASE(ret); + } + + return ret; } GLProgramState::GLProgramState() @@ -221,6 +228,7 @@ GLProgramState::GLProgramState() GLProgramState::~GLProgramState() { + GLProgramStateCache::getInstance()->removeProgramState(_glprogram); _glprogram->release(); } diff --git a/cocos/renderer/CCGLProgramState.h b/cocos/renderer/CCGLProgramState.h index b52d08fd09..ee37f56635 100644 --- a/cocos/renderer/CCGLProgramState.h +++ b/cocos/renderer/CCGLProgramState.h @@ -136,8 +136,9 @@ protected: // class GLProgramState : public Ref { + friend class GLProgramStateCache; public: - static GLProgramState* create(GLProgram* glprogram); + static GLProgramState* create(GLProgram* glprogram, bool useCache = true); void apply(const Matrix& modelView); diff --git a/cocos/renderer/CCGLProgramStateCache.cpp b/cocos/renderer/CCGLProgramStateCache.cpp new file mode 100644 index 0000000000..35b52f95c6 --- /dev/null +++ b/cocos/renderer/CCGLProgramStateCache.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +Copyright 2013-2014 Chukong Technologies Inc. + +http://www.cocos2d-x.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN false EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + +#include "renderer/CCGLProgramStateCache.h" +#include "renderer/CCGLProgramState.h" +#include "renderer/CCGLProgram.h" + + +NS_CC_BEGIN + +GLProgramStateCache* GLProgramStateCache::s_instance = nullptr; + +GLProgramStateCache::GLProgramStateCache() +{ + s_instance = nullptr; +} + +GLProgramStateCache::~GLProgramStateCache() +{ + for (auto itr = _glProgramStates.begin(); itr != _glProgramStates.end(); itr++) { + itr->second->release(); + } + _glProgramStates.clear(); + s_instance = nullptr; +} + +GLProgramStateCache* GLProgramStateCache::getInstance() +{ + if (s_instance == nullptr) + s_instance = new GLProgramStateCache(); + + return s_instance; +} + +void GLProgramStateCache::destroyInstance() +{ + delete s_instance; +} + +GLProgramState* GLProgramStateCache::getProgramState(GLProgram* glprogram) +{ + const auto& itr = _glProgramStates.find(glprogram); + if (itr != _glProgramStates.end()) + { + return itr->second; + } + + auto ret = new (std::nothrow) GLProgramState; + if(ret && ret->init(glprogram)) { + _glProgramStates[glprogram] = ret; + ret->autorelease(); + return ret; + } + + CC_SAFE_RELEASE(ret); + return ret; +} + +void GLProgramStateCache::removeProgramState(GLProgram* program) +{ + auto itr = _glProgramStates.find(program); + if (itr != _glProgramStates.end()) + { + _glProgramStates.erase(itr); + } +} + +NS_CC_END diff --git a/cocos/renderer/CCGLProgramStateCache.h b/cocos/renderer/CCGLProgramStateCache.h new file mode 100644 index 0000000000..5a1564a8be --- /dev/null +++ b/cocos/renderer/CCGLProgramStateCache.h @@ -0,0 +1,69 @@ +/**************************************************************************** +Copyright 2014 Chukong Technologies Inc. + +http://www.cocos2d-x.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + +#ifndef __CCGLPROGRAMSTATECACHE_H__ +#define __CCGLPROGRAMSTATECACHE_H__ + +#include "base/ccTypes.h" +#include "base/CCVector.h" +#include "math/Vector2.h" +#include "math/Vector3.h" +#include "math/Vector4.h" + +#include + +NS_CC_BEGIN + +class GLProgram; + +class GLProgramState; + +// +// +// GLProgramStateCache +// +// +class GLProgramStateCache +{ +public: + static GLProgramStateCache* getInstance(); + + static void destroyInstance(); + + GLProgramState* getProgramState(GLProgram* program); + + void removeProgramState(GLProgram* program); + +protected: + GLProgramStateCache(); + + ~GLProgramStateCache(); + + std::unordered_map _glProgramStates; + static GLProgramStateCache* s_instance; +}; + +NS_CC_END + +#endif /* __CCGLPROGRAMSTATECACHE_H__ */