From 7d3e9723c3732b2f8cbd05aa4415da33d11d8285 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 10 Feb 2011 18:21:38 -0600 Subject: [PATCH] Reduced LL's leakage of program/shader objects, drastically. Re-structured some shader loading/unloading handling. These changes are pretty experimental. I'll be holding off of tweaking the paramater managers(among other things) until I know if this stuff is working correctly. --- indra/llrender/llglslshader.cpp | 27 ++- indra/llrender/llglslshader.h | 3 +- indra/llrender/llshadermgr.cpp | 3 + indra/llrender/llshadermgr.h | 3 + indra/newview/llviewershadermgr.cpp | 319 ++++++++++------------------ indra/newview/llviewershadermgr.h | 12 +- 6 files changed, 151 insertions(+), 216 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 933da8ab7..74d48fa0e 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -69,9 +69,10 @@ hasGamma(false), hasLighting(false), calculatesAtmospherics(false) //=============================== // LLGLSL Shader implementation //=============================== -LLGLSLShader::LLGLSLShader() -: mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT) +LLGLSLShader::LLGLSLShader(S32 shader_class) +: mProgramObject(0), mShaderClass(shader_class), mShaderLevel(0), mShaderGroup(SG_DEFAULT) { + LLShaderMgr::getGlobalShaderList().push_back(this); } void LLGLSLShader::unload() @@ -84,17 +85,18 @@ void LLGLSLShader::unload() if (mProgramObject) { - GLhandleARB obj[1024]; + //Don't do this! Attached objects are already flagged for deletion. + //They will be deleted when no programs have them attached. (deleting a program auto-detaches them!) + /*GLhandleARB obj[1024]; GLsizei count; glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); - for (GLsizei i = 0; i < count; i++) + for (GLsizei i = 0; i < count; i++) { glDeleteObjectARB(obj[i]); - } - - glDeleteObjectARB(mProgramObject); - + }*/ + if(mProgramObject) + glDeleteObjectARB(mProgramObject); mProgramObject = 0; } @@ -110,12 +112,17 @@ BOOL LLGLSLShader::createShader(vector * attributes, llassert_always(!mShaderFiles.empty()); BOOL success = TRUE; + if(mProgramObject) //purge the old program + glDeleteObjectARB(mProgramObject); // Create program mProgramObject = glCreateProgramObjectARB(); // Attach existing objects if (!LLShaderMgr::instance()->attachShaderFeatures(this)) { + if(mProgramObject) + glDeleteObjectARB(mProgramObject); + mProgramObject = 0; return FALSE; } @@ -145,6 +152,10 @@ BOOL LLGLSLShader::createShader(vector * attributes, } if( !success ) { + if(mProgramObject) + glDeleteObjectARB(mProgramObject); + mProgramObject = 0; + LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL; // Try again using a lower shader level; diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 166d4af04..1f46a7b4f 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -67,7 +67,7 @@ public: SG_WATER }; - LLGLSLShader(); + LLGLSLShader(S32 shader_class); void unload(); BOOL createShader(std::vector * attributes, @@ -134,6 +134,7 @@ public: std::map mValue; //lookup map of uniform location to last known value std::vector mTexture; S32 mActiveTextureChannels; + S32 mShaderClass; S32 mShaderLevel; S32 mShaderGroup; BOOL mUniformsDirty; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 1286e91e4..810d9fa2c 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -385,6 +385,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (error != GL_NO_ERROR) { LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL; + glDeleteObjectARB(ret); //no longer need handle } else { @@ -394,6 +395,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (error != GL_NO_ERROR) { LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL; + glDeleteObjectARB(ret); //no longer need handle } } } @@ -413,6 +415,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade //an error occured, print log LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL; dumpObjectLog(ret); + glDeleteObjectARB(ret); //no longer need handle ret = 0; } } diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 2488c7ab0..02f5842a1 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -71,6 +71,9 @@ protected: // our parameter manager singleton instance static LLShaderMgr * sInstance; +public: + static void unloadShaderClass(int shader_class); + static std::vector &getGlobalShaderList(); //Holds a list of ALL LLGLSLShader objects. }; //LLShaderMgr #endif diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 30cc972e7..4c5990e56 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -67,99 +67,72 @@ BOOL LLViewerShaderMgr::sInitialized = FALSE; LLVector4 gShinyOrigin; -//object shaders -LLGLSLShader gObjectSimpleProgram; -LLGLSLShader gObjectSimpleWaterProgram; -LLGLSLShader gObjectFullbrightProgram; -LLGLSLShader gObjectFullbrightWaterProgram; + // WindLight shader handles + // Make sure WL Sky is the first program +LLGLSLShader gWLSkyProgram(LLViewerShaderMgr::SHADER_WINDLIGHT); +LLGLSLShader gWLCloudProgram(LLViewerShaderMgr::SHADER_WINDLIGHT); -LLGLSLShader gObjectFullbrightShinyProgram; -LLGLSLShader gObjectShinyProgram; -LLGLSLShader gObjectShinyWaterProgram; - -//environment shaders -LLGLSLShader gTerrainProgram; -LLGLSLShader gTerrainWaterProgram; -LLGLSLShader gWaterProgram; -LLGLSLShader gUnderWaterProgram; - -//interface shaders -LLGLSLShader gHighlightProgram; - -//avatar shader handles -LLGLSLShader gAvatarProgram; -LLGLSLShader gAvatarWaterProgram; -LLGLSLShader gAvatarEyeballProgram; -LLGLSLShader gAvatarPickProgram; - -// WindLight shader handles -LLGLSLShader gWLSkyProgram; -LLGLSLShader gWLCloudProgram; - -// Effects Shaders -LLGLSLShader gGlowProgram; -LLGLSLShader gGlowExtractProgram; -LLGLSLShader gPostColorFilterProgram; -LLGLSLShader gPostNightVisionProgram; -LLGLSLShader gPostGaussianBlurProgram; - -// Deferred rendering shaders -LLGLSLShader gDeferredImpostorProgram; -LLGLSLShader gDeferredWaterProgram; -LLGLSLShader gDeferredDiffuseProgram; -LLGLSLShader gDeferredBumpProgram; -LLGLSLShader gDeferredTerrainProgram; -LLGLSLShader gDeferredTreeProgram; -LLGLSLShader gDeferredAvatarProgram; -LLGLSLShader gDeferredAvatarAlphaProgram; -LLGLSLShader gDeferredLightProgram; -LLGLSLShader gDeferredMultiLightProgram; -LLGLSLShader gDeferredSunProgram; -LLGLSLShader gDeferredBlurLightProgram; -LLGLSLShader gDeferredSoftenProgram; -LLGLSLShader gDeferredShadowProgram; -LLGLSLShader gDeferredAvatarShadowProgram; -LLGLSLShader gDeferredAlphaProgram; -LLGLSLShader gDeferredFullbrightProgram; + //object shaders +LLGLSLShader gObjectSimpleProgram(LLViewerShaderMgr::SHADER_OBJECT); +LLGLSLShader gObjectSimpleWaterProgram(LLViewerShaderMgr::SHADER_OBJECT); +LLGLSLShader gObjectFullbrightProgram(LLViewerShaderMgr::SHADER_OBJECT); +LLGLSLShader gObjectFullbrightWaterProgram(LLViewerShaderMgr::SHADER_OBJECT); + +LLGLSLShader gObjectFullbrightShinyProgram(LLViewerShaderMgr::SHADER_OBJECT); +LLGLSLShader gObjectShinyProgram(LLViewerShaderMgr::SHADER_OBJECT); +LLGLSLShader gObjectShinyWaterProgram(LLViewerShaderMgr::SHADER_OBJECT); + + //environment shaders +LLGLSLShader gTerrainProgram(LLViewerShaderMgr::SHADER_ENVIRONMENT); +LLGLSLShader gTerrainWaterProgram(LLViewerShaderMgr::SHADER_WATER); //note, water. +LLGLSLShader gWaterProgram(LLViewerShaderMgr::SHADER_WATER); +LLGLSLShader gUnderWaterProgram(LLViewerShaderMgr::SHADER_WATER); + + //interface shaders +LLGLSLShader gHighlightProgram(LLViewerShaderMgr::SHADER_INTERFACE); //Not in mShaderList + + //avatar shader handles +LLGLSLShader gAvatarProgram(LLViewerShaderMgr::SHADER_AVATAR); +LLGLSLShader gAvatarWaterProgram(LLViewerShaderMgr::SHADER_AVATAR); +LLGLSLShader gAvatarEyeballProgram(LLViewerShaderMgr::SHADER_AVATAR); +LLGLSLShader gAvatarPickProgram(LLViewerShaderMgr::SHADER_AVATAR); //Not in mShaderList + + // Effects Shaders +LLGLSLShader gGlowProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList +LLGLSLShader gGlowExtractProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList +LLGLSLShader gPostColorFilterProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList +LLGLSLShader gPostNightVisionProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList +LLGLSLShader gPostGaussianBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList + + // Deferred rendering shaders +LLGLSLShader gDeferredImpostorProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics +LLGLSLShader gDeferredDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList +LLGLSLShader gDeferredBumpProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList +LLGLSLShader gDeferredTerrainProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList +LLGLSLShader gDeferredTreeProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList +LLGLSLShader gDeferredAvatarProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList +LLGLSLShader gDeferredAvatarAlphaProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics +LLGLSLShader gDeferredLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredMultiLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredSunProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredBlurLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredSoftenProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredShadowProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList +LLGLSLShader gDeferredAvatarShadowProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList +LLGLSLShader gDeferredAlphaProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics +LLGLSLShader gDeferredFullbrightProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics //current avatar shader parameter pointer GLint gAvatarMatrixParam; LLViewerShaderMgr::LLViewerShaderMgr() : mVertexShaderLevel(SHADER_COUNT, 0) -{ - /// Make sure WL Sky is the first program - mShaderList.push_back(&gWLSkyProgram); - mShaderList.push_back(&gWLCloudProgram); - mShaderList.push_back(&gAvatarProgram); - mShaderList.push_back(&gObjectShinyProgram); - mShaderList.push_back(&gWaterProgram); - mShaderList.push_back(&gAvatarEyeballProgram); - mShaderList.push_back(&gObjectSimpleProgram); - mShaderList.push_back(&gObjectFullbrightProgram); - mShaderList.push_back(&gObjectFullbrightShinyProgram); - mShaderList.push_back(&gTerrainProgram); - mShaderList.push_back(&gTerrainWaterProgram); - mShaderList.push_back(&gObjectSimpleWaterProgram); - mShaderList.push_back(&gObjectFullbrightWaterProgram); - mShaderList.push_back(&gAvatarWaterProgram); - mShaderList.push_back(&gObjectShinyWaterProgram); - mShaderList.push_back(&gUnderWaterProgram); - mShaderList.push_back(&gDeferredSunProgram); - mShaderList.push_back(&gDeferredBlurLightProgram); - mShaderList.push_back(&gDeferredSoftenProgram); - mShaderList.push_back(&gDeferredLightProgram); - mShaderList.push_back(&gDeferredMultiLightProgram); - mShaderList.push_back(&gDeferredAlphaProgram); - mShaderList.push_back(&gDeferredFullbrightProgram); - mShaderList.push_back(&gDeferredWaterProgram); - mShaderList.push_back(&gDeferredAvatarAlphaProgram); -} +{} LLViewerShaderMgr::~LLViewerShaderMgr() { mVertexShaderLevel.clear(); - mShaderList.clear(); } // static @@ -284,8 +257,6 @@ void LLViewerShaderMgr::setShaders() { return; } - // Make sure the compiled shader map is cleared before we recompile shaders. - mShaderObjects.clear(); initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); @@ -379,12 +350,7 @@ void LLViewerShaderMgr::setShaders() loadShadersWindLight(); loadShadersEffects(); loadShadersInterface(); - - // Load max avatar shaders to set the max level - mVertexShaderLevel[SHADER_AVATAR] = 3; - mMaxAvatarShaderLevel = 3; - loadShadersAvatar(); - + #if 0 && LL_DARWIN // force avatar shaders off for mac mVertexShaderLevel[SHADER_AVATAR] = 0; sMaxAvatarShaderLevel = 0; @@ -437,28 +403,24 @@ void LLViewerShaderMgr::setShaders() { gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; - mVertexShaderLevel[SHADER_LIGHTING] = 0; - mVertexShaderLevel[SHADER_INTERFACE] = 0; - mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - mVertexShaderLevel[SHADER_WATER] = 0; - mVertexShaderLevel[SHADER_OBJECT] = 0; - mVertexShaderLevel[SHADER_EFFECT] = 0; - mVertexShaderLevel[SHADER_WINDLIGHT] = 0; - mVertexShaderLevel[SHADER_AVATAR] = 0; + for (S32 i = 0; i < SHADER_COUNT; i++) + mVertexShaderLevel[i] = 0; } + + //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(); + for(it;it!=mShaderObjects.end();++it) + if(it->second) + glDeleteObjectARB(it->second); + mShaderObjects.clear(); } else { gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; - mVertexShaderLevel[SHADER_LIGHTING] = 0; - mVertexShaderLevel[SHADER_INTERFACE] = 0; - mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - mVertexShaderLevel[SHADER_WATER] = 0; - mVertexShaderLevel[SHADER_OBJECT] = 0; - mVertexShaderLevel[SHADER_EFFECT] = 0; - mVertexShaderLevel[SHADER_WINDLIGHT] = 0; - mVertexShaderLevel[SHADER_AVATAR] = 0; + for (S32 i = 0; i < SHADER_COUNT; i++) + mVertexShaderLevel[i] = 0; } if (gViewerWindow) @@ -470,43 +432,14 @@ void LLViewerShaderMgr::setShaders() void LLViewerShaderMgr::unloadShaders() { - gObjectSimpleProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightWaterProgram.unload(); + //Instead of manually unloading, shaders are now automatically accumulated in a list. + //Simply iterate and unload. + std::vector &shader_list = LLShaderMgr::getGlobalShaderList(); + for(std::vector::iterator it=shader_list.begin();it!=shader_list.end();++it) + (*it)->unload(); - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectShinyWaterProgram.unload(); - gWaterProgram.unload(); - gUnderWaterProgram.unload(); - gTerrainProgram.unload(); - gTerrainWaterProgram.unload(); - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - gAvatarProgram.unload(); - gAvatarWaterProgram.unload(); - gAvatarEyeballProgram.unload(); - gAvatarPickProgram.unload(); - gHighlightProgram.unload(); - - gWLSkyProgram.unload(); - gWLCloudProgram.unload(); - - gPostColorFilterProgram.unload(); - gPostNightVisionProgram.unload(); - gPostGaussianBlurProgram.unload(); - - gDeferredDiffuseProgram.unload(); - - mVertexShaderLevel[SHADER_LIGHTING] = 0; - mVertexShaderLevel[SHADER_OBJECT] = 0; - mVertexShaderLevel[SHADER_AVATAR] = 0; - mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - mVertexShaderLevel[SHADER_WATER] = 0; - mVertexShaderLevel[SHADER_INTERFACE] = 0; - mVertexShaderLevel[SHADER_EFFECT] = 0; - mVertexShaderLevel[SHADER_WINDLIGHT] = 0; + for (S32 i = 0; i < SHADER_COUNT; i++) + mVertexShaderLevel[i] = 0; gPipeline.mVertexShadersLoaded = 0; } @@ -603,7 +536,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment() if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0) { - gTerrainProgram.unload(); + unloadShaderClass(SHADER_ENVIRONMENT); return FALSE; } @@ -639,9 +572,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() if (mVertexShaderLevel[SHADER_WATER] == 0) { - gWaterProgram.unload(); - gUnderWaterProgram.unload(); - gTerrainWaterProgram.unload(); + unloadShaderClass(SHADER_WATER); return FALSE; } @@ -721,39 +652,32 @@ BOOL LLViewerShaderMgr::loadShadersEffects() if (mVertexShaderLevel[SHADER_EFFECT] == 0) { - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - gPostColorFilterProgram.unload(); - gPostNightVisionProgram.unload(); - gPostGaussianBlurProgram.unload(); + unloadShaderClass(SHADER_EFFECT); return FALSE; } - if (success) + if(LLPipeline::sRenderGlow) { - gGlowProgram.mName = "Glow Shader (Post)"; - gGlowProgram.mShaderFiles.clear(); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; - success = gGlowProgram.createShader(NULL, &mGlowUniforms); - if (!success) + if (success) { - LLPipeline::sRenderGlow = FALSE; + gGlowProgram.mName = "Glow Shader (Post)"; + gGlowProgram.mShaderFiles.clear(); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; + success = gGlowProgram.createShader(NULL, &mGlowUniforms); + LLPipeline::sRenderGlow = success; } - } - - if (success) - { - gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; - gGlowExtractProgram.mShaderFiles.clear(); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; - success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms); - if (!success) + + if (success) { - LLPipeline::sRenderGlow = FALSE; + gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; + gGlowExtractProgram.mShaderFiles.clear(); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; + success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms); + LLPipeline::sRenderGlow = success; } } @@ -827,23 +751,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { if (mVertexShaderLevel[SHADER_DEFERRED] == 0) { - gDeferredTreeProgram.unload(); - gDeferredDiffuseProgram.unload(); - gDeferredBumpProgram.unload(); - gDeferredImpostorProgram.unload(); - gDeferredTerrainProgram.unload(); - gDeferredLightProgram.unload(); - gDeferredMultiLightProgram.unload(); - gDeferredSunProgram.unload(); - gDeferredBlurLightProgram.unload(); - gDeferredSoftenProgram.unload(); - gDeferredShadowProgram.unload(); - gDeferredAvatarShadowProgram.unload(); - gDeferredAvatarProgram.unload(); - gDeferredAvatarAlphaProgram.unload(); - gDeferredAlphaProgram.unload(); - gDeferredFullbrightProgram.unload(); - gDeferredWaterProgram.unload(); + unloadShaderClass(SHADER_DEFERRED); return FALSE; } @@ -1051,13 +959,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() if (mVertexShaderLevel[SHADER_OBJECT] == 0) { - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectShinyWaterProgram.unload(); - gObjectSimpleProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightWaterProgram.unload(); + unloadShaderClass(SHADER_OBJECT); return FALSE; } @@ -1183,10 +1085,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() if (mVertexShaderLevel[SHADER_AVATAR] == 0) { - gAvatarProgram.unload(); - gAvatarWaterProgram.unload(); - gAvatarEyeballProgram.unload(); - gAvatarPickProgram.unload(); + unloadShaderClass(SHADER_AVATAR); return FALSE; } @@ -1273,7 +1172,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (mVertexShaderLevel[SHADER_INTERFACE] == 0) { - gHighlightProgram.unload(); + unloadShaderClass(SHADER_INTERFACE); return FALSE; } @@ -1302,8 +1201,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() if (mVertexShaderLevel[SHADER_WINDLIGHT] < 2) { - gWLSkyProgram.unload(); - gWLCloudProgram.unload(); + unloadShaderClass(SHADER_WINDLIGHT); return FALSE; } @@ -1344,3 +1242,18 @@ void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) LLWLParamManager::instance()->updateShaderUniforms(shader); LLWaterParamManager::instance()->updateShaderUniforms(shader); } + +/*static*/ void LLShaderMgr::unloadShaderClass(int shader_class) +{ + std::vector &shader_list = getGlobalShaderList(); + for(std::vector::iterator it=shader_list.begin();it!=shader_list.end();++it) + { + if((*it)->mShaderClass == shader_class) + (*it)->unload(); + } +} +/*static*/ std::vector &LLShaderMgr::getGlobalShaderList() +{ + static std::vector sGlbShaderLst; + return sGlbShaderLst; +} diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index cd19e7ae7..2b0e15051 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -227,12 +227,14 @@ public: shader_iter beginShaders() const { - return mShaderList.begin(); + return getGlobalShaderList().begin(); + //return mShaderList.begin(); } shader_iter endShaders() const { - return mShaderList.end(); + return getGlobalShaderList().end(); + //return mShaderList.end(); } @@ -263,8 +265,10 @@ private: std::vector mAvatarUniforms; // the list of shaders we need to propagate parameters to. - std::vector mShaderList; - + // Currently this is replaced with a global list of all shaders + // which isn't quite as efficient. However, if other changes prove + // stable then I will mimic mShaderList on a per-ParamManager basis. + //std::vector mShaderList; }; //LLViewerShaderMgr inline bool operator == (LLViewerShaderMgr::shader_iter const & a, LLViewerShaderMgr::shader_iter const & b)