From afc7c2b449b686a81e5e4277a77dc24e51d098c0 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 12 Sep 2012 02:13:36 -0500 Subject: [PATCH] Better robustness when loading shaders. Redundant shaders (eg: "deferred/shadowF.glsl") will only need to be compiled once, and LLShaderMgr::mShaderObjects won't have previous entries mistakenly overwritten as a result. --- indra/llrender/llshadermgr.cpp | 10 +++++++++- indra/llrender/llshadermgr.h | 10 +++++++++- indra/newview/llviewershadermgr.cpp | 6 +++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 2531df4b6..234d2e141 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -525,6 +525,14 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels) { + std::pair::iterator, std::multimap::iterator> range; + range = mShaderObjects.equal_range(filename); + for (std::multimap::iterator it = range.first; it != range.second;++it) + { + if((*it).second.mLevel == shader_level && (*it).second.mType == type) + return (*it).second.mHandle; + } + GLenum error = GL_NO_ERROR; if (gDebugGL) { @@ -888,7 +896,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (ret) { // Add shader file to map - mShaderObjects[filename] = ret; + mShaderObjects.insert(make_pair(filename,CachedObjectInfo(ret,try_gpu_class,type))); shader_level = try_gpu_class; } else diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index b06d61b3e..fc9242f7c 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -185,8 +185,16 @@ public: virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual public: + struct CachedObjectInfo + { + CachedObjectInfo(GLhandleARB handle, U32 level, GLenum type) : + mHandle(handle), mLevel(level), mType(type) {} + GLhandleARB mHandle; //Actual handle of the opengl shader object. + U32 mLevel; //Level /might/ not be needed, but it's stored to ensure there's no change in behavior. + GLenum mType; //GL_VERTEX_SHADER_ARB or GL_FRAGMENT_SHADER_ARB. Tracked because some utility shaders can be loaded as both types (carefully). + }; // Map of shader names to compiled - std::map mShaderObjects; + std::multimap mShaderObjects; //Singu Note: Packing more info here. Doing such provides capability to skip unneeded duplicate loading.. //global (reserved slot) shader parameters std::vector mReservedAttribs; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 75b2170fb..356cc6cac 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -576,10 +576,10 @@ void LLViewerShaderMgr::setShaders() //Flag base shader objects for deletion //Don't worry-- they won't be deleted until no programs refrence them. - std::map::iterator it = mShaderObjects.begin(); + std::multimap::iterator it = mShaderObjects.begin(); for(; it!=mShaderObjects.end();++it) - if(it->second) - glDeleteObjectARB(it->second); + if(it->second.mHandle) + glDeleteObjectARB(it->second.mHandle); mShaderObjects.clear(); } else