diff options
author | Oz Linden <oz@lindenlab.com> | 2014-12-05 17:12:42 -0500 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2014-12-05 17:12:42 -0500 |
commit | bf2e3fca73b80afa10a1c913ba752fcaf79ccd19 (patch) | |
tree | 12a8ae6dd43c065b6ebc91f4b3ad1e29eade4c7f | |
parent | 44f5d7320952de2c4c7e1062b1c02c2f521400fa (diff) | |
parent | 6d48db868f7459fcf5f0e89d830a844e409d4163 (diff) |
merge changes for 3.7.22-release
26 files changed, 1492 insertions, 1566 deletions
@@ -493,3 +493,5 @@ bcc2770e21c125e0bab59141c51db9145aec068d 3.7.17-release 2729c1daf0257d68a40bdbc4acf1a16184974bbd 3.7.18-release 82973b38a6c9a457333e3519e4f2b16bb5eedf47 3.7.19-release 27094824773b907c2e559396e6f9ec3a963de52d 3.7.20-release +9ecab4b0c7d8614767724a3422d3c1dca6bd4e4f 3.7.21-release +bc61801f614022c920cb5c3df1d7d67a9561ce1f 3.7.22-release diff --git a/doc/contributions.txt b/doc/contributions.txt index f64f29a559..2f479cca86 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -324,6 +324,7 @@ Cinder Roxley STORM-2035 STORM-2036 STORM-2037 + STORM-2053 Clara Young Coaldust Numbers VWR-1095 @@ -890,6 +891,8 @@ Mm Alder VWR-4794 VWR-13578 Mo Hax +Moon Metty + STORM-2078 Mourna Biziou Mr Greggan VWR-445 @@ -994,6 +997,7 @@ Nicky Perian STORM-1087 STORM-1090 STORM-1828 + STORM-2080 Nicoladie Gymnast NiranV Dean STORM-2040 @@ -1054,6 +1058,11 @@ Peekay Semyorka VWR-19 VWR-49 VWR-79 +Pell Smit + STORM-2069 + STORM-2070 + STORM-2071 + STORM-2072 Peter Lameth VWR-7331 PeterPunk Mooney @@ -1397,6 +1406,7 @@ Whirly Fizzle MAINT-873 STORM-1930 BUG-6659 + STORM-2078 Whoops Babii VWR-631 VWR-1640 diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index b81dd4c9a1..3ceed95248 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -61,33 +61,33 @@ U64 LLGLSLShader::sTotalSamplesDrawn = 0; U32 LLGLSLShader::sTotalDrawCalls = 0; //UI shader -- declared here so llui_libtest will link properly -LLGLSLShader gUIProgram; -LLGLSLShader gSolidColorProgram; +LLGLSLShader gUIProgram; +LLGLSLShader gSolidColorProgram; BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) { - return v1 != v2; + return v1 != v2; } LLShaderFeatures::LLShaderFeatures() - : atmosphericHelpers(false) - , calculatesLighting(false) - , calculatesAtmospherics(false) - , hasLighting(false) - , isAlphaLighting(false) - , isShiny(false) - , isFullbright(false) - , isSpecular(false) - , hasWaterFog(false) - , hasTransport(false) - , hasSkinning(false) - , hasObjectSkinning(false) - , hasAtmospherics(false) - , hasGamma(false) - , mIndexedTextureChannels(0) - , disableTextureIndex(false) - , hasAlphaMask(false) - , attachNothing(false) + : atmosphericHelpers(false) + , calculatesLighting(false) + , calculatesAtmospherics(false) + , hasLighting(false) + , isAlphaLighting(false) + , isShiny(false) + , isFullbright(false) + , isSpecular(false) + , hasWaterFog(false) + , hasTransport(false) + , hasSkinning(false) + , hasObjectSkinning(false) + , hasAtmospherics(false) + , hasGamma(false) + , mIndexedTextureChannels(0) + , disableTextureIndex(false) + , hasAlphaMask(false) + , attachNothing(false) { } @@ -98,225 +98,225 @@ LLShaderFeatures::LLShaderFeatures() //static void LLGLSLShader::initProfile() { - sProfileEnabled = true; - sTotalTimeElapsed = 0; - sTotalTrianglesDrawn = 0; - sTotalSamplesDrawn = 0; - sTotalDrawCalls = 0; - - for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) - { - (*iter)->clearStats(); - } + sProfileEnabled = true; + sTotalTimeElapsed = 0; + sTotalTrianglesDrawn = 0; + sTotalSamplesDrawn = 0; + sTotalDrawCalls = 0; + + for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + (*iter)->clearStats(); + } } struct LLGLSLShaderCompareTimeElapsed { - bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs) - { - return lhs->mTimeElapsed < rhs->mTimeElapsed; - } + bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs) + { + return lhs->mTimeElapsed < rhs->mTimeElapsed; + } }; //static void LLGLSLShader::finishProfile(bool emit_report) { - sProfileEnabled = false; - - if (emit_report) - { - std::vector<LLGLSLShader*> sorted; - - for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) - { - sorted.push_back(*iter); - } - - std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); - - for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) - { - (*iter)->dumpStats(); - } - - LL_INFOS() << "-----------------------------------" << LL_ENDL; - LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL; - LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL; - LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL; - } + sProfileEnabled = false; + + if (emit_report) + { + std::vector<LLGLSLShader*> sorted; + + for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + sorted.push_back(*iter); + } + + std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + + for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) + { + (*iter)->dumpStats(); + } + + LL_INFOS() << "-----------------------------------" << LL_ENDL; + LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL; + LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL; + LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL; + } } void LLGLSLShader::clearStats() { - mTrianglesDrawn = 0; - mTimeElapsed = 0; - mSamplesDrawn = 0; - mDrawCalls = 0; - mTextureStateFetched = false; - mTextureMagFilter.clear(); - mTextureMinFilter.clear(); + mTrianglesDrawn = 0; + mTimeElapsed = 0; + mSamplesDrawn = 0; + mDrawCalls = 0; + mTextureStateFetched = false; + mTextureMagFilter.clear(); + mTextureMinFilter.clear(); } void LLGLSLShader::dumpStats() { - if (mDrawCalls > 0) - { - LL_INFOS() << "=============================================" << LL_ENDL; - LL_INFOS() << mName << LL_ENDL; - for (U32 i = 0; i < mShaderFiles.size(); ++i) - { - LL_INFOS() << mShaderFiles[i].first << LL_ENDL; - } - for (U32 i = 0; i < mTexture.size(); ++i) - { - GLint idx = mTexture[i]; - - if (idx >= 0) - { - GLint uniform_idx = getUniformLocation(i); - LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL; - } - } - LL_INFOS() << "=============================================" << LL_ENDL; - - F32 ms = mTimeElapsed/1000000.f; - F32 seconds = ms/1000.f; - - F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f; - F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0); - tris_sec /= seconds; - - F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f; - F32 samples_sec = (F32) mSamplesDrawn/1000000000.0; - samples_sec /= seconds; - - F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f; - U32 avg_batch = mTrianglesDrawn/mDrawCalls; - - LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL; - LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL; - LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL; - LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL; - } + if (mDrawCalls > 0) + { + LL_INFOS() << "=============================================" << LL_ENDL; + LL_INFOS() << mName << LL_ENDL; + for (U32 i = 0; i < mShaderFiles.size(); ++i) + { + LL_INFOS() << mShaderFiles[i].first << LL_ENDL; + } + for (U32 i = 0; i < mTexture.size(); ++i) + { + GLint idx = mTexture[i]; + + if (idx >= 0) + { + GLint uniform_idx = getUniformLocation(i); + LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL; + } + } + LL_INFOS() << "=============================================" << LL_ENDL; + + F32 ms = mTimeElapsed/1000000.f; + F32 seconds = ms/1000.f; + + F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f; + F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0); + tris_sec /= seconds; + + F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f; + F32 samples_sec = (F32) mSamplesDrawn/1000000000.0; + samples_sec /= seconds; + + F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f; + U32 avg_batch = mTrianglesDrawn/mDrawCalls; + + LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL; + LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL; + LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL; + LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL; + } } //static void LLGLSLShader::startProfile() { - if (sProfileEnabled && sCurBoundShaderPtr) - { - sCurBoundShaderPtr->placeProfileQuery(); - } + if (sProfileEnabled && sCurBoundShaderPtr) + { + sCurBoundShaderPtr->placeProfileQuery(); + } } //static void LLGLSLShader::stopProfile(U32 count, U32 mode) { - if (sProfileEnabled) - { - sCurBoundShaderPtr->readProfileQuery(count, mode); - } + if (sProfileEnabled && sCurBoundShaderPtr) + { + sCurBoundShaderPtr->readProfileQuery(count, mode); + } } void LLGLSLShader::placeProfileQuery() { #if !LL_DARWIN - if (mTimerQuery == 0) - { - glGenQueriesARB(1, &mSamplesQuery); - glGenQueriesARB(1, &mTimerQuery); - } + if (mTimerQuery == 0) + { + glGenQueriesARB(1, &mSamplesQuery); + glGenQueriesARB(1, &mTimerQuery); + } - if (!mTextureStateFetched) - { - mTextureStateFetched = true; - mTextureMagFilter.resize(mTexture.size()); - mTextureMinFilter.resize(mTexture.size()); + if (!mTextureStateFetched) + { + mTextureStateFetched = true; + mTextureMagFilter.resize(mTexture.size()); + mTextureMinFilter.resize(mTexture.size()); - U32 cur_active = gGL.getCurrentTexUnitIndex(); + U32 cur_active = gGL.getCurrentTexUnitIndex(); - for (U32 i = 0; i < mTexture.size(); ++i) - { - GLint idx = mTexture[i]; + for (U32 i = 0; i < mTexture.size(); ++i) + { + GLint idx = mTexture[i]; - if (idx >= 0) - { - gGL.getTexUnit(idx)->activate(); + if (idx >= 0) + { + gGL.getTexUnit(idx)->activate(); - U32 mag = 0xFFFFFFFF; - U32 min = 0xFFFFFFFF; + U32 mag = 0xFFFFFFFF; + U32 min = 0xFFFFFFFF; - U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType()); + U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType()); - glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag); - glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min); + glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag); + glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min); - mTextureMagFilter[i] = mag; - mTextureMinFilter[i] = min; - } - } + mTextureMagFilter[i] = mag; + mTextureMinFilter[i] = min; + } + } - gGL.getTexUnit(cur_active)->activate(); - } + gGL.getTexUnit(cur_active)->activate(); + } - glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery); - glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery); + glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery); + glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery); #endif } void LLGLSLShader::readProfileQuery(U32 count, U32 mode) { #if !LL_DARWIN - glEndQueryARB(GL_TIME_ELAPSED); - glEndQueryARB(GL_SAMPLES_PASSED); - - U64 time_elapsed = 0; - glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); - - U64 samples_passed = 0; - glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed); - - sTotalTimeElapsed += time_elapsed; - mTimeElapsed += time_elapsed; - - sTotalSamplesDrawn += samples_passed; - mSamplesDrawn += samples_passed; - - U32 tri_count = 0; - switch (mode) - { - case LLRender::TRIANGLES: tri_count = count/3; break; - case LLRender::TRIANGLE_FAN: tri_count = count-2; break; - case LLRender::TRIANGLE_STRIP: tri_count = count-2; break; - default: tri_count = count; break; //points lines etc just use primitive count - } - - mTrianglesDrawn += tri_count; - sTotalTrianglesDrawn += tri_count; - - sTotalDrawCalls++; - mDrawCalls++; + glEndQueryARB(GL_TIME_ELAPSED); + glEndQueryARB(GL_SAMPLES_PASSED); + + U64 time_elapsed = 0; + glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); + + U64 samples_passed = 0; + glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed); + + sTotalTimeElapsed += time_elapsed; + mTimeElapsed += time_elapsed; + + sTotalSamplesDrawn += samples_passed; + mSamplesDrawn += samples_passed; + + U32 tri_count = 0; + switch (mode) + { + case LLRender::TRIANGLES: tri_count = count/3; break; + case LLRender::TRIANGLE_FAN: tri_count = count-2; break; + case LLRender::TRIANGLE_STRIP: tri_count = count-2; break; + default: tri_count = count; break; //points lines etc just use primitive count + } + + mTrianglesDrawn += tri_count; + sTotalTrianglesDrawn += tri_count; + + sTotalDrawCalls++; + mDrawCalls++; #endif } LLGLSLShader::LLGLSLShader() - : mProgramObject(0), - mAttributeMask(0), - mTotalUniformSize(0), - mActiveTextureChannels(0), - mShaderLevel(0), - mShaderGroup(SG_DEFAULT), - mUniformsDirty(FALSE), - mTimerQuery(0), - mSamplesQuery(0) + : mProgramObject(0), + mAttributeMask(0), + mTotalUniformSize(0), + mActiveTextureChannels(0), + mShaderLevel(0), + mShaderGroup(SG_DEFAULT), + mUniformsDirty(FALSE), + mTimerQuery(0), + mSamplesQuery(0) { - + } LLGLSLShader::~LLGLSLShader() @@ -325,1077 +325,1077 @@ LLGLSLShader::~LLGLSLShader() void LLGLSLShader::unload() { - sInstances.erase(this); - - stop_glerror(); - mAttribute.clear(); - mTexture.clear(); - mUniform.clear(); - mShaderFiles.clear(); - mDefines.clear(); - - if (mProgramObject) - { - GLhandleARB obj[1024]; - GLsizei count; - - glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); - for (GLsizei i = 0; i < count; i++) - { + sInstances.erase(this); + + stop_glerror(); + mAttribute.clear(); + mTexture.clear(); + mUniform.clear(); + mShaderFiles.clear(); + mDefines.clear(); + + if (mProgramObject) + { + GLhandleARB obj[1024]; + GLsizei count; + + glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); + for (GLsizei i = 0; i < count; i++) + { #if !LL_DARWIN - if (glIsProgramARB(obj[i])) + if (glIsProgramARB(obj[i])) #endif - { - glDeleteObjectARB(obj[i]); - } - } - - glDeleteObjectARB(mProgramObject); - - mProgramObject = 0; - } - - if (mTimerQuery) - { - glDeleteQueriesARB(1, &mTimerQuery); - mTimerQuery = 0; - } - - if (mSamplesQuery) - { - glDeleteQueriesARB(1, &mSamplesQuery); - mSamplesQuery = 0; - } - - //hack to make apple not complain - glGetError(); - - stop_glerror(); + { + glDeleteObjectARB(obj[i]); + } + } + + glDeleteObjectARB(mProgramObject); + + mProgramObject = 0; + } + + if (mTimerQuery) + { + glDeleteQueriesARB(1, &mTimerQuery); + mTimerQuery = 0; + } + + if (mSamplesQuery) + { + glDeleteQueriesARB(1, &mSamplesQuery); + mSamplesQuery = 0; + } + + //hack to make apple not complain + glGetError(); + + stop_glerror(); } BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, - std::vector<LLStaticHashedString> * uniforms, - U32 varying_count, - const char** varyings) + std::vector<LLStaticHashedString> * uniforms, + U32 varying_count, + const char** varyings) { - sInstances.insert(this); + sInstances.insert(this); - //reloading, reset matrix hash values - for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i) - { - mMatHash[i] = 0xFFFFFFFF; - } - mLightHash = 0xFFFFFFFF; + //reloading, reset matrix hash values + for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i) + { + mMatHash[i] = 0xFFFFFFFF; + } + mLightHash = 0xFFFFFFFF; - llassert_always(!mShaderFiles.empty()); - BOOL success = TRUE; + llassert_always(!mShaderFiles.empty()); + BOOL success = TRUE; - // Create program - mProgramObject = glCreateProgramObjectARB(); - + // Create program + mProgramObject = glCreateProgramObjectARB(); + #if LL_DARWIN // work-around missing mix(vec3,vec3,bvec3) mDefines["OLD_SELECT"] = "1"; #endif - - //compile new source - vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); - for ( ; fileIter != mShaderFiles.end(); fileIter++ ) - { - GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels); - LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; - if (shaderhandle > 0) - { - attachObject(shaderhandle); - } - else - { - success = FALSE; - } - } - - // Attach existing objects - if (!LLShaderMgr::instance()->attachShaderFeatures(this)) - { - return FALSE; - } - - if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3) - { //indexed texture rendering requires GLSL 1.3 or later - //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again - mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1); - } + + //compile new source + vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); + for ( ; fileIter != mShaderFiles.end(); fileIter++ ) + { + GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels); + LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; + if (shaderhandle > 0) + { + attachObject(shaderhandle); + } + else + { + success = FALSE; + } + } + + // Attach existing objects + if (!LLShaderMgr::instance()->attachShaderFeatures(this)) + { + return FALSE; + } + + if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3) + { //indexed texture rendering requires GLSL 1.3 or later + //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again + mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1); + } #ifdef GL_INTERLEAVED_ATTRIBS - if (varying_count > 0 && varyings) - { - glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS); - } + if (varying_count > 0 && varyings) + { + glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS); + } #endif - // Map attributes and uniforms - if (success) - { - success = mapAttributes(attributes); - } - if (success) - { - success = mapUniforms(uniforms); - } - if( !success ) - { - LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL; - - // Try again using a lower shader level; - if (mShaderLevel > 0) - { - LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL; - mShaderLevel--; - return createShader(attributes,uniforms); - } - } - else if (mFeatures.mIndexedTextureChannels > 0) - { //override texture channels for indexed texture rendering - bind(); - S32 channel_count = mFeatures.mIndexedTextureChannels; - - for (S32 i = 0; i < channel_count; i++) - { - LLStaticHashedString uniName(llformat("tex%d", i)); - uniform1i(uniName, i); - } - - S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten - for (U32 i = 0; i < mTexture.size(); i++) - { - if (mTexture[i] > -1 && mTexture[i] < channel_count) - { - llassert(cur_tex < gGLManager.mNumTextureImageUnits); - uniform1i(i, cur_tex); - mTexture[i] = cur_tex++; - } - } - unbind(); - } - - return success; + // Map attributes and uniforms + if (success) + { + success = mapAttributes(attributes); + } + if (success) + { + success = mapUniforms(uniforms); + } + if( !success ) + { + LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL; + + // Try again using a lower shader level; + if (mShaderLevel > 0) + { + LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL; + mShaderLevel--; + return createShader(attributes,uniforms); + } + } + else if (mFeatures.mIndexedTextureChannels > 0) + { //override texture channels for indexed texture rendering + bind(); + S32 channel_count = mFeatures.mIndexedTextureChannels; + + for (S32 i = 0; i < channel_count; i++) + { + LLStaticHashedString uniName(llformat("tex%d", i)); + uniform1i(uniName, i); + } + + S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten + for (U32 i = 0; i < mTexture.size(); i++) + { + if (mTexture[i] > -1 && mTexture[i] < channel_count) + { + llassert(cur_tex < gGLManager.mNumTextureImageUnits); + uniform1i(i, cur_tex); + mTexture[i] = cur_tex++; + } + } + unbind(); + } + + return success; } BOOL LLGLSLShader::attachObject(std::string object) { - if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0) - { - stop_glerror(); - glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]); - stop_glerror(); - return TRUE; - } - else - { - LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL; - return FALSE; - } + if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0) + { + stop_glerror(); + glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]); + stop_glerror(); + return TRUE; + } + else + { + LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL; + return FALSE; + } } void LLGLSLShader::attachObject(GLhandleARB object) { - if (object != 0) - { - stop_glerror(); - glAttachObjectARB(mProgramObject, object); - stop_glerror(); - } - else - { - LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL; - } + if (object != 0) + { + stop_glerror(); + glAttachObjectARB(mProgramObject, object); + stop_glerror(); + } + else + { + LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL; + } } void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count) { - for (S32 i = 0; i < count; i++) - { - attachObject(objects[i]); - } + for (S32 i = 0; i < count; i++) + { + attachObject(objects[i]); + } } BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes) { - //before linking, make sure reserved attributes always have consistent locations - for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) - { - const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); - glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name); - } - - //link the program - BOOL res = link(); - - mAttribute.clear(); - U32 numAttributes = (attributes == NULL) ? 0 : attributes->size(); - mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1); - - if (res) - { //read back channel locations - - mAttributeMask = 0; - - //read back reserved channels first - for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) - { - const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); - S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name); - if (index != -1) - { - mAttribute[i] = index; - mAttributeMask |= 1 << i; - LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; - } - } - if (attributes != NULL) - { - for (U32 i = 0; i < numAttributes; i++) - { - const char* name = (*attributes)[i].String().c_str(); - S32 index = glGetAttribLocationARB(mProgramObject, name); - if (index != -1) - { - mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index; - LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; - } - } - } - - return TRUE; - } - - return FALSE; + //before linking, make sure reserved attributes always have consistent locations + for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) + { + const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); + glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name); + } + + //link the program + BOOL res = link(); + + mAttribute.clear(); + U32 numAttributes = (attributes == NULL) ? 0 : attributes->size(); + mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1); + + if (res) + { //read back channel locations + + mAttributeMask = 0; + + //read back reserved channels first + for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) + { + const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); + S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name); + if (index != -1) + { + mAttribute[i] = index; + mAttributeMask |= 1 << i; + LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; + } + } + if (attributes != NULL) + { + for (U32 i = 0; i < numAttributes; i++) + { + const char* name = (*attributes)[i].String().c_str(); + S32 index = glGetAttribLocationARB(mProgramObject, name); + if (index != -1) + { + mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index; + LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; + } + } + } + + return TRUE; + } + + return FALSE; } void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms) { - if (index == -1) - { - return; - } + if (index == -1) + { + return; + } - GLenum type; - GLsizei length; - GLint size = -1; - char name[1024]; /* Flawfinder: ignore */ - name[0] = 0; + GLenum type; + GLsizei length; + GLint size = -1; + char name[1024]; /* Flawfinder: ignore */ + name[0] = 0; - glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name); + glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name); #if !LL_DARWIN - if (size > 0) - { - switch(type) - { - case GL_FLOAT_VEC2: size *= 2; break; - case GL_FLOAT_VEC3: size *= 3; break; - case GL_FLOAT_VEC4: size *= 4; break; - case GL_DOUBLE: size *= 2; break; - case GL_DOUBLE_VEC2: size *= 2; break; - case GL_DOUBLE_VEC3: size *= 6; break; - case GL_DOUBLE_VEC4: size *= 8; break; - case GL_INT_VEC2: size *= 2; break; - case GL_INT_VEC3: size *= 3; break; - case GL_INT_VEC4: size *= 4; break; - case GL_UNSIGNED_INT_VEC2: size *= 2; break; - case GL_UNSIGNED_INT_VEC3: size *= 3; break; - case GL_UNSIGNED_INT_VEC4: size *= 4; break; - case GL_BOOL_VEC2: size *= 2; break; - case GL_BOOL_VEC3: size *= 3; break; - case GL_BOOL_VEC4: size *= 4; break; - case GL_FLOAT_MAT2: size *= 4; break; - case GL_FLOAT_MAT3: size *= 9; break; - case GL_FLOAT_MAT4: size *= 16; break; - case GL_FLOAT_MAT2x3: size *= 6; break; - case GL_FLOAT_MAT2x4: size *= 8; break; - case GL_FLOAT_MAT3x2: size *= 6; break; - case GL_FLOAT_MAT3x4: size *= 12; break; - case GL_FLOAT_MAT4x2: size *= 8; break; - case GL_FLOAT_MAT4x3: size *= 12; break; - case GL_DOUBLE_MAT2: size *= 8; break; - case GL_DOUBLE_MAT3: size *= 18; break; - case GL_DOUBLE_MAT4: size *= 32; break; - case GL_DOUBLE_MAT2x3: size *= 12; break; - case GL_DOUBLE_MAT2x4: size *= 16; break; - case GL_DOUBLE_MAT3x2: size *= 12; break; - case GL_DOUBLE_MAT3x4: size *= 24; break; - case GL_DOUBLE_MAT4x2: size *= 16; break; - case GL_DOUBLE_MAT4x3: size *= 24; break; - } - mTotalUniformSize += size; - } + if (size > 0) + { + switch(type) + { + case GL_FLOAT_VEC2: size *= 2; break; + case GL_FLOAT_VEC3: size *= 3; break; + case GL_FLOAT_VEC4: size *= 4; break; + case GL_DOUBLE: size *= 2; break; + case GL_DOUBLE_VEC2: size *= 2; break; + case GL_DOUBLE_VEC3: size *= 6; break; + case GL_DOUBLE_VEC4: size *= 8; break; + case GL_INT_VEC2: size *= 2; break; + case GL_INT_VEC3: size *= 3; break; + case GL_INT_VEC4: size *= 4; break; + case GL_UNSIGNED_INT_VEC2: size *= 2; break; + case GL_UNSIGNED_INT_VEC3: size *= 3; break; + case GL_UNSIGNED_INT_VEC4: size *= 4; break; + case GL_BOOL_VEC2: size *= 2; break; + case GL_BOOL_VEC3: size *= 3; break; + case GL_BOOL_VEC4: size *= 4; break; + case GL_FLOAT_MAT2: size *= 4; break; + case GL_FLOAT_MAT3: size *= 9; break; + case GL_FLOAT_MAT4: size *= 16; break; + case GL_FLOAT_MAT2x3: size *= 6; break; + case GL_FLOAT_MAT2x4: size *= 8; break; + case GL_FLOAT_MAT3x2: size *= 6; break; + case GL_FLOAT_MAT3x4: size *= 12; break; + case GL_FLOAT_MAT4x2: size *= 8; break; + case GL_FLOAT_MAT4x3: size *= 12; break; + case GL_DOUBLE_MAT2: size *= 8; break; + case GL_DOUBLE_MAT3: size *= 18; break; + case GL_DOUBLE_MAT4: size *= 32; break; + case GL_DOUBLE_MAT2x3: size *= 12; break; + case GL_DOUBLE_MAT2x4: size *= 16; break; + case GL_DOUBLE_MAT3x2: size *= 12; break; + case GL_DOUBLE_MAT3x4: size *= 24; break; + case GL_DOUBLE_MAT4x2: size *= 16; break; + case GL_DOUBLE_MAT4x3: size *= 24; break; + } + mTotalUniformSize += size; + } #endif - S32 location = glGetUniformLocationARB(mProgramObject, name); - if (location != -1) - { - //chop off "[0]" so we can always access the first element - //of an array by the array name - char* is_array = strstr(name, "[0]"); - if (is_array) - { - is_array[0] = 0; - } - - LLStaticHashedString hashedName(name); - mUniformNameMap[location] = name; - mUniformMap[hashedName] = location; - - LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL; - - //find the index of this uniform - for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++) - { - if ( (mUniform[i] == -1) - && (LLShaderMgr::instance()->mReservedUniforms[i] == name)) - { - //found it - mUniform[i] = location; - mTexture[i] = mapUniformTextureChannel(location, type); - return; - } - } - - if (uniforms != NULL) - { - for (U32 i = 0; i < uniforms->size(); i++) - { - if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1) - && ((*uniforms)[i].String() == name)) - { - //found it - mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location; - mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type); - return; - } - } - } - } + S32 location = glGetUniformLocationARB(mProgramObject, name); + if (location != -1) + { + //chop off "[0]" so we can always access the first element + //of an array by the array name + char* is_array = strstr(name, "[0]"); + if (is_array) + { + is_array[0] = 0; + } + + LLStaticHashedString hashedName(name); + mUniformNameMap[location] = name; + mUniformMap[hashedName] = location; + + LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL; + + //find the index of this uniform + for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++) + { + if ( (mUniform[i] == -1) + && (LLShaderMgr::instance()->mReservedUniforms[i] == name)) + { + //found it + mUniform[i] = location; + mTexture[i] = mapUniformTextureChannel(location, type); + return; + } + } + + if (uniforms != NULL) + { + for (U32 i = 0; i < uniforms->size(); i++) + { + if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1) + && ((*uniforms)[i].String() == name)) + { + //found it + mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location; + mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type); + return; + } + } + } + } } void LLGLSLShader::addPermutation(std::string name, std::string value) { - mDefines[name] = value; + mDefines[name] = value; } void LLGLSLShader::removePermutation(std::string name) { - mDefines[name].erase(); + mDefines[name].erase(); } GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) { - if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) || - type == GL_SAMPLER_2D_MULTISAMPLE) - { //this here is a texture - glUniform1iARB(location, mActiveTextureChannels); - LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; - return mActiveTextureChannels++; - } - return -1; + if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) || + type == GL_SAMPLER_2D_MULTISAMPLE) + { //this here is a texture + glUniform1iARB(location, mActiveTextureChannels); + LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; + return mActiveTextureChannels++; + } + return -1; } BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) { - BOOL res = TRUE; - - mTotalUniformSize = 0; - mActiveTextureChannels = 0; - mUniform.clear(); - mUniformMap.clear(); - mUniformNameMap.clear(); - mTexture.clear(); - mValue.clear(); - //initialize arrays - U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); - mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); - mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); - - bind(); - - //get the number of active uniforms - GLint activeCount; - glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); - - for (S32 i = 0; i < activeCount; i++) - { - mapUniform(i, uniforms); - } - - unbind(); - - LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL; - return res; + BOOL res = TRUE; + + mTotalUniformSize = 0; + mActiveTextureChannels = 0; + mUniform.clear(); + mUniformMap.clear(); + mUniformNameMap.clear(); + mTexture.clear(); + mValue.clear(); + //initialize arrays + U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); + mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); + mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); + + bind(); + + //get the number of active uniforms + GLint activeCount; + glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); + + for (S32 i = 0; i < activeCount; i++) + { + mapUniform(i, uniforms); + } + + unbind(); + + LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL; + return res; } BOOL LLGLSLShader::link(BOOL suppress_errors) { - BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); + BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); - if (!suppress_errors) - { + if (!suppress_errors) + { LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName); - } + } - return success; + return success; } void LLGLSLShader::bind() { - gGL.flush(); - if (gGLManager.mHasShaderObjects) - { - LLVertexBuffer::unbind(); - glUseProgramObjectARB(mProgramObject); - sCurBoundShader = mProgramObject; - sCurBoundShaderPtr = this; - if (mUniformsDirty) - { - LLShaderMgr::instance()->updateShaderUniforms(this); - mUniformsDirty = FALSE; - } - } + gGL.flush(); + if (gGLManager.mHasShaderObjects) + { + LLVertexBuffer::unbind(); + glUseProgramObjectARB(mProgramObject); + sCurBoundShader = mProgramObject; + sCurBoundShaderPtr = this; + if (mUniformsDirty) + { + LLShaderMgr::instance()->updateShaderUniforms(this); + mUniformsDirty = FALSE; + } + } } void LLGLSLShader::unbind() { - gGL.flush(); - if (gGLManager.mHasShaderObjects) - { - stop_glerror(); - if (gGLManager.mIsNVIDIA) - { - for (U32 i = 0; i < mAttribute.size(); ++i) - { - vertexAttrib4f(i, 0,0,0,1); - stop_glerror(); - } - } - LLVertexBuffer::unbind(); - glUseProgramObjectARB(0); - sCurBoundShader = 0; - sCurBoundShaderPtr = NULL; - stop_glerror(); - } + gGL.flush(); + if (gGLManager.mHasShaderObjects) + { + stop_glerror(); + if (gGLManager.mIsNVIDIA) + { + for (U32 i = 0; i < mAttribute.size(); ++i) + { + vertexAttrib4f(i, 0,0,0,1); + stop_glerror(); + } + } + LLVertexBuffer::unbind(); + glUseProgramObjectARB(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; + stop_glerror(); + } } void LLGLSLShader::bindNoShader(void) { - LLVertexBuffer::unbind(); - if (gGLManager.mHasShaderObjects) - { - glUseProgramObjectARB(0); - sCurBoundShader = 0; - sCurBoundShaderPtr = NULL; - } + LLVertexBuffer::unbind(); + if (gGLManager.mHasShaderObjects) + { + glUseProgramObjectARB(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; + } } S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode) { - S32 channel = 0; - channel = getUniformLocation(uniform); - - return bindTexture(channel, texture, mode); + S32 channel = 0; + channel = getUniformLocation(uniform); + + return bindTexture(channel, texture, mode); } S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - - uniform = mTexture[uniform]; - - if (uniform > -1) - { - gGL.getTexUnit(uniform)->bind(texture, mode); - } - - return uniform; + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; + } + + uniform = mTexture[uniform]; + + if (uniform > -1) + { + gGL.getTexUnit(uniform)->bind(texture, mode); + } + + return uniform; } S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) { - S32 channel = 0; - channel = getUniformLocation(uniform); - - return unbindTexture(channel); + S32 channel = 0; + channel = getUniformLocation(uniform); + + return unbindTexture(channel); } S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - - uniform = mTexture[uniform]; - - if (uniform > -1) - { - gGL.getTexUnit(uniform)->unbind(mode); - } - - return uniform; + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; + } + + uniform = mTexture[uniform]; + + if (uniform > -1) + { + gGL.getTexUnit(uniform)->unbind(mode); + } + + return uniform; } S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - S32 index = mTexture[uniform]; - if (index != -1) - { - gGL.getTexUnit(index)->activate(); - gGL.getTexUnit(index)->enable(mode); - } - return index; + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; + } + S32 index = mTexture[uniform]; + if (index != -1) + { + gGL.getTexUnit(index)->activate(); + gGL.getTexUnit(index)->enable(mode); + } + return index; } S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - S32 index = mTexture[uniform]; - if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE) - { - if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) - { - if (gDebugSession) - { - gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl; - ll_fail("LLGLSLShader::disableTexture failed"); - } - else - { - LL_ERRS() << "Texture channel " << index << " texture type corrupted." << LL_ENDL; - } - } - gGL.getTexUnit(index)->disable(); - } - return index; + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; + } + S32 index = mTexture[uniform]; + if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE) + { + if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) + { + if (gDebugSession) + { + gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl; + ll_fail("LLGLSLShader::disableTexture failed"); + } + else + { + LL_ERRS() << "Texture channel " << index << " texture type corrupted." << LL_ENDL; + } + } + gGL.getTexUnit(index)->disable(); + } + return index; } void LLGLSLShader::uniform1i(U32 index, GLint x) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - if (iter == mValue.end() || iter->second.mV[0] != x) - { - glUniform1iARB(mUniform[index], x); - mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + if (iter == mValue.end() || iter->second.mV[0] != x) + { + glUniform1iARB(mUniform[index], x); + mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); + } + } + } } void LLGLSLShader::uniform1f(U32 index, GLfloat x) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - if (iter == mValue.end() || iter->second.mV[0] != x) - { - glUniform1fARB(mUniform[index], x); - mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + if (iter == mValue.end() || iter->second.mV[0] != x) + { + glUniform1fARB(mUniform[index], x); + mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); + } + } + } } void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(x,y,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform2fARB(mUniform[index], x, y); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(x,y,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform2fARB(mUniform[index], x, y); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(x,y,z,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform3fARB(mUniform[index], x, y, z); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(x,y,z,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform3fARB(mUniform[index], x, y, z); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(x,y,z,w); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform4fARB(mUniform[index], x, y, z, w); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(x,y,z,w); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform4fARB(mUniform[index], x, y, z, w); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform1ivARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform1ivARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform1fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform1fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],v[1],0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform2fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],v[1],0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform2fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],v[1],v[2],0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform3fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],v[1],v[2],0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform3fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],v[1],v[2],v[3]); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform4fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],v[1],v[2],v[3]); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform4fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } } void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - glUniformMatrix2fvARB(mUniform[index], count, transpose, v); - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix2fvARB(mUniform[index], count, transpose, v); + } + } } void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - glUniformMatrix3fvARB(mUniform[index], count, transpose, v); - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix3fvARB(mUniform[index], count, transpose, v); + } + } } void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - glUniformMatrix4fvARB(mUniform[index], count, transpose, v); - } - } + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix4fvARB(mUniform[index], count, transpose, v); + } + } } GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) { - GLint ret = -1; - if (mProgramObject > 0) - { - LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform); - if (iter != mUniformMap.end()) - { - if (gDebugGL) - { - stop_glerror(); - if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str())) - { - LL_ERRS() << "Uniform does not match." << LL_ENDL; - } - stop_glerror(); - } - ret = iter->second; - } - } - - return ret; + GLint ret = -1; + if (mProgramObject > 0) + { + LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform); + if (iter != mUniformMap.end()) + { + if (gDebugGL) + { + stop_glerror(); + if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str())) + { + LL_ERRS() << "Uniform does not match." << LL_ENDL; + } + stop_glerror(); + } + ret = iter->second; + } + } + + return ret; } GLint LLGLSLShader::getUniformLocation(U32 index) { - GLint ret = -1; - if (mProgramObject > 0) - { - llassert(index < mUniform.size()); - return mUniform[index]; - } - - return ret; + GLint ret = -1; + if (mProgramObject > 0) + { + llassert(index < mUniform.size()); + return mUniform[index]; + } + + return ret; } GLint LLGLSLShader::getAttribLocation(U32 attrib) { - if (attrib < mAttribute.size()) - { - return mAttribute[attrib]; - } - else - { - return -1; - } + if (attrib < mAttribute.size()) + { + return mAttribute[attrib]; + } + else + { + return -1; + } } void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(v,0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform1iARB(location, v); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(v,0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform1iARB(location, v); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(i,j,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform2iARB(location, i, j); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(i,j,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform2iARB(location, i, j); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(v,0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform1fARB(location, v); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(v,0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform1fARB(location, v); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(x,y,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform2fARB(location, x,y); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(x,y,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform2fARB(location, x,y); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(x,y,z,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform3fARB(location, x,y,z); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(x,y,z,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform3fARB(location, x,y,z); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(v[0],0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform1fvARB(location, count, v); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(v[0],0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform1fvARB(location, count, v); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(v[0],v[1],0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform2fvARB(location, count, v); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(v[0],v[1],0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform2fvARB(location, count, v); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - LLVector4 vec(v[0],v[1],v[2],0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform3fvARB(location, count, v); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + LLVector4 vec(v[0],v[1],v[2],0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform3fvARB(location, count, v); + mValue[location] = vec; + } + } } void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - LLVector4 vec(v); - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - stop_glerror(); - glUniform4fvARB(location, count, v); - stop_glerror(); - mValue[location] = vec; - } - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + LLVector4 vec(v); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + stop_glerror(); + glUniform4fvARB(location, count, v); + stop_glerror(); + mValue[location] = vec; + } + } } void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v) { - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - stop_glerror(); - glUniformMatrix4fvARB(location, count, transpose, v); - stop_glerror(); - } + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + stop_glerror(); + glUniformMatrix4fvARB(location, count, transpose, v); + stop_glerror(); + } } void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - if (mAttribute[index] > 0) - { - glVertexAttrib4fARB(mAttribute[index], x, y, z, w); - } + if (mAttribute[index] > 0) + { + glVertexAttrib4fARB(mAttribute[index], x, y, z, w); + } } void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v) { - if (mAttribute[index] > 0) - { - glVertexAttrib4fvARB(mAttribute[index], v); - } + if (mAttribute[index] > 0) + { + glVertexAttrib4fvARB(mAttribute[index], v); + } } void LLGLSLShader::setMinimumAlpha(F32 minimum) { - gGL.flush(); - uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum); + gGL.flush(); + uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum); } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index a89ec675b4..b2be3cc3b6 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -674,12 +674,17 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (defines) { for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter) - { - std::string define = "#define " + iter->first + " " + iter->second + "\n"; - text[count++] = (GLcharARB *) strdup(define.c_str()); - } + { + std::string define = "#define " + iter->first + " " + iter->second + "\n"; + text[count++] = (GLcharARB *) strdup(define.c_str()); + } } + if( gGLManager.mIsATI ) + { + text[ count++ ] = strdup( "#define IS_AMD_CARD 1\n" ); + } + if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB) { //use specified number of texture channels for indexed texture rendering diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index d06564df36..0fae600a90 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -843,9 +843,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS); stop_glerror(); - LLGLSLShader::startProfile(); + LLGLSLShader::startProfile(); + stop_glerror(); glDrawArrays(sGLMode[mode], first, count); - LLGLSLShader::stopProfile(count, mode); + stop_glerror(); + LLGLSLShader::stopProfile(count, mode); } stop_glerror(); diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index f1fab3b2c6..072d40f739 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -79,6 +79,7 @@ @interface LLNonInlineTextView : NSTextView { LLOpenGLView *glview; + unichar mKeyPressed; } - (void) setGLView:(LLOpenGLView*)view; diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index f7031341eb..ff312945b6 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -104,20 +104,20 @@ attributedStringInfo getSegments(NSAttributedString *str) - (unsigned long)getVramSize { CGLRendererInfoObj info = 0; - GLint vram_bytes = 0; + GLint vram_mbytes = 0; int num_renderers = 0; CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers); if(0 == the_err) { - CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes); + CGLDescribeRenderer (info, 0, kCGLRPTextureMemoryMegabytes, &vram_mbytes); CGLDestroyRendererInfo (info); } else { - vram_bytes = (256 << 20); + vram_mbytes = 256; } - return (unsigned long)vram_bytes / 1048576; // We need this in megabytes. + return (unsigned long)vram_mbytes; } - (void)viewDidMoveToWindow @@ -270,14 +270,14 @@ attributedStringInfo getSegments(NSAttributedString *str) !([theEvent modifierFlags] & NSFunctionKeyMask) && !([theEvent modifierFlags] & NSHelpKeyMask)) { - callRightMouseDown(mMousePos, mModifiers); + callRightMouseDown(mMousePos, [theEvent modifierFlags]); mSimulatedRightClick = true; } else { if ([theEvent clickCount] >= 2) { - callDoubleClick(mMousePos, mModifiers); + callDoubleClick(mMousePos, [theEvent modifierFlags]); } else if ([theEvent clickCount] == 1) { - callLeftMouseDown(mMousePos, mModifiers); + callLeftMouseDown(mMousePos, [theEvent modifierFlags]); } } } @@ -286,21 +286,21 @@ attributedStringInfo getSegments(NSAttributedString *str) { if (mSimulatedRightClick) { - callRightMouseUp(mMousePos, mModifiers); + callRightMouseUp(mMousePos, [theEvent modifierFlags]); mSimulatedRightClick = false; } else { - callLeftMouseUp(mMousePos, mModifiers); + callLeftMouseUp(mMousePos, [theEvent modifierFlags]); } } - (void) rightMouseDown:(NSEvent *)theEvent { - callRightMouseDown(mMousePos, mModifiers); + callRightMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) rightMouseUp:(NSEvent *)theEvent { - callRightMouseUp(mMousePos, mModifiers); + callRightMouseUp(mMousePos, [theEvent modifierFlags]); } - (void)mouseMoved:(NSEvent *)theEvent @@ -341,12 +341,12 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) otherMouseDown:(NSEvent *)theEvent { - callMiddleMouseDown(mMousePos, mModifiers); + callMiddleMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) otherMouseUp:(NSEvent *)theEvent { - callMiddleMouseUp(mMousePos, mModifiers); + callMiddleMouseUp(mMousePos, [theEvent modifierFlags]); } - (void) otherMouseDragged:(NSEvent *)theEvent @@ -366,22 +366,27 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) keyUp:(NSEvent *)theEvent { - callKeyUp([theEvent keyCode], mModifiers); + callKeyUp([theEvent keyCode], [theEvent modifierFlags]); } - (void) keyDown:(NSEvent *)theEvent { uint keycode = [theEvent keyCode]; + // We must not depend on flagsChange event to detect modifier flags changed, + // must depend on the modifire flags in the event parameter. + // Because flagsChange event handler misses event when other window is activated, + // e.g. OS Window for upload something or Input Window... + // mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit) + mModifiers = [theEvent modifierFlags]; bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers); + unichar ch; if (acceptsText && !mMarkedTextAllowed && + !(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow ![(LLAppDelegate*)[NSApp delegate] romanScript] && - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter && - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter && - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey && - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey && - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey && - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey) + (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' && + ch != NSDeleteCharacter && + (ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h) { [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent]; } else @@ -498,31 +503,58 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { - if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString")) + // Apple says aString can be either an NSString or NSAttributedString instance. + // But actually it's NSConcreteMutableAttributedString or __NSCFConstantString. + // I observed aString was __NSCFConstantString only aString was null string(zero length). + // Apple also says when aString is an NSString object, + // the receiver is expected to render the marked text with distinguishing appearance. + // So I tried to make attributedStringInfo, but it won't be used... (Pell Smit) + + if (mMarkedTextAllowed) { - if (mMarkedTextAllowed) + unsigned int selected[2] = { + selectedRange.location, + selectedRange.length + }; + + unsigned int replacement[2] = { + replacementRange.location, + replacementRange.length + }; + + int string_length = [aString length]; + unichar text[string_length]; + attributedStringInfo segments; + // I used 'respondsToSelector:@selector(string)' + // to judge aString is an attributed string or not. + if ([aString respondsToSelector:@selector(string)]) + { + // aString is attibuted + [[aString string] getCharacters:text range:NSMakeRange(0, string_length)]; + segments = getSegments((NSAttributedString *)aString); + } + else + { + // aString is not attributed + [aString getCharacters:text range:NSMakeRange(0, string_length)]; + segments.seg_lengths.push_back(string_length); + segments.seg_standouts.push_back(true); + } + setMarkedText(text, selected, replacement, string_length, segments); + if (string_length > 0) { - unsigned int selected[2] = { - selectedRange.location, - selectedRange.length - }; - - unsigned int replacement[2] = { - replacementRange.location, - replacementRange.length - }; - - unichar text[[aString length]]; - [[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])]; - attributedStringInfo segments = getSegments((NSAttributedString *)aString); - setMarkedText(text, selected, replacement, [aString length], segments); mHasMarkedText = TRUE; - mMarkedTextLength = [aString length]; - } else { - if (mHasMarkedText) - { - [self unmarkText]; - } + mMarkedTextLength = string_length; + } + else + { + // we must clear the marked text when aString is null. + [self unmarkText]; + } + } else { + if (mHasMarkedText) + { + [self unmarkText]; } } } @@ -641,37 +673,63 @@ attributedStringInfo getSegments(NSAttributedString *str) @implementation LLNonInlineTextView +/* Input Window is a legacy of 20 century, so we want to remove related classes. + But unfortunately, Viwer web browser has no support for modern inline input, + we need to leave these classes... + We will be back to get rid of Input Window after fixing viewer web browser. + + How Input Window should work: + 1) Input Window must not be empty. + It must close when it become empty result of edithing. + 2) Input Window must not close when it still has input data. + It must keep open user types next char before commit. by Pell Smit +*/ + - (void) setGLView:(LLOpenGLView *)view { glview = view; } -- (void) insertText:(id)insertString +- (void)keyDown:(NSEvent *)theEvent { - [[self inputContext] discardMarkedText]; - [self setString:@""]; - [_window orderOut:_window]; - [self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])]; + // mKeyPressed is used later to determine whethere Input Window should close or not + mKeyPressed = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; + // setMarkedText and insertText is called indirectly from inside keyDown: method + [super keyDown:theEvent]; } -- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange +// setMarkedText: is called for incomplete input(on the way to conversion). +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { - [glview insertText:aString replacementRange:replacementRange]; + [super setMarkedText:aString selectedRange:selectedRange replacementRange:replacementRange]; + if ([aString length] == 0) // this means Input Widow becomes empty + { + [_window orderOut:_window]; // Close this to avoid empty Input Window + } } -- (void) insertNewline:(id)sender +// insertText: is called for inserting commited text. +// There are two ways to be called here: +// a) explicitly commited (must close) +// In case of user typed commit key(usually return key) or delete key or something +// b) automatically commited (must not close) +// In case of user typed next letter after conversion +- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange { - [[self textStorage] setValue:@""]; - [[self inputContext] discardMarkedText]; + [[self inputContext] discardMarkedText]; [self setString:@""]; -} - -- (void)doCommandBySelector:(SEL)aSelector -{ - if (aSelector == @selector(insertNewline:)) - { - [self insertNewline:self]; - } + [glview insertText:aString replacementRange:replacementRange]; + if (mKeyPressed == NSEnterCharacter || + mKeyPressed == NSBackspaceCharacter || + mKeyPressed == NSTabCharacter || + mKeyPressed == NSNewlineCharacter || + mKeyPressed == NSCarriageReturnCharacter || + mKeyPressed == NSDeleteCharacter || + (mKeyPressed >= 0xF700 && mKeyPressed <= 0xF8FF)) + { + // this is case a) of above comment + [_window orderOut:_window]; // to avoid empty Input Window + } } @end diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 18d5152015..aca8bb6527 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -230,7 +230,10 @@ void callFocus() void callFocusLost() { - gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + if (gWindowImplementation) + { + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + } } void callRightMouseDown(float *pos, MASK mask) @@ -1805,8 +1808,6 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key) void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { - allowDirectMarkedTextInput(b, mGLView); - if (preeditor != mPreeditor && !b) { // This condition may occur by a call to @@ -1836,6 +1837,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) return; } mLanguageTextInputAllowed = b; + allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit } void LLWindowMacOSX::interruptLanguageTextInput() diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index c6cff55cf7..a4de059bbc 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.21 +3.7.23 diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index bc63d07d72..767fad016c 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -40,4 +40,10 @@ mat4 getSkinnedTransform() ret[3] = vec4(0,0,0,1); return ret; + +#ifdef IS_AMD_CARD + // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. + vec4 dummy1 = matrixPalette[0]; + vec4 dummy2 = matrixPalette[44]; +#endif } diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 57129c3bd1..6cd38d8ef5 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -63,5 +63,14 @@ mat4 getObjectSkinnedTransform() ret[3] = vec4(trans, 1.0); return ret; + +#ifdef IS_AMD_CARD + // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. + mat3 dummy1 = matrixPalette[0]; + vec3 dummy2 = translationPalette[0]; + mat3 dummy3 = matrixPalette[51]; + vec3 dummy4 = translationPalette[51]; +#endif + } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index a4f54dff70..5264d6e1b4 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -132,5 +132,11 @@ void main() col.y *= col.y; frag_color = col; + +#ifdef IS_AMD_CARD + // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. + vec3 dummy1 = kern[0]; + vec3 dummy2 = kern[3]; +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 236567219b..1a464fec5d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -161,4 +161,12 @@ void main() frag_color.rgb = out_col; frag_color.a = 0.0; + +#ifdef IS_AMD_CARD + // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. + vec4 dummy1 = light[0]; + vec4 dummy2 = light_col[0]; + vec4 dummy3 = light[LIGHT_COUNT-1]; + vec4 dummy4 = light_col[LIGHT_COUNT-1]; +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 0e6ab80d4d..c08e9d361a 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -127,13 +127,17 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) vec4 ret = texture2DLod(projectionMap, tc, lod); ret.rgb = srgb_to_linear(ret.rgb); - vec2 dist = tc-vec2(0.5); + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); - float det = max(1.0-lod/(proj_lod*0.5), 0.0); + float det = min(lod/(proj_lod*0.5), 1.0); - float d = dot(dist,dist); - - ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + float d = min(dist.x, dist.y); + + d *= min(1, d * (proj_lod - lod)); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); return ret; } @@ -311,19 +315,17 @@ void main() vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - stc /= stc.w; + if (stc.z > 0.0) { - float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0); - - stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + stc /= stc.w; if (stc.x < 1.0 && stc.y < 1.0 && stc.x > 0.0 && stc.y > 0.0) { - col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb; + col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity; } } } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 96f9628424..018ced4cad 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -99,4 +99,10 @@ void main() col = col*col*blur_quad.x + col*blur_quad.y + blur_quad.z; frag_color.rgb = col; + +#ifdef IS_AMD_CARD + // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. + vec2 dummy1 = kern[0]; + vec2 dummy2 = kern[31]; +#endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 8d8a6c9dde..f50635a139 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -130,15 +130,19 @@ vec4 correctWithGamma(vec4 col) vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); + ret.rgb = srgb_to_linear(ret.rgb); - vec2 dist = tc-vec2(0.5); + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); - float det = max(1.0-lod/(proj_lod*0.5), 0.0); + float det = min(lod/(proj_lod*0.5), 1.0); - float d = dot(dist,dist); - - ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + float d = min(dist.x, dist.y); + + d *= min(1, d * (proj_lod - lod)); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); return ret; } @@ -322,19 +326,14 @@ void main() if (stc.z > 0.0) { - stc.xy /= stc.w; - - float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); - - //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); - stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + stc /= stc.w; if (stc.x < 1.0 && stc.y < 1.0 && stc.x > 0.0 && stc.y > 0.0) { - col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb; + col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity; } } } diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index c20e00163c..94bd07bec6 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -131,15 +131,19 @@ vec4 correctWithGamma(vec4 col) vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); - - vec2 dist = tc-vec2(0.5); + ret.rgb = srgb_to_linear(ret.rgb); - float det = max(1.0-lod/(proj_lod*0.5), 0.0); + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); - float d = dot(dist,dist); - - ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); + + d *= min(1, d * (proj_lod - lod)); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); return ret; } @@ -334,25 +338,21 @@ void main() vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - stc /= stc.w; if (stc.z > 0.0) { - float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0); - - stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + stc /= stc.w; if (stc.x < 1.0 && stc.y < 1.0 && stc.x > 0.0 && stc.y > 0.0) { - col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb; + col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; } } } } - //not sure why, but this line prevents MATBUG-194 col = max(col, vec3(0.0)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 7689b72d20..92e1ac95a6 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -131,15 +131,19 @@ vec4 correctWithGamma(vec4 col) vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); + ret.rgb = srgb_to_linear(ret.rgb); - vec2 dist = tc-vec2(0.5); + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); - float det = max(1.0-lod/(proj_lod*0.5), 0.0); + float det = min(lod/(proj_lod*0.5), 1.0); - float d = dot(dist,dist); - - ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + float d = min(dist.x, dist.y); + + d *= min(1, d * (proj_lod - lod)); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); return ret; } @@ -336,19 +340,14 @@ void main() if (stc.z > 0.0) { - stc.xy /= stc.w; - - float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); - - //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); - stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + stc /= stc.w; if (stc.x < 1.0 && stc.y < 1.0 && stc.x > 0.0 && stc.y > 0.0) { - col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb; + col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; } } } diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 988058aad3..aad5dbae7d 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -84,7 +84,7 @@ callWindowUnfocus(); } -- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender +- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender { if (!runMainLoop()) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 90e6dfe351..e7420f32f0 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1626,7 +1626,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { F32 w = weight[j][k]; - idx[k] = llclamp((S32) floorf(w), 0, 63); + idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1); + wght[k] = w - floorf(w); scale += wght[k]; } diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 4db0422634..d89599cb45 100755 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -76,9 +76,6 @@ const char FEATURE_TABLE_FILENAME[] = "featuretable%s.txt"; const char FEATURE_TABLE_VER_FILENAME[] = "featuretable%s.%s.txt"; #endif -const char GPU_TABLE_FILENAME[] = "gpu_table.txt"; -const char GPU_TABLE_VER_FILENAME[] = "gpu_table.%s.txt"; - LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level) : mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level) { @@ -428,6 +425,7 @@ bool LLFeatureManager::loadGPUClass() { //couldn't bench, use GLVersion #if LL_DARWIN //GLVersion is misleading on OSX, just default to class 3 if we can't bench + LL_WARNS() << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; mGPUClass = GPU_CLASS_3; #else if (gGLManager.mGLVersion < 2.f) @@ -452,23 +450,31 @@ bool LLFeatureManager::loadGPUClass() } #endif } - else if (gbps < 5.f) + else if (gGLManager.mGLVersion <= 2.f) + { + mGPUClass = GPU_CLASS_0; + } + else if (gGLManager.mGLVersion <= 3.f) + { + mGPUClass = GPU_CLASS_1; + } + else if (gbps <= 5.f) { mGPUClass = GPU_CLASS_0; } - else if (gbps < 10.f) + else if (gbps <= 8.f) { mGPUClass = GPU_CLASS_1; } - else if (gbps < 20.f) + else if (gbps <= 16.f) { mGPUClass = GPU_CLASS_2; } - else if (gbps < 40.f) + else if (gbps <= 40.f) { mGPUClass = GPU_CLASS_3; } - else if (gbps < 80.f) + else if (gbps <= 80.f) { mGPUClass = GPU_CLASS_4; } @@ -476,195 +482,15 @@ bool LLFeatureManager::loadGPUClass() { mGPUClass = GPU_CLASS_5; } - + // defaults mGPUString = gGLManager.getRawGLString(); mGPUSupported = TRUE; -#if 0 - // first table is in the app dir - std::string app_path = gDirUtilp->getAppRODataDir(); - app_path += gDirUtilp->getDirDelimiter(); - app_path += GPU_TABLE_FILENAME; - - // second table is downloaded with HTTP - std::string http_filename = llformat(GPU_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str()); - std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename); - - // use HTTP table if it exists - std::string path; - bool parse_ok = false; - if (gDirUtilp->fileExists(http_path)) - { - parse_ok = parseGPUTable(http_path); - if (!parse_ok) - { - // the HTTP table failed to parse, so delete it - LLFile::remove(http_path); - LL_WARNS("RenderInit") << "Removed invalid gpu table '" << http_path << "'" << LL_ENDL; - } - } - - if (!parse_ok) - { - parse_ok = parseGPUTable(app_path); - } -#endif - return true; // indicates that the file parsed correctly, not that the gpu was recognized + return true; // indicates that a gpu value was established } -bool LLFeatureManager::parseGPUTable(std::string filename) -{ - llifstream file; - - LL_INFOS("RenderInit") << "Attempting to parse GPU table from " << filename << LL_ENDL; - file.open(filename); - - if (file) - { - const char recognizer[] = "//GPU_TABLE"; - char first_line[MAX_STRING]; - file.getline(first_line, MAX_STRING); - if (0 != strncmp(first_line, recognizer, strlen(recognizer))) - { - LL_WARNS("RenderInit") << "Invalid GPU table: " << filename << "!" << LL_ENDL; - return false; - } - } - else - { - LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL; - return false; - } - - std::string rawRenderer = gGLManager.getRawGLString(); - std::string renderer = rawRenderer; - for (std::string::iterator i = renderer.begin(); i != renderer.end(); ++i) - { - *i = tolower(*i); - } - -#if LL_EXPORT_GPU_TABLE - llofstream json; - json.open("gpu_table.json"); - - json << "var gpu_table = [" << std::endl; -#endif - - bool gpuFound; - U32 lineNumber; - for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++) - { - char buffer[MAX_STRING]; /*Flawfinder: ignore*/ - buffer[0] = 0; - - file.getline(buffer, MAX_STRING); - - if (strlen(buffer) >= 2 && /*Flawfinder: ignore*/ - buffer[0] == '/' && - buffer[1] == '/') - { - // This is a comment. - continue; - } - - if (strlen(buffer) == 0) /*Flawfinder: ignore*/ - { - // This is a blank line - continue; - } - - // setup the tokenizer - std::string buf(buffer); - std::string cls, label, expr, supported, stats_based, expected_gl_version; - boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n")); - boost_tokenizer::iterator token_iter = tokens.begin(); - - // grab the label, pseudo regular expression, and class - if(token_iter != tokens.end()) - { - label = *token_iter++; - } - if(token_iter != tokens.end()) - { - expr = *token_iter++; - } - if(token_iter != tokens.end()) - { - cls = *token_iter++; - } - if(token_iter != tokens.end()) - { - supported = *token_iter++; - } - if (token_iter != tokens.end()) - { - stats_based = *token_iter++; - } - if (token_iter != tokens.end()) - { - expected_gl_version = *token_iter++; - } - - if (label.empty() || expr.empty() || cls.empty() || supported.empty()) - { - LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL; - continue; - } -#if LL_EXPORT_GPU_TABLE - json << "{'label' : '" << label << "',\n" << - "'regexp' : '" << expr << "',\n" << - "'class' : '" << cls << "',\n" << - "'supported' : '" << supported << "',\n" << - "'stats_based' : " << stats_based << ",\n" << - "'gl_version' : " << expected_gl_version << "\n},\n"; -#endif - - for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/ - { - expr[i] = tolower(expr[i]); - } - - // run the regular expression against the renderer - boost::regex re(expr.c_str()); - if(boost::regex_search(renderer, re)) - { - // if we found it, stop! -#if !LL_EXPORT_GPU_TABLE - gpuFound = true; -#endif - mGPUString = label; - mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10); - mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10); - sscanf(expected_gl_version.c_str(), "%f", &mExpectedGLVersion); - } - } -#if LL_EXPORT_GPU_TABLE - json << "];\n\n"; - json.close(); -#endif - file.close(); - - if ( gpuFound ) - { - LL_INFOS("RenderInit") << "GPU '" << rawRenderer << "' recognized as '" << mGPUString << "'" << LL_ENDL; - if (!mGPUSupported) - { - LL_INFOS("RenderInit") << "GPU '" << mGPUString << "' is not supported." << LL_ENDL; - } - } - else - { - LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL; - } - -#if LL_DARWIN // never go over "Mid" settings by default on OS X - mGPUClass = llmin(mGPUClass, GPU_CLASS_2); -#endif - return true; -} - // responder saves table into file class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder { @@ -745,26 +571,11 @@ void fetch_feature_table(std::string table) LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path)); } -void fetch_gpu_table(std::string table) -{ - const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable"); - - const std::string filename = llformat(table.c_str(), LLVersionInfo::getVersion().c_str()); - - const std::string url = base + "/" + filename; - - const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); - - LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL; - - LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path)); -} // fetch table(s) from a website (S3) void LLFeatureManager::fetchHTTPTables() { fetch_feature_table(FEATURE_TABLE_VER_FILENAME); - fetch_gpu_table(GPU_TABLE_VER_FILENAME); } diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index 95141b241d..69078ccc21 100755 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -162,9 +162,6 @@ protected: bool parseFeatureTable(std::string filename); ///< @returns TRUE is file parsed correctly, FALSE if not - bool parseGPUTable(std::string filename); - ///< @returns true if file parsed correctly, false if not - does not reflect whether or not the gpu was recognized - void initBaseMask(); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 5debf71744..ef50594feb 100755 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -600,6 +600,9 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) // allowedv->push_back("slg"); break; #endif + case FFLOAD_XML: + allowedv->push_back("xml"); + break; case FFLOAD_RAW: allowedv->push_back("raw"); break; @@ -702,7 +705,14 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena creator = "\?\?\?\?"; extension = "slg"; break; -#endif +#endif + + case FFSAVE_XML: + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "xml"; + break; + case FFSAVE_RAW: type = "\?\?\?\?"; creator = "\?\?\?\?"; @@ -1100,6 +1110,12 @@ static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) return filtername; } +static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml", + LLTrans::getString("xml_files") + " (*.xml)"); +} + static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) { return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", @@ -1293,6 +1309,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) case FFLOAD_ANIM: filtername = add_anim_filter_to_gtkchooser(picker); break; + case FFLOAD_XML: + filtername = add_xml_filter_to_gtkchooser(picker); + break; case FFLOAD_COLLADA: filtername = add_collada_filter_to_gtkchooser(picker); break; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 4b8ac2b3cf..64f796e1fd 100755 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -881,13 +881,14 @@ void LLViewerObjectList::renderObjectBeacons() F32 gpu_benchmark() { - if (!gGLManager.mHasShaderObjects) - { //don't bother benchmarking the fixed function + if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery) + { // don't bother benchmarking the fixed function + // or venerable drivers which don't support accurate timing anyway + // and are likely to be correctly identified by the GPU table already. return -1.f; } - - if (gBenchmarkProgram.mProgramObject == 0) + if (gBenchmarkProgram.mProgramObject == 0) { LLViewerShaderMgr::instance()->initAttribsAndUniforms(); @@ -920,7 +921,10 @@ F32 gpu_benchmark() //number of samples to take const S32 samples = 64; - LLGLSLShader::initProfile(); + if (gGLManager.mHasTimerQuery) + { + LLGLSLShader::initProfile(); + } LLRenderTarget dest[count]; U32 source[count]; @@ -964,16 +968,16 @@ F32 gpu_benchmark() v[0].set(-1,1,0); v[1].set(-1,-3,0); v[2].set(3,1,0); + buff->flush(); gBenchmarkProgram.bind(); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - - //wait for any previoius GL commands to finish - glFinish(); bool busted_finish = false; + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + glFinish(); + for (S32 c = -1; c < samples; ++c) { LLTimer timer; @@ -1013,6 +1017,7 @@ F32 gpu_benchmark() if (!gGLManager.mHasTimerQuery && !busted_finish && gbps > 128.f) { //unrealistically high bandwidth for a card without timer queries, glFinish is probably ignored busted_finish = true; + LL_WARNS() << "GPU Benchmark detected GL driver with broken glFinish implementation." << LL_ENDL; } else { @@ -1023,10 +1028,12 @@ F32 gpu_benchmark() gBenchmarkProgram.unbind(); - LLGLSLShader::finishProfile(false); - - LLImageGL::deleteTextures(count, source); + if (gGLManager.mHasTimerQuery) + { + LLGLSLShader::finishProfile(false); + } + LLImageGL::deleteTextures(count, source); std::sort(results.begin(), results.end()); @@ -1037,27 +1044,20 @@ F32 gpu_benchmark() #if LL_DARWIN if (gbps > 512.f) { - LL_INFOS() << "Memory bandwidth is improbably high and likely incorrect." << LL_ENDL; + LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL; //OSX is probably lying, discard result gbps = -1.f; } #endif - if (gGLManager.mHasTimerQuery) - { - F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; - F32 seconds = ms/1000.f; + F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; + F32 seconds = ms/1000.f; - F64 samples_drawn = res*res*count*samples; - F32 samples_sec = (samples_drawn/1000000000.0)/seconds; - gbps = samples_sec*8; + F64 samples_drawn = res*res*count*samples; + F32 samples_sec = (samples_drawn/1000000000.0)/seconds; + gbps = samples_sec*8; - LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL; - } - else - { - LL_INFOS() << "ARB_timer_query unavailable." << LL_ENDL; - } + LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL; return gbps; } diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 7861573908..b2350e5a75 100755 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1240,10 +1240,10 @@ LLQuaternion LLManipRotate::dragUnconstrained( S32 x, S32 y ) F32 dist_from_sphere_center = sqrt(delta_x * delta_x + delta_y * delta_y); LLVector3 axis = mMouseDown % mMouseCur; + F32 angle = atan2(sqrtf(axis * axis), mMouseDown * mMouseCur); axis.normVec(); - F32 angle = acos(mMouseDown * mMouseCur); LLQuaternion sphere_rot( angle, axis ); - + if (is_approx_zero(1.f - mMouseDown * mMouseCur)) { return LLQuaternion::DEFAULT; @@ -1638,9 +1638,9 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) mInSnapRegime = FALSE; } - angle = acos(mMouseCur * mMouseDown); - - F32 dir = (mMouseDown % mMouseCur) * constraint_axis; // cross product + LLVector3 cross_product = mMouseDown % mMouseCur; + angle = atan2(sqrtf(cross_product * cross_product), mMouseCur * mMouseDown); + F32 dir = cross_product * constraint_axis; // cross product if( dir < 0.f ) { angle *= -1.f; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 22b979aa09..3f94074ab3 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -464,7 +464,10 @@ public: mCharacter = character; BOOL success = true; - if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) { success = false; } + if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) + { + success = false; + } if ( success ) { @@ -819,14 +822,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c //------------------------------------------------------------------------ LLVOAvatar::~LLVOAvatar() { - if (!mFullyLoaded) - { + if (!mFullyLoaded) + { debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); - } - else - { + } + else + { debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); - } + } logPendingPhases(); @@ -980,10 +983,11 @@ void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) iter != LLCharacter::sInstances.end(); ++iter) { LLVOAvatar* inst = (LLVOAvatar*) *iter; - if (!inst) - continue; - S32 rez_status = inst->getRezzedStatus(); - counts[rez_status]++; + if (inst) + { + S32 rez_status = inst->getRezzedStatus(); + counts[rez_status]++; + } } } @@ -1353,38 +1357,36 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { LLViewerJointAttachment* attachment = iter->second; - if (!attachment->getValid()) - { - continue ; - } - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + if (attachment->getValid()) { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLDrawable* drawable = attached_object->mDrawable; - if (drawable && !drawable->isState(LLDrawable::RIGGED)) + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) { - LLSpatialBridge* bridge = drawable->getSpatialBridge(); - if (bridge) + LLDrawable* drawable = attached_object->mDrawable; + if (drawable && !drawable->isState(LLDrawable::RIGGED)) { - const LLVector4a* ext = bridge->getSpatialExtents(); - LLVector4a distance; - distance.setSub(ext[1], ext[0]); - LLVector4a max_span(max_attachment_span); + LLSpatialBridge* bridge = drawable->getSpatialBridge(); + if (bridge) + { + const LLVector4a* ext = bridge->getSpatialExtents(); + LLVector4a distance; + distance.setSub(ext[1], ext[0]); + LLVector4a max_span(max_attachment_span); - S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; + S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; - // Only add the prim to spatial extents calculations if it isn't a megaprim. - // max_attachment_span calculated at the start of the function - // (currently 5 times our max prim size) - if (lt == 0x7) - { - update_min_max(newMin,newMax,ext[0]); - update_min_max(newMin,newMax,ext[1]); + // Only add the prim to spatial extents calculations if it isn't a megaprim. + // max_attachment_span calculated at the start of the function + // (currently 5 times our max prim size) + if (lt == 0x7) + { + update_min_max(newMin,newMax,ext[0]); + update_min_max(newMin,newMax,ext[1]); + } } } } @@ -1961,7 +1963,7 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, if (has_name && getNVPair("FirstName")) { mDebugExistenceTimer.reset(); - debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); + debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); } if(retval & LLViewerObject::INVALID_UPDATE) @@ -1973,9 +1975,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, } } - //LL_INFOS() << getRotation() << LL_ENDL; - //LL_INFOS() << getPosition() << LL_ENDL; - return retval; } @@ -1991,7 +1990,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU result = gTextureList.findImage(uuid); } if (!result) -{ + { const std::string url = getImageURL(te,uuid); if (url.empty()) @@ -3335,7 +3334,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) removeAnimationData("Walk Speed"); } mMotionController.setTimeStep(time_step); -// LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL; + // LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL; } if (getParent() && !mIsSitting) @@ -3476,7 +3475,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) fwdDir.normalize(); } } - } LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); @@ -3592,10 +3590,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // update animations if (mSpecialRenderMode == 1) // Animation Preview + { updateMotions(LLCharacter::FORCE_UPDATE); + } else + { updateMotions(LLCharacter::NORMAL_UPDATE); - + } + // update head position updateHeadOffset(); @@ -3692,10 +3694,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) //mesh vertices need to be reskinned mNeedsSkin = TRUE; - - - - return TRUE; } //----------------------------------------------------------------------------- @@ -3975,13 +3973,13 @@ U32 LLVOAvatar::renderSkinned() if (face) { LLVertexBuffer* vb = face->getVertexBuffer(); - if (vb) - { - vb->flush(); + if (vb) + { + vb->flush(); + } } } } - } else { mNeedsSkin = FALSE; @@ -4161,7 +4159,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) { LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); if (hair_mesh) - { + { num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); } first_pass = FALSE; @@ -5213,8 +5211,8 @@ BOOL LLVOAvatar::loadSkeletonNode () { if (!LLAvatarAppearance::loadSkeletonNode()) { - return FALSE; - } + return FALSE; + } // ATTACHMENTS { @@ -5965,27 +5963,24 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const break; // Do nothing } - /* switch(type) - case LLWearableType::WT_SHIRT: - indicator_te = TEX_UPPER_SHIRT; */ for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin(); tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end(); ++tex_iter) { const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second; if (texture_dict->mWearableType == type) - { + { // Thus, you must check to see if the corresponding baked texture is defined. // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that // gets baked into a texture that always exists (upper or lower). if (texture_dict->mIsUsedByBakedTexture) - { + { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); - } + } return FALSE; - } + } } return FALSE; } @@ -6055,7 +6050,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color) } else if (global_color == mTexEyeColor) { -// LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL; + // LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL; invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet); } updateMeshTextures(); @@ -6115,9 +6110,9 @@ void LLVOAvatar::updateRezzedStatusTimers() { // load level has decreased. start phase timers for higher load levels. for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) - { + { startPhase("load_" + LLVOAvatar::rezStatusToString(i)); - } + } } else if (rez_status > mLastRezzedStatus) { @@ -6126,16 +6121,15 @@ void LLVOAvatar::updateRezzedStatusTimers() { stopPhase("load_" + LLVOAvatar::rezStatusToString(i)); stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); - } + } if (rez_status == 3) - { + { // "fully loaded", mark any pending appearance change complete. selfStopPhase("update_appearance_from_cof"); selfStopPhase("wear_inventory_category", false); selfStopPhase("process_initial_wearables_update", false); } } - mLastRezzedStatus = rez_status; } } @@ -6197,7 +6191,7 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check) void LLVOAvatar::logPendingPhases() { if (!isAgentAvatarValid()) - { + { return; } @@ -6213,14 +6207,14 @@ void LLVOAvatar::logPendingPhases() if (!completed) { logMetricsTimerRecord(phase_name, elapsed, completed); - } + } } } - } +} //static void LLVOAvatar::logPendingPhasesAllAvatars() - { +{ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { @@ -6231,14 +6225,14 @@ void LLVOAvatar::logPendingPhasesAllAvatars() } inst->logPendingPhases(); } - } +} void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) - { +{ if (!isAgentAvatarValid()) - { + { return; - } + } LLSD record; record["timer_name"] = phase_name; @@ -6247,10 +6241,10 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse record["completed"] = completed; U32 grid_x(0), grid_y(0); if (getRegion()) - { + { record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); - } + } record["grid_x"] = LLSD::Integer(grid_x); record["grid_y"] = LLSD::Integer(grid_y); record["is_using_server_bakes"] = true; @@ -6311,8 +6305,8 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); - if (!mPreviousFullyLoaded && !loading && mFullyLoaded) - { + if (!mPreviousFullyLoaded && !loading && mFullyLoaded) + { debugAvatarRezTime("AvatarRezNotification","fully loaded"); } @@ -6368,9 +6362,7 @@ void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) LLAvatarJointMesh* mesh = (*iter); if (mesh) { - { - mesh->setColor(color); - } + mesh->setColor(color); } } } @@ -6470,7 +6462,7 @@ void LLVOAvatar::updateMeshTextures() LLViewerTexLayerSet* layerset = getTexLayerSet(i); if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) - { + { LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID); mBakedTextureDatas[i].mIsUsed = TRUE; @@ -6479,12 +6471,12 @@ void LLVOAvatar::updateMeshTextures() avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); for (; iter != end; ++iter) - { + { LLAvatarJointMesh* mesh = (*iter); if (mesh) - { + { mesh->setTexture( baked_img ); - } + } } } else if (!isUsingLocalAppearance() && is_layer_baked[i]) @@ -6513,9 +6505,9 @@ void LLVOAvatar::updateMeshTextures() baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ), src_callback_list, paused ); - // this could add paused texture callbacks - mLoadedCallbacksPaused |= paused; - checkTextureLoading(); + // this could add paused texture callbacks + mLoadedCallbacksPaused |= paused; + checkTextureLoading(); } } else if (layerset && isUsingLocalAppearance()) @@ -6534,7 +6526,7 @@ void LLVOAvatar::updateMeshTextures() if (mesh) { mesh->setLayerSet( layerset ); - } + } } } else @@ -6556,7 +6548,7 @@ void LLVOAvatar::updateMeshTextures() { LLAvatarJointMesh* mesh = (*iter); if (mesh) - { + { mesh->setColor( color ); mesh->setTexture( hair_img ); } @@ -6652,13 +6644,13 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin(); iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) -{ + { const LLMaskedMorph* maskedMorph = (*iter); LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget); if (morph_target) - { + { morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); -} + } } } @@ -6957,9 +6949,9 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, outfile.open(fullpath, LL_APR_WB ); apr_file_t* file = outfile.getFileHandle(); if (!file) - { - return; - } + { + return; + } else { LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL; @@ -6994,7 +6986,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str()); } apr_file_printf(file, "</textures>\n"); - } +} void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents) { @@ -7523,12 +7515,12 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin(); avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end(); for (; iter != end; ++iter) - { + { LLAvatarJointMesh* mesh = (*iter); if (mesh) - { + { mesh->setTexture( image_baked ); - } + } } } @@ -7552,14 +7544,13 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) { LLAvatarJointMesh* mesh = (*iter); if (mesh) - { + { mesh->setColor( LLColor4::white ); } } } } } - dirtyMesh(); } @@ -7571,7 +7562,7 @@ std::string get_sequential_numbered_file_name(const std::string& prefix, file_num_type::iterator it = file_nums.find(prefix); S32 num = 0; if (it != file_nums.end()) -{ + { num = it->second; } file_nums[prefix] = num+1; @@ -7604,65 +7595,58 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara LLAPRFile outfile; std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); - outfile.open(fullpath, LL_APR_WB ); - apr_file_t* file = outfile.getFileHandle(); - if (!file) - { - return; - } - else + if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB )) { + apr_file_t* file = outfile.getFileHandle(); LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL; - } - - apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" ); - apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); - apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); - if (group_by_wearables) - { - for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) - { - const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); - apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() ); + apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" ); + apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); + apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); - for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + if (group_by_wearables) { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - if( (viewer_param->getWearableType() == type) && - (viewer_param->isTweakable() ) ) + for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) { - dump_visual_param(file, viewer_param, viewer_param->getWeight()); - } - } + const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); + apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() ); - for (U8 te = 0; te < TEX_NUM_INDICES; te++) - { - if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) - { - // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); - if( te_image ) + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) { - std::string uuid_str; - te_image->getID().toString( uuid_str ); - apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + if( (viewer_param->getWearableType() == type) && + (viewer_param->isTweakable() ) ) + { + dump_visual_param(file, viewer_param, viewer_param->getWeight()); + } + } + + for (U8 te = 0; te < TEX_NUM_INDICES; te++) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) + { + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); + if( te_image ) + { + std::string uuid_str; + te_image->getID().toString( uuid_str ); + apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); + } + } } } } - } - } - else - { - // Just dump all params sequentially. - for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + else { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - dump_visual_param(file, viewer_param, viewer_param->getWeight()); - } + // Just dump all params sequentially. + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + { + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + dump_visual_param(file, viewer_param, viewer_param->getWeight()); + } - for (U8 te = 0; te < TEX_NUM_INDICES; te++) - { + for (U8 te = 0; te < TEX_NUM_INDICES; te++) { // MULTIPLE_WEARABLES: extend to multiple wearables? LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); @@ -7674,18 +7658,17 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara } } } + apr_file_printf( file, "\t</archetype>\n" ); + apr_file_printf( file, "\n</linden_genepool>\n" ); + bool ultra_verbose = false; + if (isSelf() && ultra_verbose) + { + // show the cloned params inside the wearables as well. + gAgentAvatarp->dumpWearableInfo(outfile); + } + outfile.close(); } - apr_file_printf( file, "\t</archetype>\n" ); - apr_file_printf( file, "\n</linden_genepool>\n" ); - - bool ultra_verbose = false; - if (isSelf() && ultra_verbose) - { - // show the cloned params inside the wearables as well. - gAgentAvatarp->dumpWearableInfo(outfile); - } - // File will close when handle goes out of scope } @@ -7799,7 +7782,7 @@ void LLVOAvatar::startAppearanceAnimation() // virtual void LLVOAvatar::removeMissingBakedTextures() - { +{ } //virtual @@ -8053,7 +8036,6 @@ void LLVOAvatar::calculateUpdateRenderCost() } } } - } // Diagnostic output to identify all avatar-related textures. @@ -8065,9 +8047,8 @@ void LLVOAvatar::calculateUpdateRenderCost() for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) { LLUUID image_id = it->first; - if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - continue; - if (all_textures.find(image_id) == all_textures.end()) + if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + && (all_textures.find(image_id) == all_textures.end())) { // attachment texture not previously seen. LL_INFOS() << "attachment_texture: " << image_id.asString() << LL_ENDL; @@ -8133,15 +8114,17 @@ LLColor4 LLVOAvatar::calcMutedAVColor(F32 value, S32 range_low, S32 range_high) // static BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index) { - if (index < 0 || index >= TEX_NUM_INDICES) return false; - return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture; + return (index < 0 || index >= TEX_NUM_INDICES) + ? false + : LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture; } // static BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index) { - if (index < 0 || index >= TEX_NUM_INDICES) return false; - return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture; + return (index < 0 || index >= TEX_NUM_INDICES) + ? false + : LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture; } const std::string LLVOAvatar::getBakedStatusForPrintout() const @@ -8191,7 +8174,7 @@ BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U { return FALSE; } - + if( !getImage( te, index ) ) { LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL; |