diff --git a/.clang-format b/.clang-format
index 0b19cae8387531906559f67da7a7de4acf277786..ee8a8a8c92f9c34e120e5a61c2f49aeeada06241 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,17 +1,18 @@
 ---
+# clang-format version 10.0.0+
 Language:        Cpp
 # BasedOnStyle:  Microsoft
 AccessModifierOffset: -2
 AlignAfterOpenBracket: Align
-AlignConsecutiveMacros: false
-AlignConsecutiveAssignments: false
-AlignConsecutiveDeclarations: false
-AlignEscapedNewlines: Right
+AlignConsecutiveMacros: true
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: true
+AlignEscapedNewlines: Left
 AlignOperands:   true
 AlignTrailingComments: true
-AllowAllArgumentsOnNextLine: true
-AllowAllConstructorInitializersOnNextLine: true
-AllowAllParametersOfDeclarationOnNextLine: true
+AllowAllArgumentsOnNextLine: false
+AllowAllConstructorInitializersOnNextLine: false
+AllowAllParametersOfDeclarationOnNextLine: false
 AllowShortBlocksOnASingleLine: Always
 AllowShortCaseLabelsOnASingleLine: false
 AllowShortFunctionsOnASingleLine: All
@@ -29,21 +30,21 @@ BreakBeforeBraces: Allman
 BreakBeforeInheritanceComma: false
 BreakInheritanceList: BeforeColon
 BreakBeforeTernaryOperators: true
-BreakConstructorInitializersBeforeComma: false
-BreakConstructorInitializers: BeforeColon
+BreakConstructorInitializersBeforeComma: true
+BreakConstructorInitializers: AfterColon
 BreakAfterJavaFieldAnnotations: false
 BreakStringLiterals: true
-ColumnLimit:     120
+ColumnLimit:     140
 CommentPragmas:  '^ IWYU pragma:'
 CompactNamespaces: false
-ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
 ConstructorInitializerIndentWidth: 4
 ContinuationIndentWidth: 4
 Cpp11BracedListStyle: true
 DeriveLineEnding: true
 DerivePointerAlignment: false
 DisableFormat:   false
-ExperimentalAutoDetectBinPacking: false
+ExperimentalAutoDetectBinPacking: true
 FixNamespaceComments: true
 ForEachMacros:
   - foreach
@@ -62,18 +63,18 @@ IncludeCategories:
     SortPriority:    0
 IncludeIsMainRegex: '(Test)?$'
 IncludeIsMainSourceRegex: ''
-IndentCaseLabels: false
+IndentCaseLabels: true
 IndentGotoLabels: true
 IndentPPDirectives: None
 IndentWidth:     4
 IndentWrappedFunctionNames: false
 JavaScriptQuotes: Leave
 JavaScriptWrapImports: true
-KeepEmptyLinesAtTheStartOfBlocks: true
+KeepEmptyLinesAtTheStartOfBlocks: false
 MacroBlockBegin: ''
 MacroBlockEnd:   ''
 MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None
+NamespaceIndentation: Inner
 ObjCBinPackProtocolList: Auto
 ObjCBlockIndentWidth: 2
 ObjCSpaceAfterProperty: false
@@ -94,16 +95,16 @@ SpaceAfterCStyleCast: true
 SpaceAfterLogicalNot: false
 SpaceAfterTemplateKeyword: true
 SpaceBeforeAssignmentOperators: true
-SpaceBeforeCpp11BracedList: false
+SpaceBeforeCpp11BracedList: true
 SpaceBeforeCtorInitializerColon: true
 SpaceBeforeInheritanceColon: true
 SpaceBeforeParens: ControlStatements
 SpaceBeforeRangeBasedForLoopColon: true
 SpaceInEmptyBlock: false
 SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 1
+SpacesBeforeTrailingComments: 2
 SpacesInAngles:  false
-SpacesInContainerLiterals: true
+SpacesInContainerLiterals: false
 SpacesInCStyleCastParentheses: false
 SpacesInParentheses: false
 SpacesInSquareBrackets: false
diff --git a/autobuild.xml b/autobuild.xml
index 51515b36962cd0b11aba89e1115dd585a1409573..eacf11fb0ff5580339ee776b5381aefb03f29045 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -76,9 +76,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d670d00aa732b97d105d287b62582762</string>
+              <string>9b8bcc3be6dbe40a04c9c81c313f70dc</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55065/512118/apr_suite-1.4.5.539073-darwin64-539073.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/68333/658209/apr_suite-1.4.5.548882-darwin64-548882.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -112,9 +112,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>83b4a047db5f7ee462753d91e6277cba</string>
+              <string>6bdf460c18ee004b41a46afc80041a92</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55143/512317/apr_suite-1.4.5.539073-windows-539073.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/68334/658225/apr_suite-1.4.5.548882-windows-548882.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -124,16 +124,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b3bbf168b39e25c08cc1febddeb33332</string>
+              <string>83104bfa4dabb77cd70d185e38a95b49</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55139/512304/apr_suite-1.4.5.539073-windows64-539073.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/68332/658215/apr_suite-1.4.5.548882-windows64-548882.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.4.5.539073</string>
+        <string>1.4.5.548882</string>
       </map>
       <key>boost</key>
       <map>
@@ -2187,16 +2187,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8501cbaa7e0f254614694da784a9c61c</string>
+              <string>b677ee43822212f0a27c838dc8bf3623</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64944/606925/llca-202008010216.546021-common-546021.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/67622/646614/llca-202009010215.548269-common-548269.tar.bz2</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
         <key>version</key>
-        <string>202008010216.546021</string>
+        <string>202009010215.548269</string>
       </map>
       <key>llphysicsextensions_source</key>
       <map>
@@ -3906,9 +3906,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
+                  <string>-DOPENAL:BOOL=ON</string>
                 </array>
               </map>
               <key>name</key>
@@ -3979,6 +3979,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
+                  <string>-DOPENAL:BOOL=ON</string>
                 </array>
               </map>
               <key>name</key>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 4d8165faf2e7aa99161d96fe2351b99565df5ba7..e2b69a9fe4755d83e9c5cfa2dc538b51f1346de5 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -258,6 +258,8 @@ Beansy Twine
 Benja Kepler
 	VWR-746
 Benjamin Bigdipper
+Beq Janus
+	BUG-227094
 Beth Walcher
 Bezilon Kasei
 Biancaluce Robbiani
@@ -829,6 +831,7 @@ Khyota Wulluf
 Kimar Coba
 Kithrak Kirkorian
 Kitty Barnett
+	BUG-228665
 	VWR-19699
 	STORM-288
 	STORM-799
@@ -1301,6 +1304,7 @@ Shyotl Kuhr
 	MAINT-2334
 	MAINT-6913
 	STORM-2143
+	SL-11625
 Siana Gearz
 	STORM-960
 	STORM-1088
@@ -1340,6 +1344,7 @@ Sovereign Engineer
     MAINT-7343
     SL-11079
     OPEN-343
+	SL-11625
 SpacedOut Frye
 	VWR-34
 	VWR-45
@@ -1445,6 +1450,8 @@ Thickbrick Sleaford
 	STORM-956
 	STORM-1147
 	STORM-1325
+Thoys Pan
+	SL-12396
 Thraxis Epsilon
 	SVC-371
 	VWR-383
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 865c057e33f064cebafaa62bd29c41bc3406ad5c..8aea50e02b1a2167b2c0fe61aebace3db1943ef3 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -63,7 +63,13 @@ if (WINDOWS)
   # Without PreferredToolArchitecture=x64, as of 2020-06-26 the 32-bit
   # compiler on our TeamCity build hosts has started running out of virtual
   # memory for the precompiled header file.
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /p:PreferredToolArchitecture=x64")
+  # CP changed to only append the flag for 32bit builds - on 64bit builds,
+  # locally at least, the build output is spammed with 1000s of 'D9002'
+  # warnings about this switch being ignored.
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")  
+  if( ADDRESS_SIZE EQUAL 32 )
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")  
+  endif()
 
   set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
       "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 429bda473b00d8b92b7aef31dad6708d35d3d1ab..8efad33f7174e16a39119a7060b2c760a26c166c 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -82,6 +82,10 @@ if(WINDOWS)
         set(release_files ${release_files} fmod.dll)
     endif (FMODSTUDIO)
 
+    if (OPENAL)
+        list(APPEND release_files openal32.dll alut.dll)
+    endif (OPENAL)
+
     #*******************************
     # Copy MS C runtime dlls, required for packaging.
     if (MSVC80)
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..48082f72f087ce7e6fa75b9c41d7387daecd447b 100644
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -0,0 +1 @@
+12
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 8b628a058e0b74b7d8d603185f5a9a3ce76a675e..558ede7bf6870ddf1ee472f94736359a2014dd1b 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -60,6 +60,10 @@ if (FMODSTUDIO)
 endif (FMODSTUDIO)
 
 if (OPENAL)
+  include_directories(
+    ${OPENAL_LIBRARIES}
+    )
+
   list(APPEND llaudio_SOURCE_FILES
     llaudioengine_openal.cpp
     lllistener_openal.cpp
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
index a38d8291fa900a3e907c17b186920858d2d33133..3bdd0302eedf16ff02d0c00b0c0c1e490e6190c3 100644
--- a/indra/llaudio/llaudioengine_openal.cpp
+++ b/indra/llaudio/llaudioengine_openal.cpp
@@ -55,7 +55,7 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
 bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title)
 {
 	mWindGen = NULL;
-	LLAudioEngine::init(num_channels, userdata);
+	LLAudioEngine::init(num_channels, userdata, app_title);
 
 	if(!alutInit(NULL, NULL))
 	{
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 0f76ff23ea9731b14eaed7001646da45a9b17991..7bea8e9f9c353e78666f73f03b686c530c0d1e43 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -1007,11 +1007,20 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd
 {
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
 
-	if (op->mCallbackSSLVerify)
-	{
-		SSL_CTX * ctx = (SSL_CTX *)sslctx;
-		// disable any default verification for server certs
-		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+    if (op->mCallbackSSLVerify)
+    {
+        SSL_CTX * ctx = (SSL_CTX *)sslctx;
+        if (op->mReqOptions && op->mReqOptions->getSSLVerifyPeer())
+        {
+            // verification for ssl certs
+            SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
+        }
+        else
+        {
+            // disable any default verification for server certs
+            // Ex: setting urls (assume non-SL) for parcel media in LLFloaterURLEntry
+            SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+        }
 		// set the verification callback.
 		SSL_CTX_set_cert_verify_callback(ctx, sslCertVerifyCallback, userdata);
 		// the calls are void
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 306c73292057c05f4da4fe5b2e481d6a8413cdb2..81937dbda529ccbb6475e1d045e27d05274a6e81 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -1295,6 +1295,9 @@ void LLSettingsSky::clampColor(LLColor3& color, F32 gamma, F32 scale) const
     color = linear;
 }
 
+// Similar/Shared Algorithms:
+//     indra\llinventory\llsettingssky.cpp                                        -- LLSettingsSky::calculateLightSettings()
+//     indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
 void LLSettingsSky::calculateLightSettings() const
 {
     // Initialize temp variables
diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h
index 222f3cf235199347813b67c6351cd3a1d74aa97a..27abf395376b13c0f7cb84a85a27a493382c56af 100644
--- a/indra/llmath/llvector4a.h
+++ b/indra/llmath/llvector4a.h
@@ -46,10 +46,10 @@ class LLRotation;
 // of this writing, July 08, 2010) about getting it implemented before you resort to
 // LLVector3/LLVector4. 
 /////////////////////////////////
-class LLVector4a;
+struct LLVector4a;
 
 LL_ALIGN_PREFIX(16)
-class LLVector4a
+struct LLVector4a
 {
 public:
 
@@ -92,6 +92,7 @@ class LLVector4a
 	// CONSTRUCTORS 
 	////////////////////////////////////
 	
+	//LLVector4a is plain data which should never have a default constructor or destructor(malloc&free won't trigger it)
 	LLVector4a()
 	{ //DO NOT INITIALIZE -- The overhead is completely unnecessary
 		ll_assert_aligned(this,16);
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 42c19e3b1c8c4991e92a704e41b7fd922918fa07..26684a4d9e93e5a5dfe3b7bfd7176ec6d3193e1c 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -77,12 +77,12 @@ class LLCoprocedurePool: private boost::noncopyable
     ///
     inline size_t countActive() const
     {
-        return mActiveCoprocs.size();
+        return mActiveCoprocsCount;
     }
 
     /// Returns the total number of coprocedures either queued or in active processing.
     ///
-    inline size_t count() const
+    inline S32 count() const
     {
         return countPending() + countActive();
     }
@@ -113,12 +113,10 @@ class LLCoprocedurePool: private boost::noncopyable
     // because the consuming coroutine might outlive this LLCoprocedurePool
     // instance.
     typedef boost::shared_ptr<CoprocQueue_t> CoprocQueuePtr;
-    typedef std::map<LLUUID, LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t> ActiveCoproc_t;
 
     std::string     mPoolName;
-    size_t          mPoolSize, mPending{0};
+    size_t          mPoolSize, mActiveCoprocsCount, mPending;
     CoprocQueuePtr  mPendingCoprocs;
-    ActiveCoproc_t  mActiveCoprocs;
     LLTempBoundListener mStatusListener;
 
     typedef std::map<std::string, LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t> CoroAdapterMap_t;
@@ -191,8 +189,13 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s
 
 void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)
 {
+    // functions to discover and store the pool sizes
     mPropertyQueryFn = queryfn;
     mPropertyDefineFn = updatefn;
+
+    // workaround until we get mutex into initializePool
+    initializePool("VAssetStorage");
+    initializePool("Upload");
 }
 
 //-------------------------------------------------------------------------
@@ -276,6 +279,8 @@ void LLCoprocedureManager::close(const std::string &pool)
 LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
     mPoolName(poolName),
     mPoolSize(size),
+    mActiveCoprocsCount(0),
+    mPending(0),
     mPendingCoprocs(boost::make_shared<CoprocQueue_t>(DEFAULT_QUEUE_SIZE)),
     mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
     mCoroMapping()
@@ -401,8 +406,7 @@ void LLCoprocedurePool::coprocedureInvokerCoro(
         }
         // we actually popped an item
         --mPending;
-
-        ActiveCoproc_t::iterator itActive = mActiveCoprocs.insert(ActiveCoproc_t::value_type(coproc->mId, httpAdapter)).first;
+        mActiveCoprocsCount++;
 
         LL_DEBUGS("CoProcMgr") << "Dequeued and invoking coprocedure(" << coproc->mName << ") with id=" << coproc->mId.asString() << " in pool \"" << mPoolName << "\" (" << mPending << " left)" << LL_ENDL;
 
@@ -410,19 +414,25 @@ void LLCoprocedurePool::coprocedureInvokerCoro(
         {
             coproc->mProc(httpAdapter, coproc->mId);
         }
+        catch (const LLCoros::Stop &e)
+        {
+            LL_INFOS("LLCoros") << "coprocedureInvokerCoro terminating because "
+                << e.what() << LL_ENDL;
+            throw; // let toplevel handle this as LLContinueError
+        }
         catch (...)
         {
             LOG_UNHANDLED_EXCEPTION(STRINGIZE("Coprocedure('" << coproc->mName
                                               << "', id=" << coproc->mId.asString()
                                               << ") in pool '" << mPoolName << "'"));
             // must NOT omit this or we deplete the pool
-            mActiveCoprocs.erase(itActive);
+            mActiveCoprocsCount--;
             continue;
         }
 
         LL_DEBUGS("CoProcMgr") << "Finished coprocedure(" << coproc->mName << ")" << " in pool \"" << mPoolName << "\"" << LL_ENDL;
 
-        mActiveCoprocs.erase(itActive);
+        mActiveCoprocsCount--;
     }
 }
 
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 7d96ac4b0256adf9f78614565f9d00c6002faa3c..64c01bd9ebdabb96e94ce3fcbad24c2a87860a18 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -85,15 +85,15 @@ const F64 LLExperienceCache::DEFAULT_EXPIRATION	= 600.0;
 const S32 LLExperienceCache::DEFAULT_QUOTA			= 128; // this is megabytes
 const int LLExperienceCache::SEARCH_PAGE_SIZE     = 30;
 
+bool LLExperienceCache::sShutdown = false;
+
 //=========================================================================
-LLExperienceCache::LLExperienceCache():
-    mShutdown(false)
+LLExperienceCache::LLExperienceCache()
 {
 }
 
 LLExperienceCache::~LLExperienceCache()
 {
-
 }
 
 void LLExperienceCache::initSingleton()
@@ -122,7 +122,7 @@ void LLExperienceCache::cleanup()
     {
         cache_stream << (*this);
     }
-    mShutdown = true;
+    sShutdown = true;
 }
 
 //-------------------------------------------------------------------------
@@ -344,7 +344,7 @@ void LLExperienceCache::requestExperiences()
     ostr << urlBase << "?page_size=" << PAGE_SIZE1;
     RequestQueue_t  requests;
 
-    while (!mRequestQueue.empty())
+    while (!mRequestQueue.empty() && !sShutdown)
     {
         RequestQueue_t::iterator it = mRequestQueue.begin();
         LLUUID key = (*it);
@@ -398,8 +398,6 @@ void LLExperienceCache::idleCoro()
     LL_INFOS("ExperienceCache") << "Launching Experience cache idle coro." << LL_ENDL;
     do 
     {
-        llcoro::suspendUntilTimeout(SECS_BETWEEN_REQUESTS);
-
         if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
         {
             eraseExpired();
@@ -410,7 +408,9 @@ void LLExperienceCache::idleCoro()
             requestExperiences();
         }
 
-    } while (!mShutdown);
+        llcoro::suspendUntilTimeout(SECS_BETWEEN_REQUESTS);
+
+    } while (!sShutdown);
 
     // The coroutine system will likely be shut down by the time we get to this point
     // (or at least no further cycling will occur on it since the user has decided to quit.)
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index f9ff69c2b6690ebddb9ab59e4555db9bfadbb73e..1c97133723aeca89b512f5a7c2383d110d37a14e 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -142,7 +142,7 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache >
     LLFrameTimer    mEraseExpiredTimer;    // Periodically clean out expired entries from the cache
     CapabilityQuery_t mCapability;
     std::string     mCacheFileName;
-    bool            mShutdown;
+    static bool     sShutdown; // control for coroutines, they exist out of LLExperienceCache's scope, so they need a static control
 
     void idleCoro();
 	void eraseExpired();
diff --git a/indra/llmessage/llteleportflags.h b/indra/llmessage/llteleportflags.h
index b3fcad036ea153f18095597e6b63073b20e8653a..fd1e702832820c88e50a6cef8affe0096f6d60bd 100644
--- a/indra/llmessage/llteleportflags.h
+++ b/indra/llmessage/llteleportflags.h
@@ -44,6 +44,8 @@ const U32 TELEPORT_FLAGS_VIA_REGION_ID  	= 1 << 12;
 const U32 TELEPORT_FLAGS_IS_FLYING			= 1 << 13;
 const U32 TELEPORT_FLAGS_SHOW_RESET_HOME	= 1 << 14;
 const U32 TELEPORT_FLAGS_FORCE_REDIRECT		= 1 << 15; // used to force a redirect to some random location - used when kicking someone from land.
+const U32 TELEPORT_FLAGS_VIA_GLOBAL_COORDS	= 1 << 16;
+const U32 TELEPORT_FLAGS_WITHIN_REGION		= 1 << 17;
 
 const U32 TELEPORT_FLAGS_MASK_VIA =   TELEPORT_FLAGS_VIA_LURE 
 									| TELEPORT_FLAGS_VIA_LANDMARK
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index ff743802170263af651af6c0eda16c4e29bf1d82..3b6a49735ea378492acabd6c611f8e45527edca4 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -985,38 +985,56 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
 		return FALSE;
 	}
 
-	if( !mHasExplicitFormat )
-	{
-		switch (mComponents)
-		{
-			case 1:
-			// Use luminance alpha (for fonts)
-			mFormatInternal = GL_LUMINANCE8;
-			mFormatPrimary = GL_LUMINANCE;
-			mFormatType = GL_UNSIGNED_BYTE;
-			break;
-			case 2:
-			// Use luminance alpha (for fonts)
-			mFormatInternal = GL_LUMINANCE8_ALPHA8;
-			mFormatPrimary = GL_LUMINANCE_ALPHA;
-			mFormatType = GL_UNSIGNED_BYTE;
-			break;
-			case 3:
-			mFormatInternal = GL_RGB8;
-			mFormatPrimary = GL_RGB;
-			mFormatType = GL_UNSIGNED_BYTE;
-			break;
-			case 4:
-			mFormatInternal = GL_RGBA8;
-			mFormatPrimary = GL_RGBA;
-			mFormatType = GL_UNSIGNED_BYTE;
-			break;
-			default:
-			LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
-		}
-	}
+    if (!mHasExplicitFormat)
+    {
+        switch (mComponents)
+        {
+            case 1:
+                // Use luminance alpha (for fonts)
+                mFormatInternal = GL_LUMINANCE8;
+                mFormatPrimary  = GL_LUMINANCE;
+                mFormatType     = GL_UNSIGNED_BYTE;
+                break;
+            case 2:
+                // Use luminance alpha (for fonts)
+                mFormatInternal = GL_LUMINANCE8_ALPHA8;
+                mFormatPrimary  = GL_LUMINANCE_ALPHA;
+                mFormatType     = GL_UNSIGNED_BYTE;
+                break;
+            case 3:
+#if USE_SRGB_DECODE
+                if (gGLManager.mHasTexturesRGBDecode)
+                {
+                    mFormatInternal = GL_SRGB8;
+                }
+                else
+#endif
+                {
+                    mFormatInternal = GL_RGB8;
+                }
+                mFormatPrimary = GL_RGB;
+                mFormatType    = GL_UNSIGNED_BYTE;
+                break;
+            case 4:
+#if USE_SRGB_DECODE
+                if (gGLManager.mHasTexturesRGBDecode)
+                {
+                    mFormatInternal = GL_SRGB8_ALPHA8;
+                }
+                else
+#endif
+                {
+                    mFormatInternal = GL_RGBA8;
+                }
+                mFormatPrimary = GL_RGBA;
+                mFormatType    = GL_UNSIGNED_BYTE;
+                break;
+            default:
+                LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL;
+        }
+    }
 
-	mCurrentDiscardLevel = discard_level;	
+    mCurrentDiscardLevel = discard_level;	
 	mDiscardLevelInAtlas = discard_level;
 	mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
 	mLastBindTime = sLastFrameTime;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index ebc4659bcfbb0a76d6e5d3329238b6806e7fc2ab..11d9ef3f57fdd42633124929011b1b8b1bdd31fe 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -849,26 +849,32 @@ void LLTexUnit::debugTextureUnit(void)
 	}
 }
 
-void LLTexUnit::setTextureColorSpace(eTextureColorSpace space) {
+void LLTexUnit::setTextureColorSpace(eTextureColorSpace space)
+{
     mTexColorSpace = space;
 
 #if USE_SRGB_DECODE
-    if (gGLManager.mHasTexturesRGBDecode) {
-
-        if (space == TCS_SRGB) {
+    if (gGLManager.mHasTexturesRGBDecode)
+    {
+        if (space == TCS_SRGB)
+        {
             glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
         }
-        else {
+        else
+        {
             glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
         }
 
-        if (gDebugGL) {
+        if (gDebugGL)
+        {
             assert_glerror();
         }
     }
+    else
 #endif
-    glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
-
+    {
+        glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+    }
 }
 
 LLLightState::LLLightState(S32 index)
@@ -1192,46 +1198,46 @@ void LLRender::refreshState(void)
 
 void LLRender::syncLightState()
 {
-	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+    LLGLSLShader *shader = LLGLSLShader::sCurBoundShaderPtr;
 
-	if (!shader)
-	{
-		return;
-	}
+    if (!shader)
+    {
+        return;
+    }
 
-	if (shader->mLightHash != mLightHash)
-	{
-		shader->mLightHash = mLightHash;
+    if (shader->mLightHash != mLightHash)
+    {
+        shader->mLightHash = mLightHash;
 
-		LLVector4 position[8];
-		LLVector3 direction[8];
-		LLVector4 attenuation[8];
-		LLVector3 diffuse[8];
-        LLVector3 diffuse_b[8];
-        bool      sun_primary[8];
+        LLVector4 position[LL_NUM_LIGHT_UNITS];
+        LLVector3 direction[LL_NUM_LIGHT_UNITS];
+        LLVector4 attenuation[LL_NUM_LIGHT_UNITS];
+        LLVector3 diffuse[LL_NUM_LIGHT_UNITS];
+        LLVector3 diffuse_b[LL_NUM_LIGHT_UNITS];
+        bool      sun_primary[LL_NUM_LIGHT_UNITS];
 
-		for (U32 i = 0; i < 8; i++)
-		{
-			LLLightState* light = mLightState[i];
+        for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; i++)
+        {
+            LLLightState *light = mLightState[i];
 
-			position[i] = light->mPosition;
-			direction[i] = light->mSpotDirection;
+            position[i]  = light->mPosition;
+            direction[i] = light->mSpotDirection;
             attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[2], light->mSpecular.mV[3]);
-			diffuse[i].set(light->mDiffuse.mV);
+            diffuse[i].set(light->mDiffuse.mV);
             diffuse_b[i].set(light->mDiffuseB.mV);
             sun_primary[i] = light->mSunIsPrimary;
-		}
+        }
 
-		shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, 8, position[0].mV);
-		shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, 8, direction[0].mV);
-		shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, 8, attenuation[0].mV);
-		shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, 8, diffuse[0].mV);
-		shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
+        shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, LL_NUM_LIGHT_UNITS, position[0].mV);
+        shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, LL_NUM_LIGHT_UNITS, direction[0].mV);
+        shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, LL_NUM_LIGHT_UNITS, attenuation[0].mV);
+        shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, LL_NUM_LIGHT_UNITS, diffuse[0].mV);
+        shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
         shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_primary[0] ? 1 : 0);
         shader->uniform4fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV);
         shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
         shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuse_b[0].mV);
-	}
+    }
 }
 
 void LLRender::syncMatrices()
@@ -1539,11 +1545,17 @@ void LLRender::matrixMode(eMatrixMode mode)
 	{
         U32 tex_index = gGL.getCurrentTexUnitIndex();
         // the shaders don't actually reference anything beyond texture_matrix0/1 outside of terrain rendering
-        llassert_always(tex_index <= 3);
-		mode = eMatrixMode(MM_TEXTURE0 + gGL.getCurrentTexUnitIndex());
+        llassert(tex_index <= 3);
+        mode = eMatrixMode(MM_TEXTURE0 + tex_index);
+        if (mode > MM_TEXTURE3)
+        {
+            // getCurrentTexUnitIndex() can go as high as 32 (LL_NUM_TEXTURE_LAYERS)
+            // Large value will result in a crash at mMatrix
+            LL_WARNS_ONCE() << "Attempted to assign matrix mode out of bounds: " << mode << LL_ENDL;
+            mode = MM_TEXTURE0;
+        }
 	}
 
-	llassert(mode < NUM_MATRIX_MODES);
 	mMatrixMode = mode;
 }
 
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 9fb4f7f2b07d18aed7bf79ea6bf7d69cad19a89d..e3c0255290fde73daac8dc5ff82493f47a4e186a 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -501,23 +501,23 @@ U32 LLRenderTarget::getNumTextures() const
 	return mTex.size();
 }
 
-
 void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options)
 {
-	gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
+    gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
 
     bool isSRGB = false;
     llassert(mInternalFormat.size() > index);
     switch (mInternalFormat[index])
     {
-        case GL_SRGB_ALPHA:
         case GL_SRGB:
+        case GL_SRGB8:
+        case GL_SRGB_ALPHA:
         case GL_SRGB8_ALPHA8:
             isSRGB = true;
-        break;
+            break;
 
         default:
-        break;
+            break;
     }
 
     gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options);
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 13830208732d0a97c1821d16a7f290a8aedd01c0..236ebbd78fa013ccf0e8c0b0e799885bed5fb186 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1180,7 +1180,7 @@ void LLShaderMgr::initAttribsAndUniforms()
 
 	llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
 
-
+    //NOTE: MUST match order in eGLSLReservedUniforms
 	mReservedUniforms.push_back("proj_mat");
 	mReservedUniforms.push_back("proj_near");
 	mReservedUniforms.push_back("proj_p");
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index edcbc3fbb7b49bf466c78ab332a40ec047fbce18..61a119800e3e483455a984d79aad1adbdc66433e 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -655,6 +655,37 @@ void	LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
 {
 	updateLayout(getRect().getWidth(),getRect().getHeight());
 }
+
+// virtual
+void LLAccordionCtrl::onUpdateScrollToChild(const LLUICtrl *cntrl)
+{
+    if (mScrollbar && mScrollbar->getVisible())
+    {
+        // same as scrollToShowRect
+        LLRect rect;
+        cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this);
+
+        // Translate to parent coordinatess to check if we are in visible rectangle
+        rect.translate(getRect().mLeft, getRect().mBottom);
+
+        if (!getRect().contains(rect))
+        {
+            // for accordition's scroll, height is in pixels
+            // Back to local coords and calculate position for scroller
+            S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom;
+            S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop;
+
+            S32 scroll_pos = llclamp(mScrollbar->getDocPos(),
+                bottom, // min vertical scroll
+                top); // max vertical scroll 
+
+            mScrollbar->setDocPos(scroll_pos);
+        }
+    }
+
+    LLUICtrl::onUpdateScrollToChild(cntrl);
+}
+
 void	LLAccordionCtrl::onOpen		(const LLSD& key)
 {
 	for(size_t i=0;i<mAccordionTabs.size();++i)
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 1fe64c472edea53d99b2a7e8385c266e57a5ec5c..b38a76d27f4d31d7e51cbbf49522c051490d612b 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -111,6 +111,7 @@ class LLAccordionCtrl: public LLPanel
 	void	draw();
 	
 	void	onScrollPosChangeCallback(S32, LLScrollbar*);
+	virtual void onUpdateScrollToChild(const LLUICtrl * cntrl);
 
 	void	onOpen		(const LLSD& key);
 	S32		notifyParent(const LLSD& info);
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 1034a219052f29b45ba4be46885f837573ec7c5d..098621b543c780e974d90c2ee986376273716bee 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -452,6 +452,35 @@ void LLAccordionCtrlTab::onVisibilityChange(BOOL new_visibility)
 	notifyParent(LLSD().with("child_visibility_change", new_visibility));
 }
 
+// virtual
+void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl)
+{
+    if (mScrollbar && mScrollbar->getVisible())
+    {
+        LLRect rect;
+        cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this);
+
+        // Translate to parent coordinatess to check if we are in visible rectangle
+        rect.translate(getRect().mLeft, getRect().mBottom);
+
+        if (!getRect().contains(rect))
+        {
+            // for accordition's scroll, height is in pixels
+            // Back to local coords and calculate position for scroller
+            S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom;
+            S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop;
+
+            S32 scroll_pos = llclamp(mScrollbar->getDocPos(),
+                bottom, // min vertical scroll
+                top); // max vertical scroll 
+
+            mScrollbar->setDocPos(scroll_pos);
+        }
+    }
+
+    LLUICtrl::onUpdateScrollToChild(cntrl);
+}
+
 BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	if(mCollapsible && mHeaderVisible && mCanOpenClose)
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index 0263bce4be7e8947a07a31a12ce0a33fbbdf21eb..2c72e8c036d166e8b541ffd6c447f6f9a7aafade 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -159,6 +159,7 @@ class LLAccordionCtrlTab : public LLUICtrl
 	 * Raises notifyParent event with "child_visibility_change" = new_visibility
 	 */
 	void onVisibilityChange(BOOL new_visibility);
+	virtual void onUpdateScrollToChild(const LLUICtrl * cntrl);
 
 	// Changes expand/collapse state and triggers expand/collapse callbacks
 	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp
index 0557cd437568df9ddbbe3c23c8d4216edfb4e6e7..5f11c383ef132ebf8522b5aecba3475f44cb2d0f 100644
--- a/indra/llui/llbadgeowner.cpp
+++ b/indra/llui/llbadgeowner.cpp
@@ -56,6 +56,14 @@ void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p)
 	}
 }
 
+void LLBadgeOwner::reshapeBadge(const LLRect& new_rect)
+{
+	if (mBadge)
+	{
+		mBadge->setShape(new_rect);
+	}
+}
+
 void LLBadgeOwner::setBadgeVisibility(bool visible)
 {
 	if (mBadge)
diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h
index 01ed95f3a3efe30be79e8ae680956122a84315e3..4ce208fa0d802f52e14e626700ae3e9acb9ddbc9 100644
--- a/indra/llui/llbadgeowner.h
+++ b/indra/llui/llbadgeowner.h
@@ -46,6 +46,7 @@ class LLBadgeOwner
 	bool hasBadgeHolderParent() const { return mHasBadgeHolderParent; };
 	void setBadgeVisibility(bool visible);
 	void setDrawBadgeAtTop(bool draw_at_top);
+	void reshapeBadge(const LLRect& new_rect);
 
 private:
 
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index c7f0326ed49f324b6d95187a444c365df1fc4489..52dc908655d8cecd488d544e4c9f894d19fde519 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -514,6 +514,14 @@ S32 LLComboBox::getCurrentIndex() const
 	return -1;
 }
 
+void LLComboBox::setEnabledByValue(const LLSD& value, BOOL enabled)
+{
+    LLScrollListItem *found = mList->getItem(value);
+    if (found)
+    {
+        found->setEnabled(enabled);
+    }
+}
 
 void LLComboBox::createLineEditor(const LLComboBox::Params& p)
 {
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 7d38c051a5a9a527811612c47b69dee1ea36813f..4af33131626c79371ac2c5fc36bc953184feda4b 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -158,6 +158,8 @@ class LLComboBox
 	BOOL			setCurrentByIndex( S32 index );
 	S32				getCurrentIndex() const;
 
+	void			setEnabledByValue(const LLSD& value, BOOL enabled);
+
 	void			createLineEditor(const Params&);
 
 	//========================================================================
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 70304cdfd245e731b024c4f37fae8f2b667bc6b3..1badd54fca5df6af7b8ab85b69abb5b9b81884ae 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2151,6 +2151,7 @@ void LLLineEditor::clear()
 void LLLineEditor::onTabInto()
 {
 	selectAll();
+    LLUICtrl::onTabInto();
 }
 
 //virtual
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 20e2b569f1a764d1e42bc66de7aeda29ae6c47b7..b3df7c154b1fd82a538da991e61f199c0cd878c5 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -509,6 +509,7 @@ void LLMultiSliderCtrl::onTabInto()
 	{
 		mEditor->onTabInto(); 
 	}
+    LLF32UICtrl::onTabInto();
 }
 
 void LLMultiSliderCtrl::reportInvalidData()
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 8d522cd2e331357a511a8f378462c78ba76e6642..b791a19c2bfe4091cf37453065a3afc5e7709f36 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -256,7 +256,7 @@ LLNotificationForm::LLNotificationForm(const LLSD& sd)
 	}
 	else
 	{
-		LL_WARNS() << "Invalid form data " << sd << LL_ENDL;
+		LL_WARNS("Notifications") << "Invalid form data " << sd << LL_ENDL;
 		mFormData = LLSD::emptyArray();
 	}
 }
@@ -449,11 +449,11 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 		mUniqueContext.push_back(context.value);
 	}
 	
-	LL_DEBUGS() << "notification \"" << mName << "\": tag count is " << p.tags.size() << LL_ENDL;
+	LL_DEBUGS("Notifications") << "notification \"" << mName << "\": tag count is " << p.tags.size() << LL_ENDL;
 	
 	BOOST_FOREACH(const LLNotificationTemplate::Tag& tag, p.tags)
 	{
-		LL_DEBUGS() << "    tag \"" << std::string(tag.value) << "\"" << LL_ENDL;
+		LL_DEBUGS("Notifications") << "    tag \"" << std::string(tag.value) << "\"" << LL_ENDL;
 		mTags.push_back(tag.value);
 	}
 
@@ -1399,8 +1399,14 @@ void LLNotifications::initSingleton()
 	createDefaultChannels();
 }
 
+void LLNotifications::cleanupSingleton()
+{
+    clear();
+}
+
 void LLNotifications::createDefaultChannels()
 {
+    LL_INFOS("Notifications") << "Generating default notification channels" << LL_ENDL;
 	// now construct the various channels AFTER loading the notifications,
 	// because the history channel is going to rewrite the stored notifications file
 	mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "",
@@ -1456,7 +1462,7 @@ void LLNotifications::forceResponse(const LLNotification::Params& params, S32 op
 	
 	if (selected_item.isUndefined())
 	{
-		LL_WARNS() << "Invalid option" << option << " for notification " << (std::string)params.name << LL_ENDL;
+		LL_WARNS("Notifications") << "Invalid option" << option << " for notification " << (std::string)params.name << LL_ENDL;
 		return;
 	}
 	response[selected_item["name"].asString()] = true;
@@ -1490,12 +1496,12 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)
 			if (found != replacements.end())
 			{
 				replacement = found->second;
-				LL_DEBUGS() << "replaceSubstitutionStrings: value: \"" << value << "\" repl: \"" << replacement << "\"." << LL_ENDL;
+				LL_DEBUGS("Notifications") << "replaceSubstitutionStrings: value: \"" << value << "\" repl: \"" << replacement << "\"." << LL_ENDL;
 				it->second->setValue(replacement);
 			}
 			else
 			{
-				LL_WARNS() << "replaceSubstitutionStrings FAILURE: could not find replacement \"" << value << "\"." << LL_ENDL;
+				LL_WARNS("Notifications") << "replaceSubstitutionStrings FAILURE: could not find replacement \"" << value << "\"." << LL_ENDL;
 			}
 		}
 	}
@@ -1534,7 +1540,7 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path
 
 bool LLNotifications::loadTemplates()
 {
-	LL_INFOS() << "Reading notifications template" << LL_ENDL;
+	LL_INFOS("Notifications") << "Reading notifications template" << LL_ENDL;
 	// Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it
 	// output all relevant pathnames instead of just the ones from the most
 	// specific skin.
@@ -1605,7 +1611,7 @@ bool LLNotifications::loadTemplates()
 		mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));
 	}
 
-	LL_INFOS() << "...done" << LL_ENDL;
+	LL_INFOS("Notifications") << "...done" << LL_ENDL;
 
 	return true;
 }
@@ -1833,7 +1839,7 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
 	for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++)
 	{
 		// An empty type/tag/name string will match any notification, so only do the comparison when the string is non-empty in the rule.
-		LL_DEBUGS() 
+		LL_DEBUGS("Notifications")
 			<< "notification \"" << n->getName() << "\" " 
 			<< "testing against " << ((*it)->mVisible?"show":"hide") << " rule, "
 			<< "name = \"" << (*it)->mName << "\" "
@@ -1878,7 +1884,7 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
 			if((*it)->mResponse.empty())
 			{
 				// Response property is empty.  Cancel this notification.
-				LL_DEBUGS() << "cancelling notification " << n->getName() << LL_ENDL;
+				LL_DEBUGS("Notifications") << "cancelling notification " << n->getName() << LL_ENDL;
 
 				cancel(n);
 			}
@@ -1889,7 +1895,7 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
 				// TODO: verify that the response template has an item with the correct name
 				response[(*it)->mResponse] = true;
 
-				LL_DEBUGS() << "responding to notification " << n->getName() << " with response = " << response << LL_ENDL;
+				LL_DEBUGS("Notifications") << "responding to notification " << n->getName() << " with response = " << response << LL_ENDL;
 				
 				n->respond(response);
 			}
@@ -1901,7 +1907,7 @@ bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
 		break;
 	}
 	
-	LL_DEBUGS() << "allowing notification " << n->getName() << LL_ENDL;
+	LL_DEBUGS("Notifications") << "allowing notification " << n->getName() << LL_ENDL;
 
 	return true;
 }
@@ -1962,7 +1968,7 @@ void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
 	// from PE merge - we should figure out if this is the right thing to do
 	if (name.empty())
 	{
-		LL_WARNS() << "Empty name received for Id: " << agent_id << LL_ENDL;
+		LL_WARNS("Notifications") << "Empty name received for Id: " << agent_id << LL_ENDL;
 		name = SYSTEM_FROM;
 	}
 	
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 048f07de9edf98fc671487c281547e36b6a8f7b6..b0b56cf599ff0a4f8ed09181dd3594fbc279b77c 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -958,6 +958,7 @@ class LLNotifications :
 	
 private:
 	/*virtual*/ void initSingleton();
+	/*virtual*/ void cleanupSingleton();
 	
 	void loadPersistentNotifications();
 
@@ -1070,6 +1071,7 @@ class LLPersistentNotificationChannel : public LLNotificationChannel
 	LLPersistentNotificationChannel() 
 		:	LLNotificationChannel("Persistent", "Visible", &notificationFilter)
 	{}
+	virtual ~LLPersistentNotificationChannel() {}
 
 	typedef std::vector<LLNotificationPtr> history_list_t;
 	history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 3b89a8ca6376e4e12261c3b19ad766c729d9fcbd..d80a434f22fb3fa22fba858cb202894d9c7772fd 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -479,6 +479,7 @@ void LLSliderCtrl::onTabInto()
 	{
 		mEditor->onTabInto(); 
 	}
+    LLF32UICtrl::onTabInto();
 }
 
 void LLSliderCtrl::reportInvalidData()
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index ce3fc29d32721a4b147a7d67548b9dc0280f908d..ee78b824295ce7d01ce2ca8b59e165a2d2d6e60e 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -442,7 +442,8 @@ void LLSpinCtrl::setAllowEdit(BOOL allow_edit)
 
 void LLSpinCtrl::onTabInto()
 {
-	mEditor->onTabInto(); 
+	mEditor->onTabInto();
+    LLF32UICtrl::onTabInto();
 }
 
 
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 83b851eed262149c356e4761b8f75513af156a91..30bf938591efa90f182895db5e05717ffee6a979 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1017,7 +1017,38 @@ BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
 	// handle triple click
 	if (!mTripleClickTimer.hasExpired())
 	{
-		selectAll();
+		S32 real_line = getLineNumFromDocIndex(mCursorPos, false);
+		S32 line_start = -1;
+		S32 line_end = -1;
+		for (line_list_t::const_iterator it = mLineInfoList.begin(), end_it = mLineInfoList.end();
+				it != end_it;
+				++it)
+		{
+			if (it->mLineNum < real_line)
+			{
+				continue;
+			}
+			if (it->mLineNum > real_line)
+			{
+				break;
+			}
+			if (line_start == -1)
+			{
+				line_start = it->mDocIndexStart;
+			}
+			line_end = it->mDocIndexEnd;
+			line_end = llclamp(line_end, 0, getLength());
+		}
+
+		if (line_start == -1)
+		{
+			return TRUE;
+		}
+
+		mSelectionEnd = line_start;
+		mSelectionStart = line_end;
+		setCursorPos(line_start);
+
 		return TRUE;
 	}
 
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index c98da0d41043dec1367871be9313a24f4b4030e8..544a76e8d583443a51d4898c8b07fa7dbc9fc05e 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -721,8 +721,9 @@ void LLUICtrl::resetDirty()
 }
 
 // virtual
-void LLUICtrl::onTabInto()				
+void LLUICtrl::onTabInto()
 {
+    onUpdateScrollToChild(this);
 }
 
 // virtual
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index bd213d594a90e250ed20eaca001c081cdc178be6..e3a6a98a9f80749068745906ec58e169e64b4961 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -645,6 +645,16 @@ void LLView::onVisibilityChange ( BOOL new_visibility )
 	}
 }
 
+// virtual
+void LLView::onUpdateScrollToChild(const LLUICtrl * cntrl)
+{
+    LLView* parent_view = getParent();
+    if (parent_view)
+    {
+        parent_view->onUpdateScrollToChild(cntrl);
+    }
+}
+
 // virtual
 void LLView::translate(S32 x, S32 y)
 {
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index db81900aaff267e0d149d76ab712159bd3edc704..5c91c37d3cd7520072de6855f99ad59275473cff 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -301,6 +301,7 @@ class LLView
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 
 	virtual void	onVisibilityChange ( BOOL new_visibility );
+	virtual void	onUpdateScrollToChild(const LLUICtrl * cntrl);
 
 	void			pushVisible(BOOL visible)	{ mLastVisible = mVisible; setVisible(visible); }
 	void			popVisible()				{ setVisible(mLastVisible); }
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 5b9dce02c4bae01ff49dd2f0e13034d51f31264e..d2c5b11c3d1899ff7b3db870eba8bb53083ab004 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -359,10 +359,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
         callRightMouseDown(mMousePos, [theEvent modifierFlags]);
         mSimulatedRightClick = true;
     } else {
-        if ([theEvent clickCount] >= 2)
+        if ([theEvent clickCount] == 2)
         {
             callDoubleClick(mMousePos, [theEvent modifierFlags]);
-        } else if ([theEvent clickCount] == 1) {
+        } else if ([theEvent clickCount] >= 1) {
             callLeftMouseDown(mMousePos, [theEvent modifierFlags]);
         }
     }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8bb5126b91b5b0af4769119b8c33d7e1fc129f63..55c7290c98e3235682ce9f70d59a38a9dfc33fdb 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1620,6 +1620,10 @@ if (WINDOWS)
         # causes those systems to run in a Windows 8 compatibility mode, which works.
         LIST(APPEND viewer_SOURCE_FILES windows.manifest)
     endif (ADDRESS_SIZE EQUAL 64)
+
+    if (OPENAL)
+      LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES})
+    endif (OPENAL)
 endif (WINDOWS)
 
 # Add the xui files. This is handy for searching for xui elements
@@ -1721,6 +1725,12 @@ if (FMODSTUDIO)
 endif (FMODSTUDIO)
 
 set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
+
+if (HAVOK OR HAVOK_TPV)
+  set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_HAVOK")
+endif (HAVOK OR HAVOK_TPV)
+
+# progress view disables/enables icons based on available packages
 set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
 
 list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
@@ -1843,6 +1853,13 @@ if (WINDOWS)
           )
     endif (FMODSTUDIO)
 
+    if (OPENAL)
+      list(APPEND COPY_INPUT_DEPENDENCIES
+           ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/OpenAL32.dll
+           ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/alut.dll
+          )
+    endif (OPENAL)
+
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
@@ -1853,6 +1870,7 @@ if (WINDOWS)
         --artwork=${ARTWORK_DIR}
         "--bugsplat=${BUGSPLAT_DB}"
         "--fmodstudio=${FMODSTUDIO}"
+        "--openal=${OPENAL}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
         "--channel=${VIEWER_CHANNEL}"
@@ -1915,6 +1933,7 @@ if (WINDOWS)
           --artwork=${ARTWORK_DIR}
           "--bugsplat=${BUGSPLAT_DB}"
           "--fmodstudio=${FMODSTUDIO}"
+          "--openal=${OPENAL}"
           --build=${CMAKE_CURRENT_BINARY_DIR}
           --buildtype=${CMAKE_BUILD_TYPE}
           "--channel=${VIEWER_CHANNEL}"
@@ -2062,6 +2081,7 @@ if (LINUX)
         --artwork=${ARTWORK_DIR}
         "--bugsplat=${BUGSPLAT_DB}"
         "--fmodstudio=${FMODSTUDIO}"
+        "--openal=${OPENAL}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
         "--channel=${VIEWER_CHANNEL}"
@@ -2089,6 +2109,7 @@ if (LINUX)
       --artwork=${ARTWORK_DIR}
       "--bugsplat=${BUGSPLAT_DB}"
       "--fmodstudio=${FMODSTUDIO}"
+      "--openal=${OPENAL}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
       "--channel=${VIEWER_CHANNEL}"
@@ -2166,6 +2187,7 @@ if (DARWIN)
       --artwork=${ARTWORK_DIR}
       "--bugsplat=${BUGSPLAT_DB}"
       "--fmodstudio=${FMODSTUDIO}"
+      "--openal=${OPENAL}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
       --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
@@ -2201,6 +2223,7 @@ if (DARWIN)
           --artwork=${ARTWORK_DIR}
           "--bugsplat=${BUGSPLAT_DB}"
           "--fmodstudio=${FMODSTUDIO}"
+          "--openal=${OPENAL}"
           --build=${CMAKE_CURRENT_BINARY_DIR}
           --buildtype=${CMAKE_BUILD_TYPE}
           "--channel=${VIEWER_CHANNEL}"
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 4b20d9700ded7107443a705c0413b347e7ba33ee..b03e20c45679019318972bb0a1883a69c7a2b5d4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.8
+6.4.10
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a00aa86d784df4b1dcf713e604449d43581c251d..8d5a97d1cb3d6092180a0f7fee8b212e684a5173 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -812,17 +812,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>FramePerSecondLimit</key>
-    <map>
-      <key>Comment</key>
-      <string>Controls upper limit of frames per second</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>U32</string>
-      <key>Value</key>
-      <integer>120</integer>
-    </map>
     <key>BackgroundYieldTime</key>
     <map>
       <key>Comment</key>
@@ -14420,7 +14409,7 @@
     <key>VoiceCallsFriendsOnly</key>
     <map>
       <key>Comment</key>
-      <string>Only accept voice calls from residents on your friends list</string>
+      <string>(Deprecated) Only accept voice calls from residents on your friends list</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 5eecf1b9f53b1c8b24752d2137c0ea7dd9d2f5b2..3d77ac43e59bc8497f9a50a568ae3cbb497b6440 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -220,6 +220,17 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
+    <key>VoiceCallsFriendsOnly</key>
+    <map>
+        <key>Comment</key>
+        <string>Only accept voice calls and receive IMs from residents on your friends list</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Boolean</string>
+        <key>Value</key>
+        <integer>0</integer>
+    </map>
     <key>VoiceEffectDefault</key>
     <map>
         <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index caa4fe1f65c5188c9ea15a231fb6165e0956fca9..b7036e02cfcc8f169dcdad32f858f334c79159c5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -1,24 +1,24 @@
-/** 
+/**
  * @file WLCloudsV.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -33,26 +33,26 @@ ATTRIBUTE vec2 texcoord0;
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec4  vary_CloudColorSun;
+VARYING vec4  vary_CloudColorAmbient;
 VARYING float vary_CloudDensity;
 
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
+VARYING vec2  vary_texcoord0;
+VARYING vec2  vary_texcoord1;
+VARYING vec2  vary_texcoord2;
+VARYING vec2  vary_texcoord3;
 VARYING float altitude_blend_factor;
 
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec4  lightnorm;
+uniform vec4  sunlight_color;
+uniform vec4  moonlight_color;
+uniform int   sun_up_factor;
+uniform vec4  ambient_color;
+uniform vec4  blue_horizon;
+uniform vec4  blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -60,7 +60,7 @@ uniform float cloud_shadow;
 uniform float density_multiplier;
 uniform float max_y;
 
-uniform vec4 glow;
+uniform vec4  glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
@@ -70,133 +70,123 @@ uniform float cloud_scale;
 // NOTE: Keep these in sync!
 //       indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
 //       indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+//       indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl
 //       indra\newview\lllegacyatmospherics.cpp
+//       indra\newview\llsettingsvo.cpp
 void main()
 {
-
-	// World / view / projection
-	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
-	// Texture coords
-	vary_texcoord0 = texcoord0;
-	vary_texcoord0.xy -= 0.5;
-	vary_texcoord0.xy /= cloud_scale;
-	vary_texcoord0.xy += 0.5;
-
-	vary_texcoord1 = vary_texcoord0;
-	vary_texcoord1.x += lightnorm.x * 0.0125;
-	vary_texcoord1.y += lightnorm.z * 0.0125;
-
-	vary_texcoord2 = vary_texcoord0 * 16.;
-	vary_texcoord3 = vary_texcoord1 * 16.;
-
-	// Get relative position
-	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
-
-    altitude_blend_factor = clamp((P.y + 512.0) / max_y, 0.0, 1.0);
-
-	// Set altitude
-	if (P.y > 0.)
-	{
-		P *= (max_y / P.y);
-	}
-	else
-	{
-		altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon
-		P *= (-32000. / P.y);
-	}
-
-	// Can normalize then
-	vec3 Pn = normalize(P);
-	float  Plen = length(P);
-
-	// Initialize temp variables
-	vec4 temp1 = vec4(0.);
-	vec4 temp2 = vec4(0.);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	//vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-    float dens_mul = density_multiplier;
-
-	// Sunlight attenuation effect (hue and brightness) due to atmosphere
-	// this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
-
-	// Calculate relative weights
-	temp1 = abs(blue_density) + vec4(abs(haze_density));
-	blue_weight = blue_density / temp1;
-	haze_weight = haze_density / temp1;
-
-	// Compute sunlight from P & lightnorm (for long rays like sky)
-	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Distance
-	temp2.z = Plen * dens_mul;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z);
-
-
-	// Compute haze glow
-	temp2.x = dot(Pn, lightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		// temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .001);	
-		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-    temp2.x *= sun_moon_glow_factor;
-
-	// Add "minimum anti-solar illumination"
-	temp2.x += .25;
-
-	// Increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient_color;
-	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
-
-	// Dim sunlight by cloud shadow percentage
-	sunlight *= (1. - cloud_shadow);
-
-	// Haze color below cloud
-	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-			 );	
-
-	// CLOUDS
-	temp2.y = max(0., lightnorm.y * 2.);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Cloud color out
-	vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
-	vary_CloudColorAmbient = tmpAmbient * cloud_color;
-	
-	// Attenuate cloud color by atmosphere
-	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds
-	vary_CloudColorSun *= temp1;
-	vary_CloudColorAmbient *= temp1;
-	vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
-
-	// Make a nice cloud density based on the cloud_shadow value that was passed in.
-	vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
-
-	// Combine these to minimize register use
-	vary_CloudColorAmbient += oHazeColorBelowCloud;
-
-	// needs this to compile on mac
-	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
-
-	// END CLOUDS
+    // World / view / projection
+    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+    // Texture coords
+    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+    vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y);  // See: LLSettingsVOSky::applySpecial
+
+    vary_texcoord0.xy -= 0.5;
+    vary_texcoord0.xy /= cloud_scale;
+    vary_texcoord0.xy += 0.5;
+
+    vary_texcoord1 = vary_texcoord0;
+    vary_texcoord1.x += lightnorm.x * 0.0125;
+    vary_texcoord1.y += lightnorm.z * 0.0125;
+
+    vary_texcoord2 = vary_texcoord0 * 16.;
+    vary_texcoord3 = vary_texcoord1 * 16.;
+
+    // Get relative position
+    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+    altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
+
+    // Set altitude
+    if (rel_pos.y > 0)
+    {
+        rel_pos *= (max_y / rel_pos.y);
+    }
+    if (rel_pos.y < 0)
+    {
+        altitude_blend_factor = 0;  // SL-11589 Fix clouds drooping below horizon
+        rel_pos *= (-32000. / rel_pos.y);
+    }
+
+    // Can normalize then
+    vec3  rel_pos_norm = normalize(rel_pos);
+    float rel_pos_len  = length(rel_pos);
+
+    // Initialize temp variables
+    vec4 sunlight = sunlight_color;
+    vec4 light_atten;
+
+    // Sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+
+    // Calculate relative weights
+    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+    vec4 blue_weight   = blue_density / combined_haze;
+    vec4 haze_weight   = haze_density / combined_haze;
+
+    // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
+    sunlight *= exp(-light_atten * off_axis);
+
+    // Distance
+    float density_dist = rel_pos_len * density_multiplier;
+
+    // Transparency (-> combined_haze)
+    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+    // compiler gets confused.
+    combined_haze = exp(-combined_haze * density_dist);
+
+    // Compute haze glow
+    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+    // haze_glow is 0 at the sun and increases away from sun
+    haze_glow = max(haze_glow, .001);
+    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    haze_glow *= glow.x;
+    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    haze_glow = pow(haze_glow, glow.z);
+    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+    haze_glow *= sun_moon_glow_factor;
+
+    // Add "minimum anti-solar illumination"
+    // For sun, add to glow.  For moon, remove glow entirely. SL-13768
+    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
+
+    // Increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient_color;
+    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+
+    // Dim sunlight by cloud shadow percentage
+    sunlight *= (1. - cloud_shadow);
+
+    // Haze color below cloud
+    vec4 additiveColorBelowCloud =
+        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
+
+    // CLOUDS
+    off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
+    sunlight *= exp(-light_atten * off_axis);
+
+    // Cloud color out
+    vary_CloudColorSun     = (sunlight * haze_glow) * cloud_color;
+    vary_CloudColorAmbient = tmpAmbient * cloud_color;
+
+    // Attenuate cloud color by atmosphere
+    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
+    vary_CloudColorSun *= combined_haze;
+    vary_CloudColorAmbient *= combined_haze;
+    vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+
+    // Make a nice cloud density based on the cloud_shadow value that was passed in.
+    vary_CloudDensity = 2. * (cloud_shadow - 0.25);
+
+    // Combine these to minimize register use
+    vary_CloudColorAmbient += oHazeColorBelowCloud;
+
+    // needs this to compile on mac
+    // vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+
+    // END CLOUDS
 }
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index bd0ad3bce80bf49604cb1eccd97b81dc841fccba..6b36d00f97e504b57a33e0b9f7c31b3bccfbab89 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -42,6 +42,9 @@ VARYING vec4 vary_position;
 
 uniform samplerCube environmentMap;
 
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
+
 vec3 fullbrightShinyAtmosTransport(vec3 light);
 vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
 vec3 fullbrightScaleSoftClip(vec3 light);
@@ -51,7 +54,9 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
 vec3 linear_to_srgb(vec3 c);
 vec3 srgb_to_linear(vec3 c);
 
-
+// See:
+//   class1\deferred\fullbrightShinyF.glsl
+//   class1\lighting\lightFullbrightShinyF.glsl
 void main()
 {
 #ifdef HAS_DIFFUSE_LOOKUP
@@ -59,25 +64,39 @@ void main()
 #else
 	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
 #endif
-	
+
 	color.rgb *= vertex_color.rgb;
-	vec3 pos = vary_position.xyz/vary_position.w;
 
-	vec3 sunlit;
-	vec3 amblit;
-	vec3 additive;
-	vec3 atten;
+	// SL-9632 HUDs are affected by Atmosphere
+	if (no_atmo == 0)
+	{
+		vec3 sunlit;
+		vec3 amblit;
+		vec3 additive;
+		vec3 atten;
+		vec3 pos = vary_position.xyz/vary_position.w;
+
+		calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
 
-	calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
-	
-	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
-	float env_intensity = vertex_color.a;
-	color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
+		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+		float env_intensity = vertex_color.a;
 
 	//color.rgb = srgb_to_linear(color.rgb);
-	
-	color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
-	color.rgb = fullbrightScaleSoftClip(color.rgb);
+		color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
+
+		color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
+		color.rgb = fullbrightScaleSoftClip(color.rgb);
+	}
+
+/*
+	// NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
+	else
+	{
+		vec3  envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+		float env_intensity = vertex_color.a;
+		color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
+	}
+*/
 
 	color.a = 1.0;
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 0afd1a96720e026652903eeb17057c4173e187d2..80d19102b6ce957d0e8defa72d93bbcd77617322 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -1,439 +1,443 @@
-/**
-* @file materialF.glsl
-*
-* $LicenseInfo:firstyear=2007&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2007, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-* $/LicenseInfo$
-*/
-
-/*[EXTRA_CODE_HERE]*/
-
-//class1/deferred/materialF.glsl
-
-// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
-
-#define DIFFUSE_ALPHA_MODE_NONE     0
-#define DIFFUSE_ALPHA_MODE_BLEND    1
-#define DIFFUSE_ALPHA_MODE_MASK     2
-#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-
-uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise
-uniform int sun_up_factor;
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-vec3 srgb_to_linear(vec3 cs);
-vec3 linear_to_srgb(vec3 cs);
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-#ifdef HAS_SUN_SHADOW
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-#endif
-
-uniform samplerCube environmentMap;
-uniform sampler2D     lightFunc;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform mat3 env_mat;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-VARYING vec2 vary_fragcoord;
-
-VARYING vec3 vary_position;
-
-uniform mat4 proj_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float getAmbientClamp();
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
-{
-    vec3 col = vec3(0);
-
-    //get light vector
-    vec3 lv = lp.xyz - v;
-
-    //get distance
-    float dist = length(lv);
-    float da = 1.0;
-
-    dist /= la;
-
-    if (dist > 0.0 && la > 0.0)
-    {
-        //normalize light vector
-        lv = normalize(lv);
-
-        //distance attenuation
-        float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
-        dist_atten *= dist_atten;
-        dist_atten *= 2.0f;
-
-        if (dist_atten <= 0.0)
-        {
-            return col;
-        }
-
-        // spotlight coefficient.
-        float spot = max(dot(-ln, lv), is_pointlight);
-        da *= spot*spot; // GL_SPOT_EXPONENT=2
-
-        //angular attenuation
-        da *= dot(n, lv);
-
-        float lit = 0.0f;
-
-        float amb_da = ambiance;
-        if (da >= 0)
-        {
-            lit = max(da * dist_atten, 0.0);
-            col = lit * light_col * diffuse;
-            amb_da += (da*0.5 + 0.5) * ambiance;
-        }
-        amb_da += (da*da*0.5 + 0.5) * ambiance;
-        amb_da *= dist_atten;
-        amb_da = min(amb_da, 1.0f - lit);
-
-        // SL-10969 need to see why these are blown out
-        //col.rgb += amb_da * light_col * diffuse;
-
-        if (spec.a > 0.0)
-        {
-            //vec3 ref = dot(pos+lv, norm);
-            vec3 h = normalize(lv + npos);
-            float nh = dot(n, h);
-            float nv = dot(n, npos);
-            float vh = dot(npos, h);
-            float sa = nh;
-            float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
-            float gtdenom = 2 * nh;
-            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
-            if (nh > 0.0)
-            {
-                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
-                vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
-                speccol = clamp(speccol, vec3(0), vec3(1));
-                col += speccol;
-
-                float cur_glare = max(speccol.r, speccol.g);
-                cur_glare = max(cur_glare, speccol.b);
-                glare = max(glare, speccol.r);
-                glare += max(cur_glare, 0.0);
-            }
-        }
-    }
-
-    return max(col, vec3(0.0, 0.0, 0.0));
-}
-
-#else
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-#endif
-
-uniform sampler2D diffuseMap;  //always in sRGB space
-
-#ifdef HAS_NORMAL_MAP
-uniform sampler2D bumpMap;
-#endif
-
-#ifdef HAS_SPECULAR_MAP
-uniform sampler2D specularMap;
-
-VARYING vec2 vary_texcoord2;
-#endif
-
-uniform float env_intensity;
-uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-uniform float minimum_alpha;
-#endif
-
-#ifdef HAS_NORMAL_MAP
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec2 vary_texcoord1;
-#else
-VARYING vec3 vary_normal;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec2 encode_normal(vec3 n);
-
-void main()
-{
-    vec2 pos_screen = vary_texcoord0.xy;
-
-    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
-	diffcol.rgb *= vertex_color.rgb;
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-
-    // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
-    float bias = 0.001953125; // 1/512, or half an 8-bit quantization
-    if (diffcol.a < minimum_alpha-bias)
-    {
-        discard;
-    }
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-	vec3 gamma_diff = diffcol.rgb;
-	diffcol.rgb = srgb_to_linear(diffcol.rgb);
-#endif
-
-#ifdef HAS_SPECULAR_MAP
-    vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
-    spec.rgb *= specular_color.rgb;
-#else
-    vec4 spec = vec4(specular_color.rgb, 1.0);
-#endif
-
-#ifdef HAS_NORMAL_MAP
-	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
-	norm.xyz = norm.xyz * 2 - 1;
-
-	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
-			  dot(norm.xyz,vary_mat1),
-			  dot(norm.xyz,vary_mat2));
-#else
-	vec4 norm = vec4(0,0,0,1.0);
-	vec3 tnorm = vary_normal;
-#endif
-
-    norm.xyz = normalize(tnorm.xyz);
-
-    vec2 abnormal = encode_normal(norm.xyz);
-
-    vec4 final_color = diffcol;
-
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
-	final_color.a = emissive_brightness;
-#else
-	final_color.a = max(final_color.a, emissive_brightness);
-#endif
-
-    vec4 final_specular = spec;
-    
-#ifdef HAS_SPECULAR_MAP
-    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
-	final_specular.a = specular_color.a * norm.a;
-#else
-	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
-	final_specular.a = specular_color.a;
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-    //forward rendering, output just lit sRGBA
-    vec3 pos = vary_position;
-
-    float shadow = 1.0f;
-
-#ifdef HAS_SUN_SHADOW
-    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
-#endif
-
-    spec = final_specular;
-    vec4 diffuse = final_color;
-    float envIntensity = final_normal.z;
-
-    vec3 color = vec3(0,0,0);
-
-    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
-
-    float bloom = 0.0;
-    vec3 sunlit;
-    vec3 amblit;
-    vec3 additive;
-    vec3 atten;
-
-    calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
-    
-        // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020)
-        // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level
-        // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage
-        //color = fullbrightScaleSoftClip(color);
-
-    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
-    //we're in sRGB space, so gamma correct this dot product so 
-    // lighting from the sun stays sharp
-    float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0);
-    da = pow(da, 1.0 / 1.3);
-
-    color = amblit;
-
-    //darken ambient for normals perpendicular to light vector so surfaces in shadow 
-    // and facing away from light still have some definition to them.
-    // do NOT gamma correct this dot product so ambient lighting stays soft
-    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
-    ambient *= 0.5;
-    ambient *= ambient;
-    ambient = (1.0 - ambient);
-
-    vec3 sun_contrib = min(da, shadow) * sunlit;
-    
-    color *= ambient;
-
-    color += sun_contrib;
-
-    color *= gamma_diff.rgb;
-
-    float glare = 0.0;
-
-    if (spec.a > 0.0) // specular reflection
-    {
-#if 1 //EEP
-
-        vec3 npos = -normalize(pos.xyz);
-
-        //vec3 ref = dot(pos+lv, norm);
-        vec3 h = normalize(light_dir.xyz + npos);
-        float nh = dot(norm.xyz, h);
-        float nv = dot(norm.xyz, npos);
-        float vh = dot(npos, h);
-        float sa = nh;
-        float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
-        float gtdenom = 2 * nh;
-        float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
-        if (nh > 0.0)
-        {
-            float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
-            vec3 sp = sun_contrib*scol / 6.0f;
-            sp = clamp(sp, vec3(0), vec3(1));
-            bloom = dot(sp, sp) / 4.0;
-            color += sp * spec.rgb;
-        }
-#else // PRODUCTION
-        float sa = dot(refnormpersp, sun_dir.xyz);
-		vec3 dumbshiny = sunlit*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-							
-		// add the two types of shiny together
-		vec3 spec_contrib = dumbshiny * spec.rgb;
-		bloom = dot(spec_contrib, spec_contrib) / 6;
-
-		glare = max(spec_contrib.r, spec_contrib.g);
-		glare = max(glare, spec_contrib.b);
-
-		color += spec_contrib;
-#endif
-    }
-
-    color = mix(color.rgb, diffcol.rgb, diffuse.a);
-    
-    if (envIntensity > 0.0)
-    {
-        //add environmentmap
-        vec3 env_vec = env_mat * refnormpersp;
-
-        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
-
-        color = mix(color, reflected_color, envIntensity);
-
-        float cur_glare = max(reflected_color.r, reflected_color.g);
-        cur_glare = max(cur_glare, reflected_color.b);
-        cur_glare *= envIntensity*4.0;
-        glare += cur_glare;
-    }
-
-    color = atmosFragLighting(color, additive, atten);
-    color = scaleSoftClipFrag(color);
-
-    //convert to linear before adding local lights
-    color = srgb_to_linear(color);
-
-    vec3 npos = normalize(-pos.xyz);
-
-    vec3 light = vec3(0, 0, 0);
-    
-#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
-
-    LIGHT_LOOP(1)
-        LIGHT_LOOP(2)
-        LIGHT_LOOP(3)
-        LIGHT_LOOP(4)
-        LIGHT_LOOP(5)
-        LIGHT_LOOP(6)
-        LIGHT_LOOP(7)
-
-    color += light;
-
-    glare = min(glare, 1.0);
-    float al = max(diffcol.a, glare)*vertex_color.a;
-
-    //convert to srgb as this color is being written post gamma correction
-    color = linear_to_srgb(color);
-
-#ifdef WATER_FOG
-    vec4 temp = applyWaterFogView(pos, vec4(color, al));
-    color = temp.rgb;
-    al = temp.a;
-#endif
-
-    frag_color = vec4(color, al);
-
-#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer 
-
-    // deferred path
-    frag_data[0] = final_color; //gbuffer is sRGB
-    frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
-    frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.
-#endif
-}
-
+/**
+* @file materialF.glsl
+*
+* $LicenseInfo:firstyear=2007&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2007, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+//class1/deferred/materialF.glsl
+
+// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
+
+#define DIFFUSE_ALPHA_MODE_NONE     0
+#define DIFFUSE_ALPHA_MODE_BLEND    1
+#define DIFFUSE_ALPHA_MODE_MASK     2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise
+uniform int sun_up_factor;
+
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
+#endif
+
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFrag(vec3 l);
+
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cs);
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+uniform samplerCube environmentMap;
+uniform sampler2D     lightFunc;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+uniform mat3 env_mat;
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+VARYING vec2 vary_fragcoord;
+
+VARYING vec3 vary_position;
+
+uniform mat4 proj_mat;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec4 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+float getAmbientClamp();
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
+{
+    vec3 col = vec3(0);
+
+    //get light vector
+    vec3 lv = lp.xyz - v;
+
+    //get distance
+    float dist = length(lv);
+    float da = 1.0;
+
+    dist /= la;
+
+    if (dist > 0.0 && la > 0.0)
+    {
+        //normalize light vector
+        lv = normalize(lv);
+
+        //distance attenuation
+        float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
+        dist_atten *= dist_atten;
+        dist_atten *= 2.0f;
+
+        if (dist_atten <= 0.0)
+        {
+            return col;
+        }
+
+        // spotlight coefficient.
+        float spot = max(dot(-ln, lv), is_pointlight);
+        da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+        //angular attenuation
+        da *= dot(n, lv);
+
+        float lit = 0.0f;
+
+        float amb_da = ambiance;
+        if (da >= 0)
+        {
+            lit = max(da * dist_atten, 0.0);
+            col = lit * light_col * diffuse;
+            amb_da += (da*0.5 + 0.5) * ambiance;
+        }
+        amb_da += (da*da*0.5 + 0.5) * ambiance;
+        amb_da *= dist_atten;
+        amb_da = min(amb_da, 1.0f - lit);
+
+        // SL-10969 need to see why these are blown out
+        //col.rgb += amb_da * light_col * diffuse;
+
+        if (spec.a > 0.0)
+        {
+            //vec3 ref = dot(pos+lv, norm);
+            vec3 h = normalize(lv + npos);
+            float nh = dot(n, h);
+            float nv = dot(n, npos);
+            float vh = dot(npos, h);
+            float sa = nh;
+            float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
+
+            float gtdenom = 2 * nh;
+            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+            if (nh > 0.0)
+            {
+                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
+                vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
+                speccol = clamp(speccol, vec3(0), vec3(1));
+                col += speccol;
+
+                float cur_glare = max(speccol.r, speccol.g);
+                cur_glare = max(cur_glare, speccol.b);
+                glare = max(glare, speccol.r);
+                glare += max(cur_glare, 0.0);
+            }
+        }
+    }
+
+    return max(col, vec3(0.0, 0.0, 0.0));
+}
+
+#else
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+#endif
+
+uniform sampler2D diffuseMap;  //always in sRGB space
+
+#ifdef HAS_NORMAL_MAP
+uniform sampler2D bumpMap;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+uniform sampler2D specularMap;
+
+VARYING vec2 vary_texcoord2;
+#endif
+
+uniform float env_intensity;
+uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+uniform float minimum_alpha;
+#endif
+
+#ifdef HAS_NORMAL_MAP
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+vec2 encode_normal(vec3 n);
+
+void main()
+{
+    vec2 pos_screen = vary_texcoord0.xy;
+
+    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+	diffcol.rgb *= vertex_color.rgb;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+
+    // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
+    float bias = 0.001953125; // 1/512, or half an 8-bit quantization
+    if (diffcol.a < minimum_alpha-bias)
+    {
+        discard;
+    }
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+	vec3 gamma_diff = diffcol.rgb;
+	diffcol.rgb = srgb_to_linear(diffcol.rgb);
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+    vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
+    spec.rgb *= specular_color.rgb;
+#else
+    vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+
+#ifdef HAS_NORMAL_MAP
+	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+
+	norm.xyz = norm.xyz * 2 - 1;
+
+	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+			  dot(norm.xyz,vary_mat1),
+			  dot(norm.xyz,vary_mat2));
+#else
+	vec4 norm = vec4(0,0,0,1.0);
+	vec3 tnorm = vary_normal;
+#endif
+
+    norm.xyz = normalize(tnorm.xyz);
+
+    vec2 abnormal = encode_normal(norm.xyz);
+
+    vec4 final_color = diffcol;
+
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+	final_color.a = emissive_brightness;
+#else
+	final_color.a = max(final_color.a, emissive_brightness);
+#endif
+
+    vec4 final_specular = spec;
+    
+#ifdef HAS_SPECULAR_MAP
+    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
+	final_specular.a = specular_color.a * norm.a;
+#else
+	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
+	final_specular.a = specular_color.a;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+    //forward rendering, output just lit sRGBA
+    vec3 pos = vary_position;
+
+    float shadow = 1.0f;
+
+#ifdef HAS_SUN_SHADOW
+    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
+#endif
+
+    spec = final_specular;
+    vec4 diffuse = final_color;
+    float envIntensity = final_normal.z;
+
+    vec3 color = vec3(0,0,0);
+
+    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+
+    float bloom = 0.0;
+    vec3 sunlit;
+    vec3 amblit;
+    vec3 additive;
+    vec3 atten;
+
+    calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
+    
+        // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020)
+        // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level
+        // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage
+        //color = fullbrightScaleSoftClip(color);
+
+    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+    //we're in sRGB space, so gamma correct this dot product so 
+    // lighting from the sun stays sharp
+    float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0);
+    da = pow(da, 1.0 / 1.3);
+
+    color = amblit;
+
+    //darken ambient for normals perpendicular to light vector so surfaces in shadow 
+    // and facing away from light still have some definition to them.
+    // do NOT gamma correct this dot product so ambient lighting stays soft
+    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+    ambient *= 0.5;
+    ambient *= ambient;
+    ambient = (1.0 - ambient);
+
+    vec3 sun_contrib = min(da, shadow) * sunlit;
+    
+    color *= ambient;
+
+    color += sun_contrib;
+
+    color *= gamma_diff.rgb;
+
+    float glare = 0.0;
+
+    if (spec.a > 0.0)  // specular reflection
+    {
+        /*  // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020
+            // Preserving the refactored version as a comment for potential reconsideration,
+            // overriding the general rule to avoid pollutiong the source with commented code.
+            //
+            //  If you're reading this in 2021+, feel free to obliterate.
+
+        vec3 npos = -normalize(pos.xyz);
+
+        //vec3 ref = dot(pos+lv, norm);
+        vec3 h = normalize(light_dir.xyz + npos);
+        float nh = dot(norm.xyz, h);
+        float nv = dot(norm.xyz, npos);
+        float vh = dot(npos, h);
+        float sa = nh;
+        float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
+
+        float gtdenom = 2 * nh;
+        float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+        if (nh > 0.0)
+        {
+            float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
+            vec3 sp = sun_contrib*scol / 6.0f;
+            sp = clamp(sp, vec3(0), vec3(1));
+            bloom = dot(sp, sp) / 4.0;
+            color += sp * spec.rgb;
+        }
+        */
+
+        float sa        = dot(refnormpersp, sun_dir.xyz);
+        vec3  dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r);
+
+        // add the two types of shiny together
+        vec3 spec_contrib = dumbshiny * spec.rgb;
+        bloom             = dot(spec_contrib, spec_contrib) / 6;
+
+        glare = max(spec_contrib.r, spec_contrib.g);
+        glare = max(glare, spec_contrib.b);
+
+        color += spec_contrib;
+    }
+
+    color = mix(color.rgb, diffcol.rgb, diffuse.a);
+
+    if (envIntensity > 0.0)
+    {
+        //add environmentmap
+        vec3 env_vec = env_mat * refnormpersp;
+
+        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
+
+        color = mix(color, reflected_color, envIntensity);
+
+        float cur_glare = max(reflected_color.r, reflected_color.g);
+        cur_glare = max(cur_glare, reflected_color.b);
+        cur_glare *= envIntensity*4.0;
+        glare += cur_glare;
+    }
+
+    color = atmosFragLighting(color, additive, atten);
+    color = scaleSoftClipFrag(color);
+
+    //convert to linear before adding local lights
+    color = srgb_to_linear(color);
+
+    vec3 npos = normalize(-pos.xyz);
+
+    vec3 light = vec3(0, 0, 0);
+    
+#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
+
+    LIGHT_LOOP(1)
+        LIGHT_LOOP(2)
+        LIGHT_LOOP(3)
+        LIGHT_LOOP(4)
+        LIGHT_LOOP(5)
+        LIGHT_LOOP(6)
+        LIGHT_LOOP(7)
+
+    color += light;
+
+    glare = min(glare, 1.0);
+    float al = max(diffcol.a, glare)*vertex_color.a;
+
+    //convert to srgb as this color is being written post gamma correction
+    color = linear_to_srgb(color);
+
+#ifdef WATER_FOG
+    vec4 temp = applyWaterFogView(pos, vec4(color, al));
+    color = temp.rgb;
+    al = temp.a;
+#endif
+
+    frag_color = vec4(color, al);
+
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer 
+
+    // deferred path
+    frag_data[0] = final_color; //gbuffer is sRGB
+    frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
+    frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 80f232948acd4a3d1bdc4e60e83c95d555c36941..35068899eee45503ed2f943e4589c93cf9546eda 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -1,9 +1,9 @@
 /** 
- * @file moonF.glsl
+ * @file class1\deferred\moonF.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2005, 2020 Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,34 +36,33 @@ out vec4 frag_data[3];
 uniform vec4 color;
 uniform vec4 sunlight_color;
 uniform vec4 moonlight_color;
-uniform vec3 lumWeights;
+uniform vec3 moon_dir;
 uniform float moon_brightness;
-uniform float minLuminance;
 uniform sampler2D diffuseMap;
-uniform sampler2D altDiffuseMap;
-uniform float blend_factor; // interp factor between moon A/B
+
 VARYING vec2 vary_texcoord0;
 
 vec3 srgb_to_linear(vec3 c);
-void main() 
-{
-    vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
-    vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
-    vec4 c     = mix(moonA, moonB, blend_factor);
 
-    c.rgb = srgb_to_linear(c.rgb);
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light);
 
-    // mix factor which blends when sunlight is brighter
-    // and shows true moon color at night
-    vec3 luma_weights = vec3(0.3, 0.5, 0.3);
+void main() 
+{
+    // Restore Pre-EEP alpha fade moon near horizon
+    float fade = 1.0;
+    if( moon_dir.z > 0 )
+        fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
 
-    vec4 light_color = max(sunlight_color, moonlight_color);
-    float mix = 1.0 - dot(normalize(light_color.rgb), luma_weights);
+    vec4 c      = texture2D(diffuseMap, vary_texcoord0.xy);
+//       c.rgb  = srgb_to_linear(c.rgb);
+         c.rgb *= moonlight_color.rgb;
+         c.rgb *= moon_brightness;
 
-    vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0  - 1.0;
-    c.rgb = pow(c.rgb, exp);
+         c.rgb *= fade;
+         c.a   *= fade;
 
-    //c.rgb *= moonlight_color.rgb;
+         c.rgb  = scaleSoftClip(c.rgb);
 
     frag_data[0] = vec4(c.rgb, c.a);
     frag_data[1] = vec4(0.0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
index e1bac4f248081f80740689aaf4399f36d9c9cf2b..c4922afd7d5e54afaa8449599042859be6da7a8f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
@@ -1,9 +1,9 @@
 /** 
- * @file moonV.glsl
+ * @file class1\deferred\moonV.glsl
  *
   * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2007, 2020 Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -32,18 +32,13 @@ ATTRIBUTE vec2 texcoord0;
 
 VARYING vec2 vary_texcoord0;
 
-void calcAtmospherics(vec3 eye_pos);
-
 void main()
 {
     //transform vertex
-    vec3 offset = vec3(0, 0, 50);
-    vec4 vert = vec4(position.xyz - offset, 1.0);
+    vec4 vert = vec4(position.xyz, 1.0);
     vec4 pos = (modelview_matrix * vert);
 
     gl_Position = modelview_projection_matrix*vert;
 
-    calcAtmospherics(pos.xyz);
-    
     vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 0d1cc817866ad5d07da80ed3a1f251888808bb29..8c402fcb5466f54b229074e4498326d370085c67 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -1,24 +1,24 @@
-/** 
- * @file multiPointLightF.glsl
+/**
+ * @file class1/deferred/multiPointLightF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -36,119 +36,112 @@ out vec4 frag_color;
 uniform sampler2DRect depthMap;
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
-uniform samplerCube environmentMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
+uniform samplerCube   environmentMap;
+uniform sampler2D     noiseMap;
+uniform sampler2D     lightFunc;
 
-
-uniform vec3 env_mat[3];
+uniform vec3  env_mat[3];
 uniform float sun_wash;
+uniform int   light_count;
+uniform vec4  light[LIGHT_COUNT];
+uniform vec4  light_col[LIGHT_COUNT];
 
-uniform int light_count;
-
-uniform vec4 light[LIGHT_COUNT];
-uniform vec4 light_col[LIGHT_COUNT];
-
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
+uniform vec2  screen_res;
 uniform float far_z;
+uniform mat4  inv_proj;
 
-uniform mat4 inv_proj;
+VARYING vec4 vary_fragcoord;
 
 vec4 getPosition(vec2 pos_screen);
 vec3 getNorm(vec2 pos_screen);
 vec3 srgb_to_linear(vec3 c);
 
-void main() 
+void main()
 {
-	vec3 out_col = vec3(0,0,0);
-
 #if defined(LOCAL_LIGHT_KILL)
-    discard;
-#else
-	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
-	vec3 pos = getPosition(frag.xy).xyz;
-	if (pos.z < far_z)
-	{
-		discard;
-	}
-	
-	vec3 norm = getNorm(frag.xy);
-
-	vec4 spec = texture2DRect(specularRect, frag.xy);
-	vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
-    diff.rgb = srgb_to_linear(diff.rgb);
-	
-	float noise = texture2D(noiseMap, frag.xy/128.0).b;
-	vec3 npos = normalize(-pos);
-
-	// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
-	for (int i = 0; i < LIGHT_COUNT; ++i)
-	{
-		vec3 lv = light[i].xyz-pos;
-		float dist = length(lv);
-		dist /= light[i].w;
-		if (dist <= 1.0)
-		{
-		float da = dot(norm, lv);
-			if (da > 0.0)
-		{
-			lv = normalize(lv);
-			da = dot(norm, lv);
-			
-			float fa = light_col[i].a+1.0;
-			float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
-			dist_atten *= dist_atten;
-            
-            // Tweak falloff slightly to match pre-EEP attenuation
-			// NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit
-			dist_atten *= 2.0;
-			
-			dist_atten *= noise;
-
-			float lit = da * dist_atten;
-						
-			vec3 col = light_col[i].rgb*lit*diff;
-			
-			//vec3 col = vec3(dist2, light_col[i].a, lit);
-			
-			if (spec.a > 0.0)
-			{
-				lit = min(da*6.0, 1.0) * dist_atten;
-				//vec3 ref = dot(pos+lv, norm);
-				vec3 h = normalize(lv+npos);
-				float nh = dot(norm, h);
-				float nv = dot(norm, npos);
-				float vh = dot(npos, h);
-				float sa = nh;
-				float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
-				float gtdenom = 2 * nh;
-				float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-								
-				if (nh > 0.0)
-				{
-					float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
-					col += lit*scol*light_col[i].rgb*spec.rgb;
-					//col += spec.rgb;
-				}
-			}
-			
-			out_col += col;
-		}
-	}
-	}
+    discard;  // Bail immediately
 #endif
-	
-	frag_color.rgb = out_col;
-	frag_color.a = 0.0;
+
+    vec3 out_col = vec3(0, 0, 0);
+    vec2 frag    = (vary_fragcoord.xy * 0.5 + 0.5) * screen_res;
+    vec3 pos     = getPosition(frag.xy).xyz;
+    if (pos.z < far_z)
+    {
+        discard;
+    }
+
+    vec3 norm = getNorm(frag.xy);
+
+    vec4 spec = texture2DRect(specularRect, frag.xy);
+    spec.rgb  = srgb_to_linear(spec.rgb);
+    vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
+    diff.rgb  = srgb_to_linear(diff.rgb);
+
+    float noise = texture2D(noiseMap, frag.xy / 128.0).b;
+    vec3  npos  = normalize(-pos);
+
+    // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
+    for (int i = 0; i < LIGHT_COUNT; ++i)
+    {
+        vec3  lv   = light[i].xyz - pos;
+        float dist = length(lv);
+        dist /= light[i].w;
+        if (dist <= 1.0)
+        {
+            float da = dot(norm, lv);
+            if (da > 0.0)
+            {
+                lv = normalize(lv);
+                da = dot(norm, lv);
+
+                float fa         = light_col[i].a + 1.0;
+                float dist_atten = clamp(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 0.0, 1.0);
+                dist_atten *= dist_atten;
+
+                // Tweak falloff slightly to match pre-EEP attenuation
+                // NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit
+                dist_atten *= 2.0;
+
+                dist_atten *= noise;
+
+                float lit = da * dist_atten;
+
+                vec3 col = light_col[i].rgb * lit * diff;
+
+                if (spec.a > 0.0)
+                {
+                    lit        = min(da * 6.0, 1.0) * dist_atten;
+                    vec3  h    = normalize(lv + npos);
+                    float nh   = dot(norm, h);
+                    float nv   = dot(norm, npos);
+                    float vh   = dot(npos, h);
+                    float sa   = nh;
+                    float fres = pow(1 - dot(h, npos), 5) * 0.4 + 0.5;
+
+                    float gtdenom = 2 * nh;
+                    float gt      = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+                    if (nh > 0.0)
+                    {
+                        float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * da);
+                        col += lit * scol * light_col[i].rgb * spec.rgb;
+                    }
+                }
+
+                out_col += col;
+            }
+        }
+    }
+
+    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];
+    // 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/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index ead754ec76184e1ef81c3aed376c1329ebbac909..28a1faf24f75c47a3991d47b7a2b7e1d83731bc4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -1,24 +1,24 @@
-/** 
+/**
  * @file WLSkyV.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -37,13 +37,13 @@ VARYING vec4 vary_HazeColor;
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec4  lightnorm;
+uniform vec4  sunlight_color;
+uniform vec4  moonlight_color;
+uniform int   sun_up_factor;
+uniform vec4  ambient_color;
+uniform vec4  blue_horizon;
+uniform vec4  blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -52,7 +52,7 @@ uniform float density_multiplier;
 uniform float distance_multiplier;
 uniform float max_y;
 
-uniform vec4 glow;
+uniform vec4  glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
@@ -63,103 +63,91 @@ uniform vec4 cloud_color;
 //       indra\newview\lllegacyatmospherics.cpp
 void main()
 {
-
-	// World / view / projection
+    // World / view / projection
     vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
-	gl_Position = pos;
-	
-	// Get relative position
-	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
-
-	// Set altitude
-	if (P.y > 0.)
-	{
-		P *= (max_y / P.y);
-	}
-	else
-	{
-		P *= (-32000. / P.y);
-	}
-
-	// Can normalize then
-	vec3 Pn = normalize(P);
-
-	float Plen = length(P);
-
-	// Initialize temp variables
-	vec4 temp1 = vec4(0.);
-	vec4 temp2 = vec4(0.);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-	vec4 light_atten;
-
-    float dens_mul = density_multiplier;
-
-	// Sunlight attenuation effect (hue and brightness) due to atmosphere
-	// this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
-
-	// Calculate relative weights
-	temp1 = abs(blue_density) + vec4(abs(haze_density));
-	blue_weight = blue_density / temp1;
-	haze_weight = haze_density / temp1;
-
-	// Compute sunlight from P & lightnorm (for long rays like sky)
-    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-    temp2.y = 1. / temp2.y;
-    sunlight *= exp( - light_atten * temp2.y);
-
-	// Distance
-	temp2.z = Plen * dens_mul;
-
-	// Transparency (-> temp1)
-    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
-    // compiler gets confused.
-    temp1 = exp(-temp1 * temp2.z);
+    gl_Position = pos;
+
+    // Get relative position
+    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+    // Adj position vector to clamp altitude
+    if (rel_pos.y > 0)
+    {
+        rel_pos *= (max_y / rel_pos.y);
+    }
+    if (rel_pos.y < 0)
+    {
+        rel_pos *= (-32000. / rel_pos.y);
+    }
+
+    // Can normalize then
+    vec3 rel_pos_norm = normalize(rel_pos);
 
-	// Compute haze glow
-	temp2.x = dot(Pn, lightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		// temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .001);	
-		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
+    float rel_pos_len = length(rel_pos);
 
-	// Add "minimum anti-solar illumination"
-	temp2.x += .25;
+    // Initialize temp variables
+    vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+    vec4 light_atten;
 
-    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient_color)
-                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color)
-             );
+    // Sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
 
+    // Calculate relative weights
+    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+    vec4 blue_weight   = blue_density / combined_haze;
+    vec4 haze_weight   = haze_density / combined_haze;
+
+    // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
+    sunlight *= exp(-light_atten * off_axis);
+
+    // Distance
+    float density_dist = rel_pos_len * density_multiplier;
+
+    // Transparency (-> combined_haze)
+    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+    // compiler gets confused.
+    combined_haze = exp(-combined_haze * density_dist);
+
+    // Compute haze glow
+    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+    // haze_glow is 0 at the sun and increases away from sun
+    haze_glow = max(haze_glow, .001);
+    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    haze_glow *= glow.x;
+    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    haze_glow = pow(haze_glow, glow.z);
+    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+    // Add "minimum anti-solar illumination"
+    // For sun, add to glow.  For moon, remove glow entirely. SL-13768
+    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
+
+    vec4 color =
+        (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
 
     // Final atmosphere additive
-    color *= (1. - temp1);
+    color *= (1. - combined_haze);
 
-	// Increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient_color;
-	tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; 
+    // Increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient_color;
+    tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
 
-	// Dim sunlight by cloud shadow percentage
-	sunlight *= max(0.0, (1. - cloud_shadow));
+    // Dim sunlight by cloud shadow percentage
+    sunlight *= max(0.0, (1. - cloud_shadow));
 
-	// Haze color below cloud
-	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-			 );	
+    // Haze color below cloud
+    vec4 additiveColorBelowCloud =
+        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
 
-	// Attenuate cloud color by atmosphere
-	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds
+    // Attenuate cloud color by atmosphere
+    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
 
-	// At horizon, blend high altitude sky color towards the darker color below the clouds
-	color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
+    // At horizon, blend high altitude sky color towards the darker color below the clouds
+    color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
 
     // Haze color above cloud
-	vary_HazeColor = color;	
+    vary_HazeColor = color;
 }
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index a5804220bc069a0ac8dca479953699e454e1ad16..f80f1a985a31a9ea796e2d47d3fef08939831e03 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -124,41 +124,15 @@ void main()
 
         if (spec.a > 0.0) // specular reflection
         {
+            float sa        = dot(refnormpersp, light_dir.xyz);
+            vec3  dumbshiny = sunlit * (texture2D(lightFunc, vec2(sa, spec.a)).r);
 
-#if 1 //EEP
-            vec3 npos = -normalize(pos.xyz);
-
-            //vec3 ref = dot(pos+lv, norm);
-            vec3 h = normalize(light_dir.xyz+npos);
-            float nh = dot(norm.xyz, h);
-            float nv = dot(norm.xyz, npos);
-            float vh = dot(npos, h);
-            float sa = nh;
-            float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
-            float gtdenom = 2 * nh;
-            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-            
-            if (nh > 0.0)
-            {
-                float scontrib = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
-                vec3 sp = sun_contrib*scontrib / 6.0;
-                sp = clamp(sp, vec3(0), vec3(1));
-                bloom += dot(sp, sp) / 4.0;
-                color += sp * spec.rgb;
-            }
-#else //PRODUCTION
-            float sa = dot(refnormpersp, light_dir.xyz);
-            vec3 dumbshiny = sunlit*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-            
             // add the two types of shiny together
             vec3 spec_contrib = dumbshiny * spec.rgb;
-            bloom = dot(spec_contrib, spec_contrib) / 6;
+            bloom             = dot(spec_contrib, spec_contrib) / 6;
             color.rgb += spec_contrib;
-#endif
-
         }
-       
+
        color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
 
         if (envIntensity > 0.0)
diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
index 50e781fa7867dc6e9755b04994c72b0135ce522c..6cd24455228f402580f9e9d068400b4d935728c6 100644
--- a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
@@ -23,6 +23,9 @@
  * $/LicenseInfo$
  */
 
+// Lambert Azimuthal Equal-Area projection
+// See: https://aras-p.info/texts/CompactNormalStorage.html
+// Also see: A_bit_more_deferred_-_CryEngine3.ppt
 vec2 encode_normal(vec3 n)
 {
 	float f = sqrt(8 * n.z + 8);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index f665394b46b06c199e34a8793db3657b3367252c..0bb48061e0b391291939ca70eb907a20932ed136 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -31,6 +31,9 @@ out vec4 frag_color;
 
 uniform float minimum_alpha;
 
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO;
+uniform int no_atmo;
+
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
@@ -41,16 +44,19 @@ void default_lighting()
 {
 	vec4 color = diffuseLookup(vary_texcoord0.xy);
 	
-	color *= vertex_color;
-
 	if (color.a < minimum_alpha)
 	{
 		discard;
 	}
+	
+	color *= vertex_color;
 
-	color.rgb = atmosLighting(color.rgb);
-
-	color.rgb = scaleSoftClip(color.rgb);
+	// SL-9632 HUDs are affected by Atmosphere
+	if (no_atmo == 0)
+	{
+		color.rgb = atmosLighting(color.rgb);
+		color.rgb = scaleSoftClip(color.rgb);
+	}
 
 	frag_color = color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
index 46390e4a0e4976446b1a3432a4155acc9d8e0425..1855cfceeb8c4b277e3fe3142d9a98791c4ecb3a 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
@@ -30,7 +30,10 @@ out vec4 frag_color;
 #endif
 
 uniform float minimum_alpha;
-uniform float texture_gamma;
+uniform float texture_gamma; // either 1.0 or 2.2; see: "::TEXTURE_GAMMA"
+
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
@@ -50,9 +53,17 @@ void fullbright_lighting()
 	color.rgb *= vertex_color.rgb;
 
 	color.rgb = pow(color.rgb, vec3(texture_gamma));
-	color.rgb = fullbrightAtmosTransport(color.rgb);
-	
-	color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+	// SL-9632 HUDs are affected by Atmosphere
+	if (no_atmo == 0)
+	{
+		color.rgb = fullbrightAtmosTransport(color.rgb);
+		color.rgb = fullbrightScaleSoftClip(color.rgb);
+	}
+
+	//*TODO: Are we missing an inverse pow() here?
+	// class1\lighting\lightFullbrightF.glsl has:
+    //     color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
 
 	frag_color = color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index b967709c57ce41e65aa0f3473fdded811619adca..5fcdf3107c63954568173fa3f64013e34af75428 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -34,6 +34,9 @@ VARYING vec2 vary_texcoord0;
 
 uniform float texture_gamma;
 
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO;
+uniform int no_atmo;
+
 vec3 fullbrightAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
 
@@ -43,9 +46,12 @@ void fullbright_lighting()
 	
 	color.rgb = pow(color.rgb, vec3(texture_gamma));
 
-	color.rgb = fullbrightAtmosTransport(color.rgb);
-	
-	color.rgb = fullbrightScaleSoftClip(color.rgb);
+	// SL-9632 HUDs are affected by Atmosphere
+	if (no_atmo == 0)
+	{
+		color.rgb = fullbrightAtmosTransport(color.rgb);
+		color.rgb = fullbrightScaleSoftClip(color.rgb);
+	}
 
 	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index 567811cd75afec893025e9a282017bcdbd2aa4ad..6f7e777d23f6e16abc6324afe0cbbc0b1ec35054 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -35,20 +35,37 @@ VARYING vec3 vary_texcoord1;
 
 uniform samplerCube environmentMap;
 
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
+
 vec3 fullbrightShinyAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
 
+// See:
+//   class1\deferred\fullbrightShinyF.glsl
+//   class1\lighting\lightFullbrightShinyF.glsl
 void fullbright_shiny_lighting()
 {
 	vec4 color = diffuseLookup(vary_texcoord0.xy);
 	color.rgb *= vertex_color.rgb;
-	
-	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
 
-	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+	// SL-9632 HUDs are affected by Atmosphere
+	if (no_atmo == 0)
+	{
+		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+		color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
 
-	color.rgb = fullbrightScaleSoftClip(color.rgb);
+		color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+		color.rgb = fullbrightScaleSoftClip(color.rgb);
+	}
+/*
+	// NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
+	else
+	{
+		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+		color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
+	}
+*/
 
 	color.a = 1.0;
 
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index a59bd9c0a684e7e7cd9c757838ac850d37deb975..9ef7704b7038ad6ae074a8d3b5011c3fce7b48b7 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file simpleV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
@@ -28,6 +28,9 @@ uniform mat4 texture_matrix0;
 uniform mat4 modelview_matrix;
 uniform mat4 modelview_projection_matrix;
 
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
+
 ATTRIBUTE vec3 position;
 void passTextureIndex();
 ATTRIBUTE vec2 texcoord0;
@@ -46,19 +49,23 @@ void main()
 {
 	//transform vertex
 	vec4 vert = vec4(position.xyz,1.0);
-	passTextureIndex();
-	vec4 pos = (modelview_matrix * vert);
 	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+
+	passTextureIndex();
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
-	
-	
-	
-	vec3 norm = normalize(normal_matrix * normal);
 
-	calcAtmospherics(pos.xyz);
+	// SL-9632 HUDs are affected by Atmosphere
+	if (no_atmo == 1)
+	{
+		vertex_color = diffuse_color;
+	}
+	else
+	{
+		vec4 pos = (modelview_matrix * vert);
+		vec3 norm = normalize(normal_matrix * normal);
 
-	vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
-	vertex_color = color;
+		calcAtmospherics(pos.xyz);
 
-	
+		vertex_color = calcLighting(pos.xyz, norm, diffuse_color);
+	}
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index dcb02bd1c17c6b5d7951dacd99e84e8058d0eadf..ea2690ba09de3d3a7c3d302dbabd0412f2799a4b 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -1,154 +1,134 @@
-/** 
+/**
  * @file class1\windlight\atmosphericsFuncs.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2019, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec4  lightnorm;
+uniform vec4  sunlight_color;
+uniform vec4  moonlight_color;
+uniform int   sun_up_factor;
+uniform vec4  ambient_color;
+uniform vec4  blue_horizon;
+uniform vec4  blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 uniform float cloud_shadow;
 uniform float density_multiplier;
 uniform float distance_multiplier;
 uniform float max_y;
-uniform vec4 glow;
+uniform vec4  glow;
 uniform float scene_light_strength;
-uniform mat3 ssao_effect_mat;
-uniform int no_atmo;
+uniform mat3  ssao_effect_mat;
+uniform int   no_atmo;
 uniform float sun_moon_glow_factor;
 
-float getAmbientClamp()
+float getAmbientClamp() { return 1.0f; }
+
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+                         out vec3 atten, bool use_ao)
 {
-    return 1.0f;
-}
+    vec3 rel_pos = inPositionEye;
 
+    //(TERRAIN) limit altitude
+    if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
 
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao) {
+    vec3  rel_pos_norm = normalize(rel_pos);
+    float rel_pos_len  = length(rel_pos);
+    vec4  sunlight     = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
 
-    vec3 P = inPositionEye;
-   
-    //(TERRAIN) limit altitude
-    if (P.y > max_y) P *= (max_y / P.y);
-    if (P.y < -max_y) P *= (-max_y / P.y); 
+    // sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+    // I had thought blue_density and haze_density should have equal weighting,
+    // but attenuation due to haze_density tends to seem too strong
 
-    vec3 tmpLightnorm = lightnorm.xyz;
+    vec4 combined_haze = blue_density + vec4(haze_density);
+    vec4 blue_weight   = blue_density / combined_haze;
+    vec4 haze_weight   = vec4(haze_density) / combined_haze;
 
-    vec3 Pn = normalize(P);
-    float Plen = length(P);
+    //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
+    float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
+    sunlight *= exp(-light_atten * above_horizon_factor);  // for sun [horizon..overhead] this maps to an exp curve [0..1]
+
+    // main atmospheric scattering line integral
+    float density_dist = rel_pos_len * density_multiplier;
 
-    vec4 temp1 = vec4(0);
-    vec3 temp2 = vec3(0);
-    vec4 blue_weight;
-    vec4 haze_weight;
-    vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-    vec4 light_atten;
+    // Transparency (-> combined_haze)
+    // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
+    // compiler gets confused.
+    combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
 
-    float dens_mul = density_multiplier;
-    float dist_mul = distance_multiplier;
+    // final atmosphere attenuation factor
+    atten = combined_haze.rgb;
 
-    //sunlight attenuation effect (hue and brightness) due to atmosphere
-    //this is used later for sunlight modulation at various altitudes
-    light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
-        //I had thought blue_density and haze_density should have equal weighting,
-        //but attenuation due to haze_density tends to seem too strong
+    // compute haze glow
+    float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
 
-    temp1 = blue_density + vec4(haze_density);
-    blue_weight = blue_density / temp1;
-    haze_weight = vec4(haze_density) / temp1;
+    // dampen sun additive contrib when not facing it...
+    // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
+    //    if (length(light_dir) > 0.01)
+    haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
 
-    //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
-    temp2.y = max(0.0, tmpLightnorm.y);
-    if (abs(temp2.y) > 0.000001f)
-    {
-        temp2.y = 1. / abs(temp2.y);
-    }
-    temp2.y = max(0.0000001f, temp2.y);
-    sunlight *= exp(-light_atten * temp2.y);
+    haze_glow = 1. - haze_glow;
+    // haze_glow is 0 at the sun and increases away from sun
+    haze_glow = max(haze_glow, .001);  // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    haze_glow *= glow.x;
+    // higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    haze_glow = pow(haze_glow, glow.z);
+    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
 
-    // main atmospheric scattering line integral
-    temp2.z = Plen * dens_mul;
+    // add "minimum anti-solar illumination"
+    haze_glow += .25;
 
-    // Transparency (-> temp1)
-    // ATI Bugfix -- can't store temp1*temp2.z*dist_mul in a variable because the ati
-    // compiler gets confused.
-    temp1 = exp(-temp1 * temp2.z * dist_mul);
+    haze_glow *= sun_moon_glow_factor;
 
-    //final atmosphere attenuation factor
-    atten = temp1.rgb;
-    
-    //compute haze glow
-    //(can use temp2.x as temp because we haven't used it yet)
-    temp2.x = dot(Pn, tmpLightnorm.xyz);
+    vec4 amb_color = ambient_color;
 
-    // dampen sun additive contrib when not facing it...
-    if (length(light_dir) > 0.01)
-    {
-        temp2.x *= max(0.0f, dot(light_dir, Pn));
-    }
-    temp2.x = 1. - temp2.x;
-        //temp2.x is 0 at the sun and increases away from sun
-    temp2.x = max(temp2.x, .001);    //was glow.y
-        //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-    temp2.x *= glow.x;
-        //higher glow.x gives dimmer glow (because next step is 1 / "angle")
-    temp2.x = pow(temp2.x, glow.z);
-        //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-    //add "minimum anti-solar illumination"
-    temp2.x += .25;
-
-    temp2.x *= sun_moon_glow_factor;
- 
-    vec4 amb_color = ambient_color; 
-    
-    //increase ambient when there are more clouds
+    // increase ambient when there are more clouds
     vec4 tmpAmbient = amb_color + (vec4(1.) - amb_color) * cloud_shadow * 0.5;
-    
+
     /*  decrease value and saturation (that in HSV, not HSL) for occluded areas
      * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
      * // The following line of code performs the equivalent of:
      * float ambAlpha = tmpAmbient.a;
      * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
      * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
-     * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+     * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat,
+     * ambAlpha);
      */
     if (use_ao)
     {
         tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
     }
 
-    //haze color
-        additive =
-        vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
-      + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
-          + tmpAmbient));
+    // Similar/Shared Algorithms:
+    //     indra\llinventory\llsettingssky.cpp                                        -- LLSettingsSky::calculateLightSettings()
+    //     indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
+    // haze color
+    vec3 cs = sunlight.rgb * (1. - cloud_shadow);
+    additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
 
-    //brightness of surface both sunlight and ambient
+    // brightness of surface both sunlight and ambient
     sunlit = sunlight.rgb * 0.5;
     amblit = tmpAmbient.rgb * .25;
-    additive *= vec3(1.0 - temp1);
+    additive *= vec3(1.0 - combined_haze);
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
index 24f3992e32fa6fbbdb3c419816f5b134af9598a1..2425a2ad049075f0dd0f294844d0ad732ab29f4c 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -3,7 +3,7 @@
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2005, 2020 Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,28 +36,30 @@ out vec4 frag_color;
 uniform vec4 color;
 uniform vec4 sunlight_color;
 uniform vec4 moonlight_color;
-uniform vec3 lumWeights;
+uniform vec3 moon_dir;
 uniform float moon_brightness;
-uniform float minLuminance;
 uniform sampler2D diffuseMap;
-uniform sampler2D altDiffuseMap;
-uniform float blend_factor; // interp factor between moon A/B
+
 VARYING vec2 vary_texcoord0;
 
+vec3 scaleSoftClip(vec3 light);
+
 void main() 
 {
-    vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
-    vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
-    vec4 c     = mix(moonA, moonB, blend_factor);
+    // Restore Pre-EEP alpha fade moon near horizon
+    float fade = 1.0;
+    if( moon_dir.z > 0 )
+        fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
+
+    vec4 c     = texture2D(diffuseMap, vary_texcoord0.xy);
+//       c.rgb = pow(c.rgb, vec3(0.7f)); // can't use "srgb_to_linear(color.rgb)" as that is a deferred only function
+         c.rgb *= moonlight_color.rgb;
+         c.rgb *= moon_brightness;
 
-    // mix factor which blends when sunlight is brighter
-    // and shows true moon color at night
-    vec3 luma_weights = vec3(0.3, 0.5, 0.3);
-    float mix = 1.0f - dot(normalize(sunlight_color.rgb), luma_weights);
+         c.rgb *= fade;
+         c.a   *= fade;
 
-    vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0 - 1.0;
-    c.rgb = pow(c.rgb, exp);
-    //c.rgb *= moonlight_color.rgb;
+         c.rgb  = scaleSoftClip(c.rgb);
 
     frag_color = vec4(c.rgb, c.a);
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
index 8cd4b2ef4794611625a16d606cc5c27d8b629d4a..2fceb5f743f78d967e922f36965df88160972112 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
@@ -3,7 +3,7 @@
  *
   * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2007, 2020 Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,20 +30,15 @@ uniform mat4 modelview_projection_matrix;
 ATTRIBUTE vec3 position;
 ATTRIBUTE vec2 texcoord0;
 
-void calcAtmospherics(vec3 inPositionEye);
-
 VARYING vec2 vary_texcoord0;
 
 void main()
 {
     //transform vertex
-    vec3 offset = vec3(0, 0, 50);
-    vec4 vert = vec4(position.xyz - offset, 1.0);
+    vec4 vert = vec4(position.xyz, 1.0);
     vec4 pos = (modelview_matrix * vert);
 
     gl_Position = modelview_projection_matrix*vert;
     
     vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-    
-    calcAtmospherics(pos.xyz);
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
index 1dce85a83b0ed14eea22f039ca8dd13d4e6454a6..1485c515a4d27863e5a4f64a26accd235de57933 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -1,24 +1,24 @@
-/** 
+/**
  * @file class2/deferred/skyF.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -32,13 +32,13 @@ uniform mat4 modelview_projection_matrix;
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec4  lightnorm;
+uniform vec4  sunlight_color;
+uniform vec4  moonlight_color;
+uniform int   sun_up_factor;
+uniform vec4  ambient_color;
+uniform vec4  blue_horizon;
+uniform vec4  blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -47,7 +47,7 @@ uniform float density_multiplier;
 uniform float distance_multiplier;
 uniform float max_y;
 
-uniform vec4 glow;
+uniform vec4  glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
@@ -73,16 +73,16 @@ uniform float ice_level;
 
 vec3 rainbow(float d)
 {
-   d = clamp(d, -1.0, 0.0);
-   float rad = (droplet_radius - 5.0f) / 1024.0f;
-   return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
+    d         = clamp(d, -1.0, 0.0);
+    float rad = (droplet_radius - 5.0f) / 1024.0f;
+    return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
 }
 
 vec3 halo22(float d)
 {
-   d = clamp(d, 0.1, 1.0);
-   float v = sqrt(clamp(1 - (d * d), 0, 1));
-   return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
+    d       = clamp(d, 0.1, 1.0);
+    float v = sqrt(clamp(1 - (d * d), 0, 1));
+    return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
 }
 
 /// Soft clips the light with a gamma correction
@@ -90,115 +90,96 @@ vec3 scaleSoftClip(vec3 light);
 
 void main()
 {
-
     // World / view / projection
-    // Get relative position
-    vec3 P = pos.xyz - camPosLocal.xyz + vec3(0,50,0);
+    // Get relative position (offset why?)
+    vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
 
-    // Set altitude
-    if (P.y > 0.)
+    // Adj position vector to clamp altitude
+    if (rel_pos.y > 0.)
     {
-        P *= (max_y / P.y);
+        rel_pos *= (max_y / rel_pos.y);
     }
-    else
+    if (rel_pos.y < 0.)
     {
-        P *= (-32000. / P.y);
+        rel_pos *= (-32000. / rel_pos.y);
     }
 
-    // Can normalize then
-    vec3 Pn = normalize(P);
-    float  Plen = length(P);
+    // Normalized
+    vec3  rel_pos_norm = normalize(rel_pos);
+    float rel_pos_len  = length(rel_pos);
 
     // Initialize temp variables
-    vec4 temp1 = vec4(0.);
-    vec4 temp2 = vec4(0.);
-    vec4 blue_weight;
-    vec4 haze_weight;
     vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-    vec4 light_atten;
-
-    float dens_mul = density_multiplier;
 
     // Sunlight attenuation effect (hue and brightness) due to atmosphere
     // this is used later for sunlight modulation at various altitudes
-    light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
+    vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
 
     // Calculate relative weights
-    temp1 = abs(blue_density) + vec4(abs(haze_density));
-    blue_weight = blue_density / temp1;
-    haze_weight = haze_density / temp1;
+    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+    vec4 blue_weight   = blue_density / combined_haze;
+    vec4 haze_weight   = haze_density / combined_haze;
 
-    // Compute sunlight from P & lightnorm (for long rays like sky)
-    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-    temp2.y = 1. / temp2.y;
-    sunlight *= exp( - light_atten * temp2.y);
+    // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+    float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
+    sunlight *= exp(-light_atten * off_axis);
 
     // Distance
-    temp2.z = Plen * dens_mul;
+    float density_dist = rel_pos_len * density_multiplier;
 
-    // Transparency (-> temp1)
-    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
+    // Transparency (-> combined_haze)
+    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
     // compiler gets confused.
-    temp1 = exp(-temp1 * temp2.z);
+    combined_haze = exp(-combined_haze * density_dist);
 
     // Compute haze glow
-    temp2.x = dot(Pn, lightnorm.xyz);
-    temp2.x = 1. - temp2.x;
-        // temp2.x is 0 at the sun and increases away from sun
-    temp2.x = max(temp2.x, .001);   
-        // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-    temp2.x *= glow.x;
-        // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-    temp2.x = pow(temp2.x, glow.z);
-        // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+    float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
+    haze_glow       = 1. - haze_glow;
+    // haze_glow is 0 at the sun and increases away from sun
+    haze_glow = max(haze_glow, .001);
+    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    haze_glow *= glow.x;
+    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    haze_glow = pow(haze_glow, glow.z);
+    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
 
     // Add "minimum anti-solar illumination"
-    temp2.x += .25;
-
-    temp2.x *= sun_moon_glow_factor;
+    // For sun, add to glow.  For moon, remove glow entirely. SL-13768
+    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
 
     // Haze color above cloud
-    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient_color)
-                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color)
-             ); 
+    vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color) 
+               + haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
 
     // Final atmosphere additive
-    color *= (1. - temp1);
+    color *= (1. - combined_haze);
 
     // Increase ambient when there are more clouds
-    vec4 tmpAmbient = ambient_color;
-    tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; 
+    // TODO 9/20: DJH what does this do?  max(0,(1-ambient)) will change the color
+    vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
 
     // Dim sunlight by cloud shadow percentage
     sunlight *= max(0.0, (1. - cloud_shadow));
 
     // Haze color below cloud
-    vec4 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient)
-                + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-             ); 
+    vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient) 
+                         + haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
 
-    
-    
     // Attenuate cloud color by atmosphere
-    temp1 = sqrt(temp1);    //less atmos opacity (more transparency) below clouds
+    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
 
     // At horizon, blend high altitude sky color towards the darker color below the clouds
-    color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
-    
-    float optic_d = dot(Pn, lightnorm.xyz);
-
-    vec3 halo_22 = halo22(optic_d);
+    color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
 
+    float optic_d = dot(rel_pos_norm, lightnorm.xyz);
+    vec3  halo_22 = halo22(optic_d);
     color.rgb += rainbow(optic_d);
-
     color.rgb += halo_22;
-
     color.rgb *= 2.;
     color.rgb = scaleSoftClip(color.rgb);
 
-    /// Gamma correct for WL (soft clip effect).
+    // Gamma correct for WL (soft clip effect).
     frag_data[0] = vec4(color.rgb, 1.0);
-    frag_data[1] = vec4(0.0,0.0,0.0,0.0);
-    frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog
+    frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
+    frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0);  // 1.0 in norm.w masks off fog
 }
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index b0dff0c62839c89935e2079b6f2118172eb083d2..f4db53e0b7816815fff8323758940e17283a2322 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -1,24 +1,24 @@
-/** 
+/**
  * @file class2/deferred/softenLightF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -39,7 +39,7 @@ uniform sampler2DRect specularRect;
 uniform sampler2DRect normalMap;
 uniform sampler2DRect lightMap;
 uniform sampler2DRect depthMap;
-uniform samplerCube environmentMap;
+uniform samplerCube   environmentMap;
 uniform sampler2D     lightFunc;
 
 uniform float blur_size;
@@ -50,7 +50,7 @@ uniform mat3 env_mat;
 
 uniform vec3 sun_dir;
 uniform vec3 moon_dir;
-uniform int sun_up_factor;
+uniform int  sun_up_factor;
 VARYING vec2 vary_fragcoord;
 
 uniform mat4 inv_proj;
@@ -61,10 +61,10 @@ vec4 getPositionWithDepth(vec2 pos_screen, float depth);
 
 void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
 float getAmbientClamp();
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
+vec3  atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3  scaleSoftClipFrag(vec3 l);
+vec3  fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3  fullbrightScaleSoftClip(vec3 light);
 
 vec3 linear_to_srgb(vec3 c);
 vec3 srgb_to_linear(vec3 c);
@@ -73,128 +73,85 @@ vec3 srgb_to_linear(vec3 c);
 vec4 applyWaterFogView(vec3 pos, vec4 color);
 #endif
 
-void main() 
+void main()
 {
-    vec2 tc = vary_fragcoord.xy;
-    float depth = texture2DRect(depthMap, tc.xy).r;
-    vec4 pos = getPositionWithDepth(tc, depth);
-    vec4 norm = texture2DRect(normalMap, tc);
+    vec2  tc           = vary_fragcoord.xy;
+    float depth        = texture2DRect(depthMap, tc.xy).r;
+    vec4  pos          = getPositionWithDepth(tc, depth);
+    vec4  norm         = texture2DRect(normalMap, tc);
     float envIntensity = norm.z;
-    norm.xyz = getNorm(tc);
-    
-    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
-    float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
-    float light_gamma = 1.0/1.3;
-    da = pow(da, light_gamma);
-    
+    norm.xyz           = getNorm(tc);
+
+    vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir;
+    float da          = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+    float light_gamma = 1.0 / 1.3;
+    da                = pow(da, light_gamma);
+
     vec4 diffuse = texture2DRect(diffuseRect, tc);
-    
-    vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+    vec4 spec    = texture2DRect(specularRect, vary_fragcoord.xy);
 
     vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
-    scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+    scol_ambocc      = pow(scol_ambocc, vec2(light_gamma));
+    float scol       = max(scol_ambocc.r, diffuse.a);
+    float ambocc     = scol_ambocc.g;
 
-    float scol = max(scol_ambocc.r, diffuse.a); 
+    vec3  color = vec3(0);
+    float bloom = 0.0;
 
-    float ambocc = scol_ambocc.g;
+    vec3 sunlit;
+    vec3 amblit;
+    vec3 additive;
+    vec3 atten;
+    calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
 
-    vec3 color = vec3(0);
-    float bloom = 0.0;
+    color.rgb = amblit;
+
+    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+    ambient *= 0.5;
+    ambient *= ambient;
+    ambient = (1.0 - ambient);
+    color.rgb *= ambient;
+
+    vec3 sun_contrib = min(da, scol) * sunlit;
+    color.rgb += sun_contrib;
+    color.rgb *= diffuse.rgb;
+
+    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+    if (spec.a > 0.0)  // specular reflection
     {
-        vec3 sunlit;
-        vec3 amblit;
-        vec3 additive;
-        vec3 atten;
-    
-        calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
-
-        color.rgb = amblit;
-
-        float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
-        ambient *= 0.5;
-        ambient *= ambient;
-        ambient = (1.0 - ambient);
-
-        color.rgb *= ambient;
-
-        vec3 sun_contrib = min(da, scol) * sunlit;
-
-        color.rgb += sun_contrib;
-
-        color.rgb *= diffuse.rgb;
-
-        vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
-        if (spec.a > 0.0) // specular reflection
-        {
-
-#if 1 //EEP
-            vec3 npos = -normalize(pos.xyz);
-
-            //vec3 ref = dot(pos+lv, norm);
-            vec3 h = normalize(light_dir.xyz+npos);
-            float nh = dot(norm.xyz, h);
-            float nv = dot(norm.xyz, npos);
-            float vh = dot(npos, h);
-            float sa = nh;
-            float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
-            float gtdenom = 2 * nh;
-            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-            
-            if (nh > 0.0)
-            {
-                float scontrib = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
-                vec3 sp = sun_contrib*scontrib / 6.0;
-                sp = clamp(sp, vec3(0), vec3(1));
-                bloom += dot(sp, sp) / 4.0;
-                color += sp * spec.rgb;
-            }
-#else //PRODUCTION
-            float sa = dot(refnormpersp, light_dir.xyz);
-            vec3 dumbshiny = sunlit*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-            
-            // add the two types of shiny together
-            vec3 spec_contrib = dumbshiny * spec.rgb;
-            bloom = dot(spec_contrib, spec_contrib) / 6;
-            color.rgb += spec_contrib;
-#endif
+        float sa        = dot(refnormpersp, light_dir.xyz);
+        vec3  dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
+
+        // add the two types of shiny together
+        vec3 spec_contrib = dumbshiny * spec.rgb;
+        bloom             = dot(spec_contrib, spec_contrib) / 6;
+        color.rgb += spec_contrib;
+    }
+
+    color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
 
-        }
-       
-       color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
-
-        if (envIntensity > 0.0)
-        { //add environmentmap
-            vec3 env_vec = env_mat * refnormpersp;
-            vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
-            color = mix(color.rgb, reflected_color, envIntensity);
-        }
-       
-        if (norm.w < 0.5)
-        {
-            color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
-            color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
-        }
-
-        #ifdef WATER_FOG
-            vec4 fogged = applyWaterFogView(pos.xyz,vec4(color, bloom));
-            color = fogged.rgb;
-            bloom = fogged.a;
-        #endif
+    if (envIntensity > 0.0)
+    {  // add environmentmap
+        vec3 env_vec         = env_mat * refnormpersp;
+        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
+        color                = mix(color.rgb, reflected_color, envIntensity);
+    }
 
+    if (norm.w < 0.5)
+    {
+        color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
+        color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
     }
 
-// linear debuggables
-//color.rgb = vec3(final_da);
-//color.rgb = vec3(ambient);
-//color.rgb = vec3(scol);
-//color.rgb = diffuse_srgb.rgb;
+#ifdef WATER_FOG
+    vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
+    color       = fogged.rgb;
+    bloom       = fogged.a;
+#endif
 
     // convert to linear as fullscreen lights need to sum in linear colorspace
     // and will be gamma (re)corrected downstream...
-    
     frag_color.rgb = srgb_to_linear(color.rgb);
-    frag_color.a = bloom;
+    frag_color.a   = bloom;
 }
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index 2c1475d5478872d28080826443919bcfa81c52a2..1f881eb44b5fcb4f94b1e72ddd4136dac7d9bfc1 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -1,24 +1,24 @@
-/** 
+/**
  * @file class2\wl\cloudsV.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -33,25 +33,26 @@ ATTRIBUTE vec2 texcoord0;
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec4  vary_CloudColorSun;
+VARYING vec4  vary_CloudColorAmbient;
 VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
+
+VARYING vec2  vary_texcoord0;
+VARYING vec2  vary_texcoord1;
+VARYING vec2  vary_texcoord2;
+VARYING vec2  vary_texcoord3;
 VARYING float altitude_blend_factor;
 
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec4  lightnorm;
+uniform vec4  sunlight_color;
+uniform vec4  moonlight_color;
+uniform int   sun_up_factor;
+uniform vec4  ambient_color;
+uniform vec4  blue_horizon;
+uniform vec4  blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -59,141 +60,133 @@ uniform float cloud_shadow;
 uniform float density_multiplier;
 uniform float max_y;
 
-uniform vec4 glow;
+uniform vec4  glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
 
 uniform float cloud_scale;
 
+// NOTE: Keep these in sync!
+//       indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
+//       indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+//       indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl
+//       indra\newview\lllegacyatmospherics.cpp
+//       indra\newview\llsettingsvo.cpp
 void main()
 {
+    // World / view / projection
+    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+    // Texture coords
+    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+    vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y);  // See: LLSettingsVOSky::applySpecial
 
-	// World / view / projection
-	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+    vary_texcoord0.xy -= 0.5;
+    vary_texcoord0.xy /= cloud_scale;
+    vary_texcoord0.xy += 0.5;
 
-	vary_texcoord0 = texcoord0;
+    vary_texcoord1 = vary_texcoord0;
+    vary_texcoord1.x += lightnorm.x * 0.0125;
+    vary_texcoord1.y += lightnorm.z * 0.0125;
 
-	// Get relative position
-	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
+    vary_texcoord2 = vary_texcoord0 * 16.;
+    vary_texcoord3 = vary_texcoord1 * 16.;
+
+    // Get relative position
+    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
 
     // fade clouds beyond a certain point so the bottom of the sky dome doesn't look silly at high altitude
-    altitude_blend_factor = clamp((P.y + 512.0) / max_y, 0.0, 1.0);
-
-	// Set altitude
-	if (P.y > 0.)
-	{
-		P *= (max_y / P.y);
-	}
-	else
-	{
-		P *= (-32000. / P.y);
-	}
-
-	// Can normalize then
-	vec3 Pn = normalize(P);
-	float  Plen = length(P);
-
-	// Initialize temp variables
-	vec4 temp1 = vec4(0.);
-	vec4 temp2 = vec4(0.);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	//vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-    float dens_mul = density_multiplier;
-
-	// Sunlight attenuation effect (hue and brightness) due to atmosphere
-	// this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
-
-	// Calculate relative weights
-	temp1 = abs(blue_density) + vec4(abs(haze_density));
-	blue_weight = blue_density / temp1;
-	haze_weight = haze_density / temp1;
-
-	// Compute sunlight from P & lightnorm (for long rays like sky)
-	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Distance
-	temp2.z = Plen * dens_mul;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z);
-
-
-	// Compute haze glow
-	temp2.x = dot(Pn, lightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		// temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .001);	
-		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-    temp2.x *= sun_moon_glow_factor;
-
-	// Add "minimum anti-solar illumination"
-	temp2.x += .25;
-
-	// Increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient_color;
-	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
-
-	// Dim sunlight by cloud shadow percentage
-	sunlight *= (1. - cloud_shadow);
-
-	// Haze color below cloud
-	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-			 );	
-
-	// CLOUDS
-	temp2.y = max(0., lightnorm.y * 2.);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Cloud color out
-	vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
-	vary_CloudColorAmbient = tmpAmbient * cloud_color;
-	
-	// Attenuate cloud color by atmosphere
-	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds
-	vary_CloudColorSun *= temp1;
-	vary_CloudColorAmbient *= temp1;
-	vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
-
-	// Make a nice cloud density based on the cloud_shadow value that was passed in.
-	vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
-
-	// Texture coords
-	vary_texcoord0 = texcoord0;
-	vary_texcoord0.xy -= 0.5;
-	vary_texcoord0.xy /= cloud_scale;
-	vary_texcoord0.xy += 0.5;
-
-	vary_texcoord1 = vary_texcoord0;
-	vary_texcoord1.x += lightnorm.x * 0.0125;
-	vary_texcoord1.y += lightnorm.z * 0.0125;
-
-	vary_texcoord2 = vary_texcoord0 * 16.;
-	vary_texcoord3 = vary_texcoord1 * 16.;
-
-	// Combine these to minimize register use
-	vary_CloudColorAmbient += oHazeColorBelowCloud;
-
-	// needs this to compile on mac
-	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
-
-	// END CLOUDS
+    altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
+
+    // Adj position vector to clamp altitude
+    if (rel_pos.y > 0.)
+    {
+        rel_pos *= (max_y / rel_pos.y);
+    }
+    if (rel_pos.y < 0.)
+    {
+        rel_pos *= (-32000. / rel_pos.y);
+    }
+
+    // Can normalize then
+    vec3  rel_pos_norm = normalize(rel_pos);
+    float rel_pos_len  = length(rel_pos);
+
+    // Initialize temp variables
+    vec4 sunlight = sunlight_color;
+    vec4 light_atten;
+
+    // Sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+
+    // Calculate relative weights
+    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+    vec4 blue_weight   = blue_density / combined_haze;
+    vec4 haze_weight   = haze_density / combined_haze;
+
+    // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
+    sunlight *= exp(-light_atten * off_axis);
+
+    // Distance
+    float density_dist = rel_pos_len * density_multiplier;
+
+    // Transparency (-> combined_haze)
+    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+    // compiler gets confused.
+    combined_haze = exp(-combined_haze * density_dist);
+
+    // Compute haze glow
+    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+    // haze_glow is 0 at the sun and increases away from sun
+    haze_glow = max(haze_glow, .001);
+    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    haze_glow *= glow.x;
+    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    haze_glow = pow(haze_glow, glow.z);
+    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+    haze_glow *= sun_moon_glow_factor;
+
+    // Add "minimum anti-solar illumination"
+    // For sun, add to glow.  For moon, remove glow entirely. SL-13768
+    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
+
+    // Increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient_color;
+    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+
+    // Dim sunlight by cloud shadow percentage
+    sunlight *= (1. - cloud_shadow);
+
+    // Haze color below cloud
+    vec4 additiveColorBelowCloud =
+        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
+
+    // CLOUDS
+    off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
+    sunlight *= exp(-light_atten * off_axis);
+
+    // Cloud color out
+    vary_CloudColorSun     = (sunlight * haze_glow) * cloud_color;
+    vary_CloudColorAmbient = tmpAmbient * cloud_color;
+
+    // Attenuate cloud color by atmosphere
+    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
+    vary_CloudColorSun *= combined_haze;
+    vary_CloudColorAmbient *= combined_haze;
+    vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+
+    // Make a nice cloud density based on the cloud_shadow value that was passed in.
+    vary_CloudDensity = 2. * (cloud_shadow - 0.25);
+
+    // Combine these to minimize register use
+    vary_CloudColorAmbient += oHazeColorBelowCloud;
+
+    // needs this to compile on mac
+    // vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+
+    // END CLOUDS
 }
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index 0d141342ce239d7c095446fbadaf1c41da7caf0b..a0a33b8642e516d020bb0cd569905d4c93e9477b 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -1,28 +1,28 @@
-/** 
+/**
  * @file class2\wl\skyV.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
 uniform mat4 modelview_projection_matrix;
 
 ATTRIBUTE vec3 position;
@@ -37,13 +37,13 @@ VARYING vec4 vary_HazeColor;
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec4  lightnorm;
+uniform vec4  sunlight_color;
+uniform vec4  moonlight_color;
+uniform int   sun_up_factor;
+uniform vec4  ambient_color;
+uniform vec4  blue_horizon;
+uniform vec4  blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -52,110 +52,98 @@ uniform float density_multiplier;
 uniform float distance_multiplier;
 uniform float max_y;
 
-uniform vec4 glow;
+uniform vec4  glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
 
 void main()
 {
-
-	// World / view / projection
+    // World / view / projection
     vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
-	gl_Position = pos;
-	
-	// Get relative position
-	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
-
-	// Set altitude
-	if (P.y > 0.)
-	{
-		P *= (max_y / P.y);
-	}
-	else
-	{
-		P *= (-32000. / P.y);
-	}
-
-	// Can normalize then
-	vec3 Pn = normalize(P);
-
-	float Plen = length(P);
-
-	// Initialize temp variables
-	vec4 temp1 = vec4(0.);
-	vec4 temp2 = vec4(0.);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-	vec4 light_atten;
-
-    float dens_mul = density_multiplier;
-
-	// Sunlight attenuation effect (hue and brightness) due to atmosphere
-	// this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
-
-	// Calculate relative weights
-	temp1 = abs(blue_density) + vec4(abs(haze_density));
-	blue_weight = blue_density / temp1;
-	haze_weight = haze_density / temp1;
-
-	// Compute sunlight from P & lightnorm (for long rays like sky)
-    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-    temp2.y = 1. / temp2.y;
-    sunlight *= exp( - light_atten * temp2.y);
-
-	// Distance
-	temp2.z = Plen * dens_mul;
-
-	// Transparency (-> temp1)
-    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
-    // compiler gets confused.
-    temp1 = exp(-temp1 * temp2.z);
+    gl_Position = pos;
+
+    // Get relative position
+    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+    // Adj position vector to clamp altitude
+    if (rel_pos.y > 0.)
+    {
+        rel_pos *= (max_y / rel_pos.y);
+    }
+    if (rel_pos.y < 0.)
+    {
+        rel_pos *= (-32000. / rel_pos.y);
+    }
 
-	// Compute haze glow
-	temp2.x = dot(Pn, lightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		// temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .001);	
-		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
+    // Can normalize then
+    vec3 rel_pos_norm = normalize(rel_pos);
 
-	// Add "minimum anti-solar illumination"
-	temp2.x += .25;
+    float rel_pos_len = length(rel_pos);
 
-    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient_color)
-                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color)
-             );
+    // Initialize temp variables
+    vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+    vec4 light_atten;
 
+    // Sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+
+    // Calculate relative weights
+    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+    vec4 blue_weight   = blue_density / combined_haze;
+    vec4 haze_weight   = haze_density / combined_haze;
+
+    // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
+    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
+    sunlight *= exp(-light_atten * off_axis);
+
+    // Distance
+    float density_dist = rel_pos_len * density_multiplier;
+
+    // Transparency (-> combined_haze)
+    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+    // compiler gets confused.
+    combined_haze = exp(-combined_haze * density_dist);
+
+    // Compute haze glow
+    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+    // haze_glow is 0 at the sun and increases away from sun
+    haze_glow = max(haze_glow, .001);
+    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    haze_glow *= glow.x;
+    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    haze_glow = pow(haze_glow, glow.z);
+    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+    // Add "minimum anti-solar illumination"
+    // For sun, add to glow.  For moon, remove glow entirely. SL-13768
+    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
+
+    vec4 color =
+        (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
 
     // Final atmosphere additive
-    color *= (1. - temp1);
+    color *= (1. - combined_haze);
 
-	// Increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient_color;
-	tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; 
+    // Increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient_color;
+    tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
 
-	// Dim sunlight by cloud shadow percentage
-	sunlight *= max(0.0, (1. - cloud_shadow));
+    // Dim sunlight by cloud shadow percentage
+    sunlight *= max(0.0, (1. - cloud_shadow));
 
-	// Haze color below cloud
-	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-			 );	
+    // Haze color below cloud
+    vec4 additiveColorBelowCloud =
+        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
 
-	// Attenuate cloud color by atmosphere
-	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds
+    // Attenuate cloud color by atmosphere
+    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
 
-	// At horizon, blend high altitude sky color towards the darker color below the clouds
-	color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
+    // At horizon, blend high altitude sky color towards the darker color below the clouds
+    color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
 
     // Haze color above cloud
-	vary_HazeColor = color;	
+    vary_HazeColor = color;
 }
-
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f3df79fb6bd0bbcd6d5021d456bc8a039d3da61e..166c2d67c88b0fe81343793f31fdb5fa7d659b90 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -867,9 +867,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 	if (mRegionp != regionp)
 	{
 
-		std::string ip = regionp->getHost().getString();
-		LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName()
-				<< " located at " << ip << LL_ENDL;
+		LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() << LL_ENDL;
 		if (mRegionp)
 		{
 			// We've changed regions, we're now going to change our agent coordinate frame.
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 9e65409256890db2d751144f91fe990260a42caa..672104dd7023461f0ee06971d9c22fa1bfb934a2 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -354,6 +354,18 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
 	resetPanDiff();
 	resetOrbitDiff();
 	mHUDTargetZoom = 1.f;
+
+    if (LLSelectMgr::getInstance()->mAllowSelectAvatar)
+    {
+        // resetting camera also resets position overrides in debug mode 'AllowSelectAvatar'
+        LLObjectSelectionHandle selected_handle = LLSelectMgr::getInstance()->getSelection();
+        if (selected_handle->getObjectCount() == 1
+            && selected_handle->getFirstObject() != NULL
+            && selected_handle->getFirstObject()->isAvatar())
+        {
+            LLSelectMgr::getInstance()->resetObjectOverrides(selected_handle);
+        }
+    }
 }
 
 // Allow camera to be moved somewhere other than behind avatar.
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index afa44149684eb718b8d4f055680a563a1e376075..134a34137bd0c89f683bdf2575c24aae3b6dbd0c 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -522,20 +522,20 @@ void LLAppCoreHttp::refreshSettings(bool initial)
 LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url, 
 	const LLCore::HttpHandler::ptr_t &handler, void *appdata)
 {
-	X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
-	LLCore::HttpStatus result;
-	LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
-	LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
-	LLSD validation_params = LLSD::emptyMap();
-	LLURI uri(url);
+    LLCore::HttpStatus result;
+    try
+    {
+        X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
+        LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
+        LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
+        LLSD validation_params = LLSD::emptyMap();
+        LLURI uri(url);
 
-	validation_params[CERT_HOSTNAME] = uri.hostName();
+        validation_params[CERT_HOSTNAME] = uri.hostName();
 
-	// *TODO: In the case of an exception while validating the cert, we need a way
-	// to pass the offending(?) cert back out. *Rider*
+        // *TODO: In the case of an exception while validating the cert, we need a way
+        // to pass the offending(?) cert back out. *Rider*
 
-	try
-	{
 		// don't validate hostname.  Let libcurl do it instead.  That way, it'll handle redirects
 		store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
 	}
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 47fde299c7e3863fe0b0dbde6fbaf2fa918f691a..a2b7362608d38c822cf4d5fd28a31b338e5883a7 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -294,6 +294,7 @@ struct AttachmentInfo
     std::vector<AttachmentInfo> info{
         AttachmentInfo(metadata.logFilePathname,      "text/plain"),
         AttachmentInfo(metadata.userSettingsPathname, "text/xml"),
+        AttachmentInfo(metadata.accountSettingsPathname, "text/xml"),
         AttachmentInfo(metadata.staticDebugPathname,  "text/xml")
     };
 
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 1a330591882d1fc730049e5152831ab1c486d1f3..168b8eb47a53bab0c943c7f86695d9bf6aa44ffd 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3582,6 +3582,10 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
     }
 
     llcoro::suspend();
+    if (LLApp::isQuitting())
+    {
+        return;
+    }
     S32 retryCount(0);
     bool bRetry;
     do
@@ -3645,6 +3649,11 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
 
         LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
 
+        if (LLApp::isQuitting())
+        {
+            return;
+        }
+
         LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
         LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
 
@@ -3680,6 +3689,10 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
                 LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL;
 
                 llcoro::suspendUntilTimeout(timeout); 
+                if (LLApp::isQuitting())
+                {
+                    return;
+                }
                 bRetry = true;
                 continue;
             }
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 75574df00e8637686dbe75cc5015ffb6ce329cb2..70b41a0a5faa2844101984a91d611d9d074f815c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -73,6 +73,7 @@
 #include "llviewermedia.h"
 #include "llviewerparcelaskplay.h"
 #include "llviewerparcelmedia.h"
+#include "llviewershadermgr.h"
 #include "llviewermediafocus.h"
 #include "llviewermessage.h"
 #include "llviewerobjectlist.h"
@@ -688,8 +689,7 @@ LLAppViewer::LLAppViewer()
 	mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
 	mFastTimerLogThread(NULL),
 	mSettingsLocationList(NULL),
-	mIsFirstRun(false),
-	mMinMicroSecPerFrame(0.f)
+	mIsFirstRun(false)
 {
 	if(NULL != sInstance)
 	{
@@ -1258,10 +1258,6 @@ bool LLAppViewer::init()
 
 	joystick = LLViewerJoystick::getInstance();
 	joystick->setNeedsReset(true);
-	/*----------------------------------------------------------------------*/
-
-	gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
-	onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
 
 	return true;
 }
@@ -1481,21 +1477,6 @@ bool LLAppViewer::doFrame()
 
 				display();
 
-				static U64 last_call = 0;
-				if (!gTeleportDisplay || gGLManager.mIsIntel) // SL-10625...throttle early, throttle often with Intel
-				{
-					// Frame/draw throttling
-					U64 elapsed_time = LLTimer::getTotalTime() - last_call;
-					if (elapsed_time < mMinMicroSecPerFrame)
-					{
-						LL_RECORD_BLOCK_TIME(FTM_SLEEP);
-						// llclamp for when time function gets funky
-						U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6);
-						micro_sleep(sleep_time, 0);
-					}
-				}
-				last_call = LLTimer::getTotalTime();
-
 				pingMainloopTimeout("Main:Snapshot");
 				LLFloaterSnapshot::update(); // take snapshots
 					LLFloaterOutfitSnapshot::update();
@@ -3122,8 +3103,9 @@ LLSD LLAppViewer::getViewerInfo() const
 		info["POSITION"] = ll_sd_from_vector3d(pos);
 		info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
 		info["REGION"] = gAgent.getRegion()->getName();
-		info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
-		info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
+
+		boost::regex regex("\\.(secondlife|lindenlab)\\..*");
+		info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getHost().getHostName(), regex, "");
 		info["SERVER_VERSION"] = gLastVersionChannel;
 		LLSLURL slurl;
 		LLAgentUI::buildSLURL(slurl);
@@ -3991,6 +3973,7 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q
 
 void LLAppViewer::userQuit()
 {
+	LL_INFOS() << "User requested quit" << LL_ENDL;
 	if (gDisconnected
 		|| !gViewerWindow
 		|| !gViewerWindow->getProgressView()
@@ -4851,13 +4834,14 @@ void LLAppViewer::idle()
     {
 		return;
     }
+
+    gViewerWindow->updateUI();
+
 	if (gTeleportDisplay)
     {
 		return;
     }
 
-	gViewerWindow->updateUI();
-
 	///////////////////////////////////////
 	// Agent and camera movement
 	//
@@ -5433,19 +5417,6 @@ void LLAppViewer::disconnectViewer()
 	LLUrlEntryParcel::setDisconnected(gDisconnected);
 }
 
-bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
-{
-	if (evt.asInteger() > 0)
-	{
-		mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
-	}
-	else
-	{
-		mMinMicroSecPerFrame = 0;
-	}
-	return false;
-}
-
 void LLAppViewer::forceErrorLLError()
 {
    	LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index e8b3464c6e7815cc1b419a3e6fd64d096e938073..8f0f54de3becf1cbb6ff023652f64e90357dab75 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -255,8 +255,6 @@ class LLAppViewer : public LLApp
     void sendLogoutRequest();
     void disconnectViewer();
 
-	bool onChangeFrameLimit(LLSD const & evt);
-
 	// *FIX: the app viewer class should be some sort of singleton, no?
 	// Perhaps its child class is the singleton and this should be an abstract base.
 	static LLAppViewer* sInstance; 
@@ -313,10 +311,7 @@ class LLAppViewer : public LLApp
 	// llcorehttp library init/shutdown helper
 	LLAppCoreHttp mAppCoreHttp;
 
-        bool mIsFirstRun;
-	U64 mMinMicroSecPerFrame; // frame throttling
-
-
+    bool mIsFirstRun;
 };
 
 // consts from viewer.h
diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp
index 94250f1fc2e81336cbb8c69c88064ff8ec38b64c..2380a8ebf060730b82ff8a0f67a5da289af281f6 100644
--- a/indra/newview/llappviewerlistener.cpp
+++ b/indra/newview/llappviewerlistener.cpp
@@ -52,10 +52,12 @@ LLAppViewerListener::LLAppViewerListener(const LLAppViewerGetter& getter):
 
 void LLAppViewerListener::requestQuit(const LLSD& event)
 {
+    LL_INFOS() << "Listener requested quit" << LL_ENDL;
     mAppViewerGetter()->requestQuit();
 }
 
 void LLAppViewerListener::forceQuit(const LLSD& event)
 {
+    LL_INFOS() << "Listener requested force quit" << LL_ENDL;
     mAppViewerGetter()->forceQuit();
 }
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index 37e8a3917a928f483585f0402ab61dc25e1d4fbf..79c3efff91d5069e1b2c991efa3f473e87ee8894 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -41,6 +41,7 @@ struct CrashMetadata
 {
     std::string logFilePathname;
     std::string userSettingsPathname;
+    std::string accountSettingsPathname;
     std::string staticDebugPathname;
     std::string OSInfo;
     std::string agentFullname;
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 3111540a13192c79a94b87a6f2c1a6fd32d0d109..662164af2dc74a4f9e0e6259a65d226aeacd9e90 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -199,10 +199,11 @@ CrashMetadataSingleton::CrashMetadataSingleton()
     else
     {
         LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
-        logFilePathname      = get_metadata(info, "SLLog");
-        userSettingsPathname = get_metadata(info, "SettingsFilename");
-        OSInfo               = get_metadata(info, "OSInfo");
-        agentFullname        = get_metadata(info, "LoginName");
+        logFilePathname         = get_metadata(info, "SLLog");
+        userSettingsPathname    = get_metadata(info, "SettingsFilename");
+        accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename");
+        OSInfo                  = get_metadata(info, "OSInfo");
+        agentFullname           = get_metadata(info, "LoginName");
         // Translate underscores back to spaces
         LLStringUtil::replaceChar(agentFullname, '_', ' ');
         regionName           = get_metadata(info, "CurrentRegion");
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 156a1c5893295abe7608e1fad7963bfa30698252..9b1c0d1f8b01d7200973daefaae86e76565eee9c 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -139,6 +139,9 @@ namespace
             {
                 // user name, when we have it
                 sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
+
+                sBugSplatSender->sendAdditionalFile(
+                    WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "settings_per_account.xml")));
             }
 
             // LL_ERRS message, when there is one
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index dedb06c9459404a0b73fdfc3684949b86f62ff06..8d89455cd480d2af7f09c71d86e0112ade8f00f0 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1092,6 +1092,10 @@ void LLScriptChiclet::onMenuItemClicked(const LLSD& user_data)
 	{
 		LLScriptFloaterManager::instance().removeNotification(getSessionId());
 	}
+	else if ("close all" == action)
+	{
+		LLIMWellWindow::getInstance()->closeAll();
+	}
 }
 
 void LLScriptChiclet::createPopupMenu()
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 76e16f5a1fffef3ac7445260f02268a28a2773a9..3aaaaf52f566d1fd85390e2e554c814846dfbe75 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -347,6 +347,13 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren
 bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,
     const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
 {
+    if (LLApp::isQuitting())
+    {
+        // Reply from coroutine came on shutdown
+        // We are quiting, don't start any more coroutines!
+        return true;
+    }
+
     LLSD result;
     LLCheckedHandle<LLFloaterCompileQueue> floater(hfloater);
     // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle.
@@ -381,6 +388,8 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
         result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
             LLSDMap("timeout", LLSD::Boolean(true)));
 
+        floater.check();
+
         if (result.has("timeout"))
         {   // A timeout filed in the result will always be true if present.
             LLStringUtil::format_map_t args;
@@ -404,6 +413,12 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
 
     }
 
+    if (!gAssetStorage)
+    {
+        // viewer likely is shutting down
+        return true;
+    }
+
     {
         HandleScriptUserData    userData(pump.getName());
 
@@ -468,6 +483,8 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
 
     result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true)));
 
+    floater.check();
+
     if (result.has("timeout"))
     { // A timeout filed in the result will always be true if present.
         LLStringUtil::format_map_t args;
@@ -797,6 +814,7 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L
                 // but offers no guarantee of doing so.
                 llcoro::suspend();
             }
+            floater.check();
         }
 
         floater->addStringMessage("Done");
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 5539fa75dd4afb23b125514d78b2a310279b1db2..9430bb3ca331dc7ede43576a23275a9a5084a51e 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -482,6 +482,10 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 		conv_it->getSessionID().toString(conversation_id);
 		conv_it->getParticipantID().toString(participant_id);
 
+		bool is_adhoc = (conv_it->getConversationType() == LLIMModel::LLIMSession::ADHOC_SESSION);
+		std::string conv_name = is_adhoc ? conv_it->getConversationName() : LLURI::escape(conv_it->getConversationName());
+		std::string file_name = is_adhoc ? conv_it->getHistoryFileName() : LLURI::escape(conv_it->getHistoryFileName());
+
 		// examples of two file entries
 		// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
 		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
@@ -490,10 +494,10 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 				(S32)conv_it->getConversationType(),
 				(S32)0,
 				(S32)conv_it->hasOfflineMessages(),
-				LLURI::escape(conv_it->getConversationName()).c_str(),
+				conv_name.c_str(),
 				participant_id.c_str(),
 				conversation_id.c_str(),
-				LLURI::escape(conv_it->getHistoryFileName()).c_str());
+				file_name.c_str());
 	}
 	fclose(fp);
 	return true;
@@ -541,14 +545,18 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 				conv_id_buffer,
 				history_file_name);
 
+		bool is_adhoc = ((SessionType)stype == LLIMModel::LLIMSession::ADHOC_SESSION);
+		std::string conv_name = is_adhoc ? conv_name_buffer : LLURI::unescape(conv_name_buffer);
+		std::string file_name = is_adhoc ? history_file_name : LLURI::unescape(history_file_name);
+
 		ConversationParams params;
 		params.time(LLUnits::Seconds::fromValue(time))
 			.conversation_type((SessionType)stype)
 			.has_offline_ims(has_offline_ims)
-			.conversation_name(LLURI::unescape(conv_name_buffer))
+			.conversation_name(conv_name)
 			.participant_id(LLUUID(part_id_buffer))
 			.session_id(LLUUID(conv_id_buffer))
-			.history_filename(LLURI::unescape(history_file_name));
+			.history_filename(file_name);
 
 		LLConversation conversation(params);
 
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 8c6cbc020b7ef7d918540e64bdd13ea4f1cd1e12..2219f202729317542ffb88067528ad23101377aa 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -1178,11 +1178,33 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
 	}
 	else if (isRoot())
 	{
-		if (mSpatialBridge && (mSpatialBridge->asPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) != mVObjp->isHUDAttachment())
+		if (mSpatialBridge)
 		{
-			// remove obsolete bridge
-			mSpatialBridge->markDead();
-			setSpatialBridge(NULL);
+			U32 partition_type = mSpatialBridge->asPartition()->mPartitionType;
+			bool is_hud = mVObjp->isHUDAttachment();
+			bool is_animesh = mVObjp->isAnimatedObject() && mVObjp->getControlAvatar() != NULL;
+			bool is_attachment = mVObjp->isAttachment() && !is_hud && !is_animesh;
+			if ((partition_type == LLViewerRegion::PARTITION_HUD) != is_hud)
+			{
+				// Was/became HUD
+				// remove obsolete bridge
+				mSpatialBridge->markDead();
+				setSpatialBridge(NULL);
+			}
+			else if ((partition_type == LLViewerRegion::PARTITION_CONTROL_AV) != is_animesh)
+			{
+				// Was/became part of animesh
+				// remove obsolete bridge
+				mSpatialBridge->markDead();
+				setSpatialBridge(NULL);
+			}
+			else if ((partition_type == LLViewerRegion::PARTITION_AVATAR) != is_attachment)
+			{
+				// Was/became part of avatar
+				// remove obsolete bridge
+				mSpatialBridge->markDead();
+				setSpatialBridge(NULL);
+			}
 		}
 		//must be an active volume
 		if (!mSpatialBridge)
@@ -1191,6 +1213,15 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
 			{
 				setSpatialBridge(new LLHUDBridge(this, getRegion()));
 			}
+			else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
+			{
+				setSpatialBridge(new LLControlAVBridge(this, getRegion()));
+			}
+			// check HUD first, because HUD is also attachment
+			else if (mVObjp->isAttachment())
+			{
+				setSpatialBridge(new LLAvatarBridge(this, getRegion()));
+			}
 			else
 			{
 				setSpatialBridge(new LLVolumeBridge(this, getRegion()));
@@ -1698,12 +1729,26 @@ void LLDrawable::updateFaceSize(S32 idx)
 LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
 : LLSpatialPartition(0, FALSE, 0, regionp) 
 { 
-	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; 
+	mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; 
 	mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
 	mLODPeriod = 16;
 	mSlopRatio = 0.25f;
 }
 
+LLAvatarPartition::LLAvatarPartition(LLViewerRegion* regionp)
+	: LLBridgePartition(regionp)
+{
+	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
+	mPartitionType = LLViewerRegion::PARTITION_AVATAR;
+}
+
+LLControlAVPartition::LLControlAVPartition(LLViewerRegion* regionp)
+	: LLBridgePartition(regionp)
+{
+	mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV;
+	mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV;
+}
+
 LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
 : LLVolumeBridge(drawablep, regionp)
 {
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 2aee7b450acc116ecc355a6480cff6cedcde43ff..d583a692f9f26d4ca398ae88baeb75f9f9604d83 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -86,7 +86,8 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
 		poolp = new LLDrawPoolAlpha();
 		break;
 	case POOL_AVATAR:
-		poolp = new LLDrawPoolAvatar();
+	case POOL_CONTROL_AV:
+		poolp = new LLDrawPoolAvatar(type);
 		break;
 	case POOL_TREE:
 		poolp = new LLDrawPoolTree(tex0);
@@ -383,16 +384,6 @@ LLRenderPass::~LLRenderPass()
 
 }
 
-LLDrawPool* LLRenderPass::instancePool()
-{
-#if LL_RELEASE_FOR_DOWNLOAD
-	LL_WARNS() << "Attempting to instance a render pass.  Invalid operation." << LL_ENDL;
-#else
-	LL_ERRS() << "Attempting to instance a render pass.  Invalid operation." << LL_ENDL;
-#endif
-	return NULL;
-}
-
 void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
 {					
 	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
@@ -449,7 +440,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
 	if (params.mModelMatrix != gGLLastMatrix)
 	{
 		gGLLastMatrix = params.mModelMatrix;
-        gGL.matrixMode(LLRender::MM_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.loadMatrix(gGLModelView);
 		if (params.mModelMatrix)
 		{
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 4eb9a4151d59daeb6912d10a1005197119774cd3..ecd9bd034ff85b84b0e825b185106b4af10c2651 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -60,6 +60,7 @@ class LLDrawPool
 		POOL_GRASS,
 		POOL_INVISIBLE, // see below *
 		POOL_AVATAR,
+		POOL_CONTROL_AV, // Animesh
 		POOL_VOIDWATER,
 		POOL_WATER,
 		POOL_GLOW,
@@ -110,7 +111,6 @@ class LLDrawPool
 	virtual S32 getShaderLevel() const { return mShaderLevel; }
 	
 	static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
-	virtual LLDrawPool *instancePool() = 0;	// Create an empty new instance of the pool.
 	virtual LLViewerTexture* getTexture() = 0;
 	virtual BOOL isFacePool() { return FALSE; }
 	virtual void resetDrawOrders() = 0;
@@ -138,31 +138,30 @@ class LLRenderPass : public LLDrawPool
 		PASS_POST_BUMP,
 		PASS_MATERIAL,
 		PASS_MATERIAL_ALPHA,
-		PASS_MATERIAL_ALPHA_MASK,
+		PASS_MATERIAL_ALPHA_MASK,              // Diffuse texture used as alpha mask
 		PASS_MATERIAL_ALPHA_EMISSIVE,
 		PASS_SPECMAP,
 		PASS_SPECMAP_BLEND,
-		PASS_SPECMAP_MASK,
+		PASS_SPECMAP_MASK,                     // Diffuse texture used as alpha mask and specular texture(map)
 		PASS_SPECMAP_EMISSIVE,
 		PASS_NORMMAP,
 		PASS_NORMMAP_BLEND,
-		PASS_NORMMAP_MASK,
+		PASS_NORMMAP_MASK,                     // Diffuse texture used as alpha mask and normal map
 		PASS_NORMMAP_EMISSIVE,
 		PASS_NORMSPEC,
 		PASS_NORMSPEC_BLEND,
-		PASS_NORMSPEC_MASK,
+		PASS_NORMSPEC_MASK,                    // Diffuse texture used as alpha mask with normal and specular map
 		PASS_NORMSPEC_EMISSIVE,
 		PASS_GLOW,
 		PASS_ALPHA,
 		PASS_ALPHA_MASK,
-		PASS_FULLBRIGHT_ALPHA_MASK,
+		PASS_FULLBRIGHT_ALPHA_MASK,            // Diffuse texture used as alpha mask and fullbright
 		PASS_ALPHA_INVISIBLE,
 		NUM_RENDER_TYPES,
 	};
 
 	LLRenderPass(const U32 type);
 	virtual ~LLRenderPass();
-	/*virtual*/ LLDrawPool* instancePool();
 	/*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
 	LLViewerTexture* getTexture() { return NULL; }
 	BOOL isDead() { return FALSE; }
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index da0467315f3f5e61308b4e5d1890febf790ec6bd..4ee08e869a087c650b66dff9dd3de387e0eba16a 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -314,11 +314,15 @@ void LLDrawPoolAlpha::render(S32 pass)
 							LLVertexBuffer::MAP_TEXCOORD0);
 
 		pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
-		pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
 		pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
 
+		// Material alpha mask
 		gGL.diffuseColor4f(0, 0, 1, 1);
 		pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+		pushBatches(LLRenderPass::PASS_NORMMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+		pushBatches(LLRenderPass::PASS_SPECMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+		pushBatches(LLRenderPass::PASS_NORMSPEC_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+		pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
 
 		gGL.diffuseColor4f(0, 1, 0, 1);
 		pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 789a254389b8e34ed46ed82b9f293ede3567a848..6fc39f213e1bd6a79d3c9fa76eddfadc352c5249 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -106,8 +106,8 @@ S32 cube_channel = -1;
 
 static LLTrace::BlockTimerStatHandle FTM_SHADOW_AVATAR("Avatar Shadow");
 
-LLDrawPoolAvatar::LLDrawPoolAvatar() : 
-	LLFacePool(POOL_AVATAR)	
+LLDrawPoolAvatar::LLDrawPoolAvatar(U32 type) : 
+	LLFacePool(type)	
 {
 }
 
@@ -136,15 +136,6 @@ BOOL LLDrawPoolAvatar::isDead()
     }
     return TRUE;
 }
- 
-//-----------------------------------------------------------------------------
-// instancePool()
-//-----------------------------------------------------------------------------
-LLDrawPool *LLDrawPoolAvatar::instancePool()
-{
-	return new LLDrawPoolAvatar();
-}
-
 
 S32 LLDrawPoolAvatar::getShaderLevel() const
 {
@@ -1741,11 +1732,16 @@ void LLDrawPoolAvatar::getRiggedGeometry(
     LLVolume* volume,
     const LLVolumeFace& vol_face)
 {
-	face->setGeomIndex(0);
-	face->setIndicesIndex(0);
-		
-	//rigged faces do not batch textures
-	face->setTextureIndex(255);
+    face->setGeomIndex(0);
+    face->setIndicesIndex(0);
+
+    if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES)
+    {
+        face->setDrawInfo(NULL);
+    }
+
+    //rigged faces do not batch textures
+    face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
 
 	if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
 	{
@@ -1810,7 +1806,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(
 	}
 	else
 	{
-		face->setPoolType(LLDrawPool::POOL_AVATAR);
+		face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV
 	}
 
 	//LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL;
@@ -2494,7 +2490,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
 void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
 {
     llassert (facep->isState(LLFace::RIGGED));
-    llassert(getType() == LLDrawPool::POOL_AVATAR);
+    llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
     if (facep->getPool() && facep->getPool() != this)
     {
         LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL;
@@ -2516,7 +2512,7 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
 void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
 {
     llassert (facep->isState(LLFace::RIGGED));
-    llassert(getType() == LLDrawPool::POOL_AVATAR);
+    llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
     if (facep->getPool() != this)
     {
         LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL;
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index cb09eb18e2152bc3ef35b8aee6aa55d1dd21be68..92a85389588cb3a06c02e0bfc6f9ce14d68dba37 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -178,12 +178,10 @@ typedef enum
 
 	virtual S32 getShaderLevel() const;
 
-	LLDrawPoolAvatar();
+	LLDrawPoolAvatar(U32 type);
 
 	static LLMatrix4& getModelView();
 
-	/*virtual*/ LLDrawPool *instancePool();
-
 	/*virtual*/ S32  getNumPasses();
 	/*virtual*/ void beginRenderPass(S32 pass);
 	/*virtual*/ void endRenderPass(S32 pass);
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index 6bd2631d3b2badc315e0a494b3eebe432e20e5ab..5b74264dab4cb2ddca721316f733de27ebe174fb 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -46,11 +46,6 @@ LLDrawPoolGround::LLDrawPoolGround() :
 {
 }
 
-LLDrawPool *LLDrawPoolGround::instancePool()
-{
-	return new LLDrawPoolGround();
-}
-
 void LLDrawPoolGround::prerender()
 {
 	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
diff --git a/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolground.h
index a4f8a3fcf50e343bba2dff7b85a0fc3c806cc243..15b1dc60a29f5f4b751a722264e75d4817f05047 100644
--- a/indra/newview/lldrawpoolground.h
+++ b/indra/newview/lldrawpoolground.h
@@ -43,8 +43,6 @@ class LLDrawPoolGround : public LLFacePool
 
 	LLDrawPoolGround();
 
-	/*virtual*/ LLDrawPool *instancePool();
-
 	/*virtual*/ void prerender();
 	/*virtual*/ void render(S32 pass = 0);
 };
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index dbe8724088716f844bd60a368dba81c721891239..b6f55e800afe8b21b57723351754763028bb2cd4 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -48,11 +48,6 @@ LLDrawPoolSky::LLDrawPoolSky()
 {
 }
 
-LLDrawPool *LLDrawPoolSky::instancePool()
-{
-	return new LLDrawPoolSky();
-}
-
 void LLDrawPoolSky::prerender()
 {
 	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); 
@@ -128,23 +123,12 @@ void LLDrawPoolSky::renderSkyFace(U8 index)
 		return;
 	}
 
-    F32 interp_val = gSky.mVOSkyp ? gSky.mVOSkyp->getInterpVal() : 0.0f;
-
     if (index < 6) // sky tex...interp
     {
         llassert(mSkyTex);
 	    mSkyTex[index].bindTexture(true); // bind the current tex
 
         face->renderIndexed();
-
-        if (interp_val > 0.01f) // iff, we've got enough info to lerp (a to and a from)
-	    {
-		    LLGLEnable blend(GL_BLEND);
-            llassert(mSkyTex);
-	        mSkyTex[index].bindTexture(false); // bind the "other" texture
-		    gGL.diffuseColor4f(1, 1, 1, interp_val); // lighting is disabled
-		    face->renderIndexed();
-	    }
     }
     else // heavenly body faces, no interp...
     {
diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h
index 916d8c1cbe7243892900a4db5dcf6b59cf058537..d1dcd6b22ee5258d67aff3e503d795f34df96f89 100644
--- a/indra/newview/lldrawpoolsky.h
+++ b/indra/newview/lldrawpoolsky.h
@@ -49,8 +49,6 @@ class LLDrawPoolSky : public LLFacePool
 
 	LLDrawPoolSky();
 
-	/*virtual*/ LLDrawPool *instancePool();
-
 	/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); }
 	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); }
 	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); }
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 33a11631fef9662b2487697c977ad8483f870ba0..37dc80e2b7d95e9e05c577eae0e94a78ee5d2b28 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -87,13 +87,6 @@ LLDrawPoolTerrain::~LLDrawPoolTerrain()
 	llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
 }
 
-
-LLDrawPool *LLDrawPoolTerrain::instancePool()
-{
-	return new LLDrawPoolTerrain(mTexturep);
-}
-
-
 U32 LLDrawPoolTerrain::getVertexDataMask() 
 { 
 	if (LLPipeline::sShadowRender)
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 04e27d9370ed4dd05309450a0e8a5eceebb441f0..5b4558020d6b9d63be94b9da99e9a8560dcb7c08 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -49,8 +49,6 @@ class LLDrawPoolTerrain : public LLFacePool
 	LLDrawPoolTerrain(LLViewerTexture *texturep);
 	virtual ~LLDrawPoolTerrain();
 
-	/*virtual*/ LLDrawPool *instancePool();
-
 	/*virtual*/ S32 getNumDeferredPasses() { return 1; }
 	/*virtual*/ void beginDeferredPass(S32 pass);
 	/*virtual*/ void endDeferredPass(S32 pass);
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index b885008caeade02b3eca3ab7f8e664971c8890e3..0d5195bdbfcd67211519270c39e3d029658905ed 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -51,11 +51,6 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
 	mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
 }
 
-LLDrawPool *LLDrawPoolTree::instancePool()
-{
-	return new LLDrawPoolTree(mTexturep);
-}
-
 void LLDrawPoolTree::prerender()
 {
 	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index 9c1e60f5ebb990a8fc8310cf0569e1230c6a997d..13f9ec8dcef699f5a6ee4e8e469fd2e440f4979f 100644
--- a/indra/newview/lldrawpooltree.h
+++ b/indra/newview/lldrawpooltree.h
@@ -45,8 +45,6 @@ class LLDrawPoolTree : public LLFacePool
 
 	LLDrawPoolTree(LLViewerTexture *texturep);
 
-	/*virtual*/ LLDrawPool *instancePool();
-
 	/*virtual*/ void prerender();
 
 	/*virtual*/ S32 getNumDeferredPasses() { return 1; }
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 073adfb627ae16cc3e7d73f60d8f33fce330a29c..7249f22555ee7c69807abc47de4219270663fa37 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -104,13 +104,6 @@ void LLDrawPoolWater::restoreGL()
     }*/
 }
 
-LLDrawPool *LLDrawPoolWater::instancePool()
-{
-	LL_ERRS() << "Should never be calling instancePool on a water pool!" << LL_ENDL;
-	return NULL;
-}
-
-
 void LLDrawPoolWater::prerender()
 {
 	mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index d436557e1cb070f43ceb23598c23b874864a7add..a5d163e0d716d289ffbab6c3d8bd130763559c17 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -61,7 +61,6 @@ class LLDrawPoolWater: public LLFacePool
 	LLDrawPoolWater();
 	/*virtual*/ ~LLDrawPoolWater();
 
-	/*virtual*/ LLDrawPool *instancePool();
 	static void restoreGL();
 	
 	/*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 961d72c62eb7bc18b3680ba43fb4a75b84726654..d4e7f1600e7637b025c41ab05fe94f0ddbfd2934 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -216,10 +216,11 @@ void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightL
 
 	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
 	{
+        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
         LLGLSPipelineDepthTestSkyBox sky(true, false);
         sky_shader->bind();
         sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
-        sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, 1.0f);
+        sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
         renderDome(origin, camHeightLocal, sky_shader);	
 		sky_shader->unbind();
     }
@@ -531,8 +532,6 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
         }
 	}
 
-    blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
-
 	face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
 
 	if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader)
@@ -550,17 +549,17 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
             {
                 // Bind current and next sun textures
                 moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
-                blend_factor = 0;
+                //blend_factor = 0;
             }
             else if (tex_b && !tex_a)
             {
                 moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
-                blend_factor = 0;
+                //blend_factor = 0;
             }
             else if (tex_b != tex_a)
             {
                 moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
-                moon_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+                //moon_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
             }
 
             LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
@@ -570,7 +569,8 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
             moon_shader->uniform1f(LLShaderMgr::MOON_BRIGHTNESS, moon_brightness);
             moon_shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
             moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
-            moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+            //moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+            moon_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, psky->getMoonDirection().mV); // shader: moon_dir
 
             face->renderIndexed();
 
@@ -632,11 +632,6 @@ void LLDrawPoolWLSky::prerender()
 	//LL_INFOS() << "wlsky prerendering pass." << LL_ENDL;
 }
 
-LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool()
-{
-	return new LLDrawPoolWLSky();
-}
-
 LLViewerTexture* LLDrawPoolWLSky::getTexture()
 {
 	return NULL;
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index 3acfda4eee55508f3779a5aa65e96a6300ffd3bf..a4f176d6db7f3247e3bbeef48c355096c5683111 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -62,8 +62,6 @@ class LLDrawPoolWLSky : public LLDrawPool {
 	
 	//static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
 
-	// Create an empty new instance of the pool.
-	/*virtual*/ LLDrawPoolWLSky *instancePool();  ///< covariant override
 	/*virtual*/ LLViewerTexture* getTexture();
 	/*virtual*/ BOOL isFacePool() { return FALSE; }
 	/*virtual*/ void resetDrawOrders();
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 18ea184da6a128617cca14cd851349a6521a8637..4a802ad9aa774462f5faa92d06c1f9dd7cc6567d 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -153,7 +153,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
 	}
 
 	mTEOffset		= -1;
-	mTextureIndex = 255;
+	mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES;
 
 	setDrawable(drawablep);
 	mVObjp = objp;
@@ -184,6 +184,7 @@ void LLFace::destroy()
 		if(mTexture[i].notNull())
 		{
 			mTexture[i]->removeFace(i, this) ;
+			mTexture[i] = NULL;
 		}
 	}
 	
@@ -195,7 +196,7 @@ void LLFace::destroy()
 
 	if (mDrawPoolp)
 	{
-		if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
+		if (this->isState(LLFace::RIGGED) && (mDrawPoolp->getType() == LLDrawPool::POOL_CONTROL_AV || mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR))
 		{
 			((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this);
 		}
@@ -203,7 +204,6 @@ void LLFace::destroy()
 		{
 			mDrawPoolp->removeFace(this);
 		}
-	
 		mDrawPoolp = NULL;
 	}
 
@@ -212,7 +212,7 @@ void LLFace::destroy()
 		delete mTextureMatrix;
 		mTextureMatrix = NULL;
 
-		if (mDrawablep.notNull())
+		if (mDrawablep)
 		{
 			LLSpatialGroup* group = mDrawablep->getSpatialGroup();
 			if (group)
@@ -224,7 +224,7 @@ void LLFace::destroy()
 	}
 	
 	setDrawInfo(NULL);
-		
+
 	mDrawablep = NULL;
 	mVObjp = NULL;
 }
@@ -456,13 +456,13 @@ void LLFace::setTextureIndex(U8 index)
 	{
 		mTextureIndex = index;
 
-		if (mTextureIndex != 255)
+		if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES)
 		{
 			mDrawablep->setState(LLDrawable::REBUILD_POSITION);
 		}
 		else
 		{
-			if (mDrawInfo && mDrawInfo->mTextureList.size() <= 1)
+			if (mDrawInfo && !mDrawInfo->mTextureList.empty())
 			{
 				LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL;
 			}
@@ -535,7 +535,7 @@ void LLFace::updateCenterAgent()
 
 void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 {
-	if (mDrawablep->getSpatialGroup() == NULL)
+	if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL)
 	{
 		return;
 	}
@@ -543,7 +543,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 	mDrawablep->getSpatialGroup()->rebuildGeom();
 	mDrawablep->getSpatialGroup()->rebuildMesh();
 		
-	if(mDrawablep.isNull() || mVertexBuffer.isNull())
+	if(mVertexBuffer.isNull())
 	{
 		return;
 	}
@@ -1539,7 +1539,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
 
-			U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+			U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
 
 			S32 val = 0;
 			U8* vp = (U8*) &val;
@@ -2072,7 +2072,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 			LLVector4a texIdx;
 
-			S32 index = mTextureIndex < 255 ? mTextureIndex : 0;
+			S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
 
 			F32 val = 0.f;
 			S32* vp = (S32*) &val;
@@ -2673,7 +2673,7 @@ S32 LLFace::renderElements(const U16 *index_array) const
 
 S32 LLFace::renderIndexed()
 {
-	if(mDrawablep.isNull() || mDrawPoolp == NULL)
+	if(mDrawablep == NULL || mDrawPoolp == NULL)
 	{
 		return 0;
 	}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index c74d4e3fa843a1f114f5d1df272cad1a1a7b8b46..3611539ff84a548d05e7949345387631a9754bef 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -52,6 +52,7 @@ class LLDrawInfo;
 
 const F32 MIN_ALPHA_SIZE = 1024.f;
 const F32 MIN_TEX_ANIM_SIZE = 512.f;
+const U8 FACE_DO_NOT_BATCH_TEXTURES = 255;
 
 class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16>
 {
@@ -279,8 +280,13 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16>
 	LLXformMatrix* mXform;
 
 	LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
-	
-	LLPointer<LLDrawable> mDrawablep;
+
+	// mDrawablep is not supposed to be null, don't use LLPointer because
+	// mDrawablep owns LLFace and LLPointer is a good way to either cause a
+	// memory leak or a 'delete each other' situation if something deletes
+	// drawable wrongly.
+	LLDrawable* mDrawablep;
+	// LLViewerObject technically owns drawable, but also it should be strictly managed
 	LLPointer<LLViewerObject> mVObjp;
 	S32			mTEOffset;
 
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 44725cab7023cfbe4eb027fb598b70d4b226cc55..dd2baacb7ed287b44fd299089689398d3a7a424b 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -84,10 +84,7 @@ BOOL LLFloaterConversationPreview::postBuild()
 		file = "chat";
 	}
 	mChatHistoryFileName = file;
-	if (mIsGroup)
-	{
-		mChatHistoryFileName += GROUP_CHAT_SUFFIX;
-	}
+
 	LLStringUtil::format_map_t args;
 	args["[NAME]"] = name;
 	std::string title = getString("Title", args);
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 696f748613e7bbdfae6b19de3ed96b96c0652030..028c922a4da8c9ab586666bcf24fa2d14d8bf927 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -35,6 +35,7 @@
 
 #include "llagent.h"
 #include "llbutton.h"
+#include "llcheckboxctrl.h"
 #include "llcombobox.h"
 #include "lldrawable.h"
 #include "lldrawpoolavatar.h"
@@ -115,8 +116,14 @@ BOOL LLFloaterImagePreview::postBuild()
 		mSculptedPreview = new LLImagePreviewSculpted(256, 256);
 		mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f);
 
-		if (mRawImagep->getWidth() * mRawImagep->getHeight () <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
-			getChildView("lossless_check")->setEnabled(TRUE);
+        if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
+        {
+            // We want "lossless_check" to be unchecked when it is disabled, regardless of
+            // LosslessJ2CUpload state, so only assign control when enabling checkbox
+            LLCheckBoxCtrl* check_box = getChild<LLCheckBoxCtrl>("lossless_check");
+            check_box->setEnabled(TRUE);
+            check_box->setControlVariable(gSavedSettings.getControl("LosslessJ2CUpload"));
+        }
 	}
 	else
 	{
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 21420b122b8ead0d1db60d868cef5b0b15d3b6c5..82ce97f311f2c027edfa29c1ae829a1f6b5a8f52 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -57,6 +57,9 @@
 #include "llviewerobjectlist.h"
 #include "boost/foreach.hpp"
 
+
+const S32 EVENTS_PER_IDLE_LOOP = 100;
+
 //
 // LLFloaterIMContainer
 //
@@ -66,7 +69,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
 	mConversationsRoot(NULL),
 	mConversationsEventStream("ConversationsEvents"),
 	mInitialized(false),
-	mIsFirstLaunch(true)
+	mIsFirstLaunch(true),
+	mConversationEventQueue()
 {
     mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
@@ -424,7 +428,9 @@ void LLFloaterIMContainer::idle(void* user_data)
 {
 	LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data);
 
-    if (!self->getVisible() || self->isMinimized())
+	self->idleProcessEvents();
+
+	if (!self->getVisible() || self->isMinimized())
     {
         return;
     }
@@ -455,7 +461,7 @@ void LLFloaterIMContainer::idleUpdate()
             while (current_participant_model != end_participant_model)
             {
                 LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-                participant_model->setModeratorOptionsVisible(is_moderator && participant_model->getUUID() != gAgentID);
+                participant_model->setModeratorOptionsVisible(is_moderator);
                 participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
 
                 current_participant_model++;
@@ -485,13 +491,28 @@ void LLFloaterIMContainer::idleUpdate()
     }
 }
 
+void LLFloaterIMContainer::idleProcessEvents()
+{
+	if (!mConversationEventQueue.empty())
+	{
+		S32 events_to_handle = llmin((S32)mConversationEventQueue.size(), EVENTS_PER_IDLE_LOOP);
+		for (S32 i = 0; i < events_to_handle; i++)
+		{
+			handleConversationModelEvent(mConversationEventQueue.back());
+			mConversationEventQueue.pop_back();
+		}
+	}
+}
+
 bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 {
-	// For debug only
-	//std::ostringstream llsd_value;
-	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
-	//LL_INFOS() << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << LL_ENDL;
-	// end debug
+	mConversationEventQueue.push_front(event);
+	return true;
+}
+
+
+void LLFloaterIMContainer::handleConversationModelEvent(const LLSD& event)
+{
 	
 	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
 	// the model could change substantially and the view could echo only a portion of this model (though currently the 
@@ -508,7 +529,7 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 	if (!session_view)
 	{
 		// We skip events that are not associated with a session
-		return false;
+		return;
 	}
 	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
     LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ?
@@ -535,9 +556,9 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 	{
 		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
 		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+		LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
 		if (!participant_view && session_model && participant_model)
-		{
-			LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
+		{	
 			if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
 			{
 				participant_view = createConversationViewParticipant(participant_model);
@@ -548,7 +569,8 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 		// Add a participant view to the conversation floater 
 		if (conversation_floater && participant_model)
 		{
-			conversation_floater->addConversationViewParticipant(participant_model);
+			bool skip_updating = im_sessionp && im_sessionp->isGroupChat();
+			conversation_floater->addConversationViewParticipant(participant_model, !skip_updating);
 		}
 	}
 	else if (type == "update_participant")
@@ -571,12 +593,6 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 	
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
-	if (conversation_floater)
-	{
-		conversation_floater->refreshConversation();
-	}
-	
-	return false;
 }
 
 void LLFloaterIMContainer::draw()
@@ -1409,12 +1425,21 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
     {
 		return is_single_select;
 	}
-	
-	// Beyond that point, if only the user agent is selected, everything is disabled
-	if (is_single_select && (single_id == gAgentID))
-	{
-		return false;
-	}
+
+    bool is_moderator_option = ("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item);
+
+    // Beyond that point, if only the user agent is selected, everything is disabled
+    if (is_single_select && (single_id == gAgentID))
+    {
+        if (is_moderator_option)
+        {
+            return enableModerateContextMenuItem(item, true);
+        }
+        else
+        {
+            return false;
+        }
+    }
 
 	// If the user agent is selected with others, everything is disabled
 	for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
@@ -1480,11 +1505,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
     {
    		return canBanSelectedMember(single_id);
     }
-	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
-	{
-		// *TODO : get that out of here...
-		return enableModerateContextMenuItem(item);
-	}
+    else if (is_moderator_option)
+    {
+        // *TODO : get that out of here...
+        return enableModerateContextMenuItem(item);
+    }
 
 	// By default, options that not explicitely disabled are enabled
     return true;
@@ -1854,7 +1879,7 @@ LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParti
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
 
-bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata)
+bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata, bool is_self)
 {
 	// only group moderators can perform actions related to this "enable callback"
 	if (!isGroupModerator())
@@ -1874,7 +1899,7 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user
 	{
 		return voice_channel;
 	}
-	else if ("can_mute" == userdata)
+	else if (("can_mute" == userdata) && !is_self)
 	{
 		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
 	}
@@ -1884,7 +1909,7 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user
 	}
 
 	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
-	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
+	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID()) && !is_self;
 }
 
 bool LLFloaterIMContainer::isGroupModerator()
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 78b35721112e751970fc5668c9f9cc0faf0f404c..468b47f1f1b457037b013c1f3a9da46975ff5f8f 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -164,7 +164,7 @@ class LLFloaterIMContainer
     void doToSelectedGroup(const LLSD& userdata);
 
 	static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
-	bool enableModerateContextMenuItem(const std::string& userdata);
+	bool enableModerateContextMenuItem(const std::string& userdata, bool is_self = false);
 	LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
 	LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
 	bool isGroupModerator();
@@ -181,6 +181,7 @@ class LLFloaterIMContainer
 	bool isParticipantListExpanded();
 
 	void idleUpdate(); // for convenience (self) from static idle
+	void idleProcessEvents();
 
 	LLButton* mExpandCollapseBtn;
 	LLButton* mStubCollapseBtn;
@@ -220,6 +221,7 @@ class LLFloaterIMContainer
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
 	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
 	bool onConversationModelEvent(const LLSD& event);
+	void handleConversationModelEvent(const LLSD& event);
 
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
@@ -229,6 +231,8 @@ class LLFloaterIMContainer
 	LLFolderView* mConversationsRoot;
 	LLEventStream mConversationsEventStream; 
 
+	std::deque<LLSD> mConversationEventQueue;
+
 	LLTimer mParticipantRefreshTimer;
 };
 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 3aee08482b95cf82383d2b9e3145cd5fdfa1ec7b..d604d0a789f66804b2cd48fb4c02e711b1efa554 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -465,9 +465,10 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
 	}
 }
 
-
+static LLTrace::BlockTimerStatHandle FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT("Build Conversation View");
 void LLFloaterIMSessionTab::buildConversationViewParticipant()
 {
+	LL_RECORD_BLOCK_TIME(FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT);
 	// Clear the widget list since we are rebuilding afresh from the model
 	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 	while (widget_it != mConversationsWidgets.end())
@@ -496,14 +497,20 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
 	}
 }
 
-void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model)
+void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model, bool update_view)
 {
+	if (!participant_model)
+	{
+		// Nothing to do if the model is inexistent
+		return;
+	}
+
 	// Check if the model already has an associated view
 	LLUUID uuid = participant_model->getUUID();
 	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
 	
 	// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
-	if (widget)
+	if (widget && update_view)
 	{
 		updateConversationViewParticipant(uuid); // overkill?
 	}
@@ -524,8 +531,8 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
 	{
 		mConversationsRoot->extractItem(widget);
 		delete widget;
-		mConversationsWidgets.erase(participant_id);
 	}
+	mConversationsWidgets.erase(participant_id);
 }
 
 void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 1b4922fd73105e715dfcb58d0b8b1665d0fe1929..5357a14ab9aee12b169eb40f26d7c96ce5b43d55 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -84,7 +84,7 @@ class LLFloaterIMSessionTab
 	/*virtual*/ void setFocus(BOOL focus);
 	
 	// Handle the left hand participant list widgets
-	void addConversationViewParticipant(LLConversationItem* item);
+	void addConversationViewParticipant(LLConversationItem* item, bool update_view = true);
 	void removeConversationViewParticipant(const LLUUID& participant_id);
 	void updateConversationViewParticipant(const LLUUID& participant_id);
 	void refreshConversation();
diff --git a/indra/newview/llfloaterloadprefpreset.cpp b/indra/newview/llfloaterloadprefpreset.cpp
index fa17a9d40e3d08e0e37b99b1044deaa6328d295c..f89daf3e04a3113590829e76cb4afb074acc5a40 100644
--- a/indra/newview/llfloaterloadprefpreset.cpp
+++ b/indra/newview/llfloaterloadprefpreset.cpp
@@ -66,6 +66,11 @@ void LLFloaterLoadPrefPreset::onOpen(const LLSD& key)
 
 	EDefaultOptions option = DEFAULT_TOP;
 	LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
+	std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+	if (!preset_graphic_active.empty())
+	{
+		combo->setSimple(preset_graphic_active);
+	}
 }
 
 void LLFloaterLoadPrefPreset::onPresetsListChange()
@@ -74,6 +79,11 @@ void LLFloaterLoadPrefPreset::onPresetsListChange()
 
 	EDefaultOptions option = DEFAULT_TOP;
 	LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
+	std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+	if (!preset_graphic_active.empty())
+	{
+		combo->setSimple(preset_graphic_active);
+	}
 }
 
 void LLFloaterLoadPrefPreset::onBtnCancel()
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 3968f43485437166733b737c00ecbf3e9af7e3a9..649a107d74f8dfbb98828a9f3235f7936da1aae8 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -178,7 +178,6 @@ void LLFloaterPermsDefault::sendInitialPerms()
 	if(!mCapSent)
 	{
 		updateCap();
-		setCapSent(true);
 	}
 }
 
@@ -240,7 +239,7 @@ void LLFloaterPermsDefault::updateCapCoro(std::string url)
         {
             const std::string& reason = status.toString();
             // Do not display the same error more than once in a row
-            if (reason != previousReason)
+            if ((reason != previousReason) && mCapSent)
             {
                 previousReason = reason;
                 LLSD args;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 81f4b2234ca0972cd41e3093fb508a9577dcc26b..96094dcf1464d1c326b01ed98b1910e2e711640d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1094,6 +1094,7 @@ void LLFloaterPreference::onBtnCancel(const LLSD& userdata)
 	if (userdata.asString() == "closeadvanced")
 	{
 		LLFloaterReg::hideInstance("prefs_graphics_advanced");
+		updateMaxComplexity();
 	}
 	else
 	{
@@ -1926,6 +1927,8 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	getChildView("log_path_button")->setEnabled(TRUE);
 	getChildView("chat_font_size")->setEnabled(TRUE);
 	getChildView("conversation_log_combo")->setEnabled(TRUE);
+	getChild<LLUICtrl>("voice_call_friends_only_check")->setEnabled(TRUE);
+	getChild<LLUICtrl>("voice_call_friends_only_check")->setValue(gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"));
 }
 
 
@@ -2034,6 +2037,14 @@ void LLFloaterPreference::updateMaxComplexity()
     LLAvatarComplexityControls::updateMax(
         getChild<LLSliderCtrl>("IndirectMaxComplexity"),
         getChild<LLTextBox>("IndirectMaxComplexityText"));
+
+    LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced");
+    if (floater_graphics_advanced)
+    {
+        LLAvatarComplexityControls::updateMax(
+            floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+            floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText"));
+    }
 }
 
 bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
@@ -2081,6 +2092,14 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
     LLAvatarComplexityControls::updateMax(
         getChild<LLSliderCtrl>("IndirectMaxComplexity"),
         getChild<LLTextBox>("IndirectMaxComplexityText"));
+
+    LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+    if (floater_preferences)
+    {
+        LLAvatarComplexityControls::updateMax(
+            floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+            floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText"));
+    }
 }
 
 void LLFloaterPreference::onChangeMaturity()
@@ -2554,9 +2573,13 @@ void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLS
 
 void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
 {
-	if (checkbox && checkbox->getValue())
+	if (checkbox)
 	{
-		LLNotificationsUtil::add("FriendsAndGroupsOnly");
+		gSavedPerAccountSettings.setBOOL("VoiceCallsFriendsOnly", checkbox->getValue().asBoolean());
+		if (checkbox->getValue())
+		{
+			LLNotificationsUtil::add("FriendsAndGroupsOnly");
+		}
 	}
 }
 
@@ -2659,7 +2682,6 @@ class LLPanelPreferencePrivacy : public LLPanelPreference
 public:
 	LLPanelPreferencePrivacy()
 	{
-		mAccountIndependentSettings.push_back("VoiceCallsFriendsOnly");
 		mAccountIndependentSettings.push_back("AutoDisengageMic");
 	}
 
@@ -2916,6 +2938,7 @@ void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
 	{
 		instance->cancel();
 	}
+	updateMaxComplexity();
 }
 
 LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 702d612343770b77273e019bafd590b14f7ea684..7bfba2a6d7081337ae290d31e5f247fc496bf219 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -930,7 +930,7 @@ void LLFloaterReporter::takeNewSnapshot()
 
 	// Take a screenshot, but don't draw this floater.
 	setVisible(FALSE);
-    if (!gViewerWindow->rawSnapshot(mImageRaw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, gSavedSettings.getBOOL("RenderHUDInSnapshot"), TRUE, FALSE))
+    if (!gViewerWindow->rawSnapshot(mImageRaw,IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE /*UI*/, TRUE, FALSE))
 	{
 		LL_WARNS() << "Unable to take screenshot" << LL_ENDL;
 		setVisible(TRUE);
diff --git a/indra/newview/llfloatersaveprefpreset.cpp b/indra/newview/llfloatersaveprefpreset.cpp
index 5f3cf9d95bc195e53c0a066a59a20e9657a3d281..dd47d02bfa70a9409abe1aabe6475d5cb577d4de 100644
--- a/indra/newview/llfloatersaveprefpreset.cpp
+++ b/indra/newview/llfloatersaveprefpreset.cpp
@@ -86,7 +86,10 @@ void LLFloaterSavePrefPreset::onBtnSave()
 {
 	std::string name = mPresetCombo->getSimple();
 
-	if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (name == PRESETS_DEFAULT))
+	std::string upper_name(name);
+	LLStringUtil::toUpper(upper_name);
+
+	if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (upper_name == PRESETS_DEFAULT_UPPER))
 	{
 		LLNotificationsUtil::add("DefaultPresetNotSaved");
 	}
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index dbf76395391469532f8610fb2a41e7853512da55..32f88b49ac9595d2fbe335b3145f4f6c8cef7eac 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -944,10 +944,14 @@ static void formatDateString(std::string &date_string)
 	}
 }
 
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members");
+
 // static
 void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
 {
-	LL_DEBUGS() << "LLGroupMgr::processGroupMembersReply" << LL_ENDL;
+    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY);
+
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupMembersReply" << LL_ENDL;
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
@@ -1050,10 +1054,14 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
 	LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
 }
 
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties");
+
 //static 
 void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
 {
-	LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;
+    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY);
+
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;
 	if (!msg)
 	{
 		LL_ERRS() << "Can't access the messaging system" << LL_ENDL;
@@ -1119,13 +1127,25 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
 	group_datap->mGroupPropertiesDataComplete = true;
 	group_datap->mChanged = TRUE;
 
+    properties_request_map_t::iterator request = LLGroupMgr::getInstance()->mPropRequests.find(group_id);
+    if (request != LLGroupMgr::getInstance()->mPropRequests.end())
+    {
+        LLGroupMgr::getInstance()->mPropRequests.erase(request);
+    }
+    else
+    {
+        LL_DEBUGS("GrpMgr") << "GroupPropertyResponse received with no pending request. Response was slow." << LL_ENDL;
+    }
 	LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);
 }
 
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data");
 // static
 void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
 {
-	LL_DEBUGS() << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL;
+    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY);
+
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL;
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
@@ -1186,7 +1206,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
 
 
 
-		LL_DEBUGS() << "Adding role data: " << name << " {" << role_id << "}" << LL_ENDL;
+        LL_DEBUGS("GrpMgr") << "Adding role data: " << name << " {" << role_id << "}" << LL_ENDL;
 		LLGroupRoleData* rd = new LLGroupRoleData(role_id,name,title,desc,powers,member_count);
 		group_datap->mRoles[role_id] = rd;
 	}
@@ -1207,10 +1227,13 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
 	LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA);
 }
 
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members");
 // static
 void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
 {
-	LL_DEBUGS() << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL;
+    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY);
+
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL;
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
@@ -1271,7 +1294,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
 
 				if (rd && md)
 				{
-					LL_DEBUGS() << "Adding role-member pair: " << role_id << ", " << member_id << LL_ENDL;
+					LL_DEBUGS("GrpMgr") << "Adding role-member pair: " << role_id << ", " << member_id << LL_ENDL;
 					rd->addMember(member_id);
 					md->addRole(role_id,rd);
 				}
@@ -1323,7 +1346,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
 // static
 void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
 {
-	LL_DEBUGS() << "LLGroupMgr::processGroupTitlesReply" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupTitlesReply" << LL_ENDL;
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
@@ -1356,7 +1379,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
 
 		if (!title.mTitle.empty())
 		{
-			LL_DEBUGS() << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << LL_ENDL;
+			LL_DEBUGS("GrpMgr") << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << LL_ENDL;
 			group_datap->mTitles.push_back(title);
 		}
 	}
@@ -1368,7 +1391,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
 // static
 void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data)
 {
-	LL_DEBUGS() << "processEjectGroupMemberReply" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "processEjectGroupMemberReply" << LL_ENDL;
 	LLUUID group_id;
 	msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
 	BOOL success;
@@ -1384,7 +1407,7 @@ void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data
 // static
 void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
 {
-	LL_DEBUGS() << "processJoinGroupReply" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "processJoinGroupReply" << LL_ENDL;
 	LLUUID group_id;
 	BOOL success;
 	msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
@@ -1404,7 +1427,7 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
 // static
 void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data)
 {
-	LL_DEBUGS() << "processLeaveGroupReply" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "processLeaveGroupReply" << LL_ENDL;
 	LLUUID group_id;
 	BOOL success;
 	msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
@@ -1488,6 +1511,28 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id)
 	return group_datap;
 }
 
+bool LLGroupMgr::hasPendingPropertyRequest(const LLUUID & id)
+{
+    properties_request_map_t::iterator existing_req = LLGroupMgr::getInstance()->mPropRequests.find(id);
+    if (existing_req != LLGroupMgr::getInstance()->mPropRequests.end())
+    {
+        if (gFrameTime - existing_req->second < MIN_GROUP_PROPERTY_REQUEST_FREQ)
+        {
+            return true;
+        }
+        else
+        {
+            LLGroupMgr::getInstance()->mPropRequests.erase(existing_req);
+        }
+    }
+    return false;
+}
+
+void LLGroupMgr::addPendingPropertyRequest(const LLUUID& id)
+{
+    LLGroupMgr::getInstance()->mPropRequests[id] = gFrameTime;
+}
+
 void LLGroupMgr::notifyObservers(LLGroupChange gc)
 {
 	for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi)
@@ -1566,10 +1611,17 @@ void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap)
 
 void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL;
 	// This will happen when we get the reply
 	//LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 	
+    if (LLGroupMgr::getInstance()->hasPendingPropertyRequest(group_id))
+    {
+        LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest suppressed repeat for " << group_id << LL_ENDL;
+        return;
+    }
+    LLGroupMgr::getInstance()->addPendingPropertyRequest(group_id);
+
 	LLMessageSystem* msg = gMessageSystem;
 	msg->newMessage("GroupProfileRequest");
 	msg->nextBlock("AgentData");
@@ -1582,7 +1634,7 @@ void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id)
 
 void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupMembersRequest" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupMembersRequest" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 	if (group_datap->mMemberRequestID.isNull())
 	{
@@ -1604,7 +1656,7 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
 
 void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupRoleDataRequest" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleDataRequest" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 	if (group_datap->mRoleDataRequestID.isNull())
 	{
@@ -1625,7 +1677,7 @@ void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
 
 void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupRoleMembersRequest" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleMembersRequest" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 	
 	if (group_datap->mRoleMembersRequestID.isNull())
@@ -1635,7 +1687,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
 			|| !group_datap->isRoleDataComplete())
 		{
 			// *TODO: KLW FIXME: Should we start a member or role data request?
-			LL_INFOS() << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")
+			LL_INFOS("GrpMgr") << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")
 				<< " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N")
 				<< " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << LL_ENDL;
 			group_datap->mPendingRoleMemberRequest = TRUE;
@@ -1659,7 +1711,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
 
 void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupTitlesRequest" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupTitlesRequest" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 	
 	group_datap->mTitles.clear();
@@ -1678,7 +1730,7 @@ void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id)
 
 void LLGroupMgr::sendGroupTitleUpdate(const LLUUID& group_id, const LLUUID& title_role_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupTitleUpdate" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupTitleUpdate" << LL_ENDL;
 
 	LLMessageSystem* msg = gMessageSystem;
 	msg->newMessage("GroupTitleUpdate");
@@ -1737,7 +1789,7 @@ void LLGroupMgr::sendCreateGroupRequest(const std::string& name,
 
 void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendUpdateGroupInfo" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendUpdateGroupInfo" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 
 	LLMessageSystem* msg = gMessageSystem;
@@ -1766,7 +1818,7 @@ void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id)
 
 void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupRoleMemberChanges" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleMemberChanges" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = createGroupData(group_id);
 
 	if (group_datap->mRoleMemberChanges.empty()) return;
@@ -2313,7 +2365,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 
 void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = getGroupData(group_id);
 
 	if (group_datap && group_datap->pendingRoleChanges())
@@ -2328,7 +2380,7 @@ void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
 
 void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id)
 {
-	LL_DEBUGS() << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL;
+	LL_DEBUGS("GrpMgr") << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL;
 	LLGroupMgrGroupData* group_datap = getGroupData(group_id);
 
 	if (group_datap) group_datap->cancelRoleChanges();
@@ -2362,7 +2414,7 @@ bool LLGroupMgr::parseRoleActions(const std::string& xml_filename)
 		std::string action_set_name;
 		if (action_set->getAttributeString("name", action_set_name))
 		{
-			LL_DEBUGS() << "Loading action set " << action_set_name << LL_ENDL;
+			LL_DEBUGS("GrpMgr") << "Loading action set " << action_set_name << LL_ENDL;
 			role_action_data->mName = action_set_name;
 		}
 		else
@@ -2403,7 +2455,7 @@ bool LLGroupMgr::parseRoleActions(const std::string& xml_filename)
 			std::string action_name;
 			if (action->getAttributeString("name", action_name))
 			{
-				LL_DEBUGS() << "Loading action " << action_name << LL_ENDL;
+				LL_DEBUGS("GrpMgr") << "Loading action " << action_name << LL_ENDL;
 				role_action->mName = action_name;
 			}
 			else
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index cf9735e38a0510ed0cb94ceb156f736501162ffa..0d25e8fb22ac352fae904049d4dab74a7b135a19 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -448,6 +448,8 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 	void notifyObserver(const LLUUID& group_id, LLGroupChange gc);
 	void addGroup(LLGroupMgrGroupData* group_datap);
 	LLGroupMgrGroupData* createGroupData(const LLUUID &id);
+	bool hasPendingPropertyRequest(const LLUUID& id);
+	void addPendingPropertyRequest(const LLUUID& id);
 
 	typedef std::multimap<LLUUID,LLGroupMgrObserver*> observer_multimap_t;
 	observer_multimap_t mObservers;
@@ -455,6 +457,10 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 	typedef std::map<LLUUID, LLGroupMgrGroupData*> group_map_t;
 	group_map_t mGroups;
 
+	const U64MicrosecondsImplicit MIN_GROUP_PROPERTY_REQUEST_FREQ = 100000;//100ms between requests should be enough to avoid spamming.
+	typedef std::map<LLUUID, U64MicrosecondsImplicit> properties_request_map_t;
+	properties_request_map_t mPropRequests;
+
 	typedef std::set<LLParticularGroupObserver*> observer_set_t;
 	typedef std::map<LLUUID,observer_set_t> observer_map_t;
 	observer_map_t mParticularObservers;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 81d862a82765ea3a669db7e739bdcd0872188de5..4ed802138ddf8f649c142546161e88c7dd62e1e8 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -415,7 +415,8 @@ void LLHUDNameTag::clearString()
 void LLHUDNameTag::addLine(const std::string &text_utf8,
 						const LLColor4& color,
 						const LLFontGL::StyleFlags style,
-						const LLFontGL* font)
+						const LLFontGL* font,
+						const bool use_ellipses)
 {
 	LLWString wline = utf8str_to_wstring(text_utf8);
 	if (!wline.empty())
@@ -432,18 +433,52 @@ void LLHUDNameTag::addLine(const std::string &text_utf8,
 		tokenizer tokens(wline, sep);
 		tokenizer::iterator iter = tokens.begin();
 
-		while (iter != tokens.end())
-		{
-			U32 line_length = 0;
-			do	
-			{
-				F32 max_pixels = HUD_TEXT_MAX_WIDTH;
-				S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
-				LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font);
-				mTextSegments.push_back(segment);
-				line_length += segment_length;
-			}
-			while (line_length != iter->size());
+        const F32 max_pixels = HUD_TEXT_MAX_WIDTH;
+        while (iter != tokens.end())
+        {
+            U32 line_length = 0;
+            if (use_ellipses)
+            {
+                // "QualityAssuranceAssuresQuality1" will end up like "QualityAssuranceAssuresQual..."
+                // "QualityAssuranceAssuresQuality QualityAssuranceAssuresQuality" will end up like "QualityAssuranceAssuresQual..."
+                // "QualityAssurance AssuresQuality1" will end up as "QualityAssurance AssuresQua..." because we are enforcing single line
+                do
+                {
+                    S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::ANYWHERE);
+                    if (segment_length + line_length < wline.length()) // since we only draw one string, line_length should be 0
+                    {
+                        // token does does not fit into signle line, need to draw "...".
+                        // Use four dots for ellipsis width to generate padding
+                        const LLWString dots_pad(utf8str_to_wstring(std::string("....")));
+                        S32 elipses_width = font->getWidthF32(dots_pad.c_str());
+                        // truncated string length
+                        segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels - elipses_width, wline.length(), LLFontGL::ANYWHERE);
+                        const LLWString dots(utf8str_to_wstring(std::string("...")));
+                        LLHUDTextSegment segment(iter->substr(line_length, segment_length) + dots, style, color, font);
+                        mTextSegments.push_back(segment);
+                        break; // consider it to be complete
+                    }
+                    else
+                    {
+                        // token fits fully into string
+                        LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font);
+                        mTextSegments.push_back(segment);
+                        line_length += segment_length;
+                    }
+                } while (line_length != iter->size());
+            }
+            else
+            {
+                // "QualityAssuranceAssuresQuality 1" will be split into two lines "QualityAssuranceAssuresQualit" and "y 1"
+                // "QualityAssurance AssuresQuality 1" will be split into two lines "QualityAssurance" and "AssuresQuality"
+                do
+                {
+                    S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
+                    LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font);
+                    mTextSegments.push_back(segment);
+                    line_length += segment_length;
+                } while (line_length != iter->size());
+            }
 			++iter;
 		}
 	}
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 38a4f184153c09eae0264e2a64aa098c00a77c2a..20272a823295cb249081af5b895307bab836d7a4 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -92,7 +92,7 @@ class LLHUDNameTag : public LLHUDObject
 	void clearString();
 
 	// Add text a line at a time, allowing custom formatting
-	void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL);
+	void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL, const bool use_ellipses = false);
 
 	// For bubble chat, set the part above the chat text
 	void setLabel(const std::string& label_utf8);
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index e1b58dde51dce55484413a689a3291e626ffd03b..1e43e4ea3a9abaa6452dd015c1968e19b3836da3 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -450,7 +450,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
         || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id));
     BOOL is_owned_by_me = FALSE;
     BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
-    BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
+    BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly");
     BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
         LLMuteList::getInstance()->isLinden(name);
 
@@ -1164,7 +1164,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
             {
                 return;
             }
-            else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
+            else if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
             {
                 return;
             }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d5142a4496a9b2bc3e9a6c2894d80a6ba3a73f7d..d17bb982e1d0b23512c7fcb08673030b4b7cc9cd 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -515,6 +515,7 @@ LLIMModel::LLIMModel()
 {
 	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
 	addNewMsgCallback(boost::bind(&on_new_message, _1));
+	LLCallDialogManager::instance();
 }
 
 LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
@@ -2683,7 +2684,7 @@ void LLIMMgr::addMessage(
 	}
 	bool skip_message = false;
 	bool from_linden = LLMuteList::getInstance()->isLinden(from);
-	if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
+    if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
 	{
 		// Evaluate if we need to skip this message when that setting is true (default is false)
 		skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);	// Skip non friends...
@@ -2742,7 +2743,7 @@ void LLIMMgr::addMessage(
 			}
 
 			//Play sound for new conversations
-			if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
+			if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
 			{
 				make_ui_sound("UISndNewIncomingIMSession");
 			}
@@ -3072,7 +3073,7 @@ void LLIMMgr::inviteToSession(
 	if (voice_invite)
 	{
 		bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
-		bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
+        bool isRejectNonFriendCall = (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
 		if	(isRejectGroupCall || isRejectNonFriendCall || gAgent.isDoNotDisturb())
 		{
 			if (gAgent.isDoNotDisturb() && !isRejectGroupCall && !isRejectNonFriendCall)
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 2e0037aa570306388a6b3e5306bef808a395a4a7..72631174e73929442739973d29d41aaafd9424e2 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -194,10 +194,15 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 	// when applying a filter, matching folders get their contents downloaded first
 	// but make sure we are not interfering with pre-download
 	if (isNotDefault()
-		&& !gInventory.isCategoryComplete(folder_id)
 		&& LLStartUp::getStartupState() > STATE_WEARABLES_WAIT)
-	{
-		LLInventoryModelBackgroundFetch::instance().start(folder_id);
+    {
+        LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id);
+        if (!cat || (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN))
+        {
+            // At the moment background fetch only cares about VERSION_UNKNOWN,
+            // so do not check isCategoryComplete that compares descendant count
+            LLInventoryModelBackgroundFetch::instance().start(folder_id);
+        }
 	}
 
 	// Marketplace folder filtering
@@ -289,21 +294,34 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent
 	// Pass if this item's type is of the correct filter type
 	if (filterTypes & FILTERTYPE_OBJECT)
 	{
-
-		// If it has no type, pass it, unless it's a link.
-		if (object_type == LLInventoryType::IT_NONE)
-		{
-			if (object && object->getIsLinkType())
-			{
-				return FALSE;
-			}
-		}
-		else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
-		{
-			return FALSE;
-		}
+        switch (object_type)
+        {
+        case LLInventoryType::IT_NONE:
+            // If it has no type, pass it, unless it's a link.
+            if (object && object->getIsLinkType())
+            {
+                return FALSE;
+            }
+            break;
+        case LLInventoryType::IT_UNKNOWN:
+            {
+                // Unknows are only shown when we show every type. 
+                // Unknows are 255 and won't fit in 64 bits.
+                if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL)
+                {
+                    return FALSE;
+                }
+                break;
+            }
+        default:
+            if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
+            {
+                return FALSE;
+            }
+            break;
+        }
 	}
-	
+
 	if(filterTypes & FILTERTYPE_WORN)
 	{
 		if (!get_is_item_worn(object_id))
@@ -428,18 +446,32 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) cons
 	// Pass if this item's type is of the correct filter type
 	if (filterTypes & FILTERTYPE_OBJECT)
 	{
-		// If it has no type, pass it, unless it's a link.
-		if (object_type == LLInventoryType::IT_NONE)
-		{
-			if (item && item->getIsLinkType())
-			{
-				return false;
-			}
-		}
-		else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
-		{
-			return false;
-		}
+        switch (object_type)
+        {
+        case LLInventoryType::IT_NONE:
+            // If it has no type, pass it, unless it's a link.
+            if (item && item->getIsLinkType())
+            {
+                return FALSE;
+            }
+            break;
+        case LLInventoryType::IT_UNKNOWN:
+            {
+                // Unknows are only shown when we show every type. 
+                // Unknows are 255 and won't fit in 64 bits.
+                if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL)
+                {
+                    return FALSE;
+                }
+                break;
+            }
+        default:
+            if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
+            {
+                return FALSE;
+            }
+            break;
+        }
 	}
 
 	////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 8e814916ad5be83c307205ef9d434a78ac0b3048..c65998cf907394254fdc2f3517588977590aa3e6 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1851,41 +1851,7 @@ void LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder()
 
 /************************************************************************/
 /* Asset Pre-Filtered Inventory Panel related class                     */
-/* Exchanges filter's flexibility for speed of generation and           */
-/* improved performance                                                 */
 /************************************************************************/
-class LLAssetFilteredInventoryPanel : public LLInventoryPanel
-{
-public:
-    struct Params
-        : public LLInitParam::Block<Params, LLInventoryPanel::Params>
-    {
-        Mandatory<std::string>	filter_asset_type;
-
-        Params() : filter_asset_type("filter_asset_type") {}
-    };
-
-    void initFromParams(const Params& p);
-protected:
-    LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {}
-    friend class LLUICtrlFactory;
-public:
-    ~LLAssetFilteredInventoryPanel() {}
-
-    /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-                                       EDragAndDropType cargo_type,
-                                       void* cargo_data,
-                                       EAcceptance* accept,
-                                       std::string& tooltip_msg) override;
-
-protected:
-    /*virtual*/ LLFolderViewItem*	buildNewViews(const LLUUID& id) override;
-    /*virtual*/ void				itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
-
-private:
-    LLAssetType::EType mAssetType;
-};
-
 
 void LLAssetFilteredInventoryPanel::initFromParams(const Params& p)
 {
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 32d122cab8aee392cf9ee71481d7645deff66e15..7cb52dc1f30a5aa7c44c9def1c9e8dad810631fe 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -339,6 +339,44 @@ class LLInventoryPanel : public LLPanel
 	bool				mViewsInitialized; // Views have been generated
 };
 
+/************************************************************************/
+/* Asset Pre-Filtered Inventory Panel related class                     */
+/* Exchanges filter's flexibility for speed of generation and           */
+/* improved performance                                                 */
+/************************************************************************/
+
+class LLAssetFilteredInventoryPanel : public LLInventoryPanel
+{
+public:
+    struct Params
+        : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+    {
+        Mandatory<std::string>	filter_asset_type;
+
+        Params() : filter_asset_type("filter_asset_type") {}
+    };
+
+    void initFromParams(const Params& p);
+protected:
+    LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {}
+    friend class LLUICtrlFactory;
+public:
+    ~LLAssetFilteredInventoryPanel() {}
+
+    /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+        EDragAndDropType cargo_type,
+        void* cargo_data,
+        EAcceptance* accept,
+        std::string& tooltip_msg) override;
+
+protected:
+    /*virtual*/ LLFolderViewItem*	buildNewViews(const LLUUID& id) override;
+    /*virtual*/ void				itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
+
+private:
+    LLAssetType::EType mAssetType;
+};
+
 
 class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
 {
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index c58540914e1a4aad0f32a302cec8acc50c92b2b4..1fc70cd6d6438888396b837192ee2ffc961d9e16 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -39,6 +39,11 @@
 // Globals
 LLLandmarkList gLandmarkList;
 
+// number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size,
+// which is 4096, to not overfill the pool if user has more than 4K of landmarks,
+// and low number helps with not flooding server with requests
+const S32 MAX_SIMULTANEOUS_REQUESTS = 512;
+
 
 ////////////////////////////////////////////////////////////////////////////
 // LLLandmarkList
@@ -69,6 +74,11 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
 		{
 			return NULL;
 		}
+	    if ( mWaitList.find(asset_uuid) != mWaitList.end() )
+		{
+            // Landmark is sheduled for download, but not requested yet
+			return NULL;
+		}
 		
 		landmark_requested_list_t::iterator iter = mRequestedList.find(asset_uuid);
 		if (iter != mRequestedList.end())
@@ -86,6 +96,13 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
 			mLoadedCallbackMap.insert(vt);
 		}
 
+        if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
+        {
+            // Postpone download till queu is emptier
+            mWaitList.insert(asset_uuid);
+            return NULL;
+        }
+
 		gAssetStorage->getAssetData(asset_uuid,
 									LLAssetType::AT_LANDMARK,
 									LLLandmarkList::processGetAssetReply,
@@ -155,8 +172,22 @@ void LLLandmarkList::processGetAssetReply(
 		}
 
 		gLandmarkList.mBadList.insert(uuid);
+        gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
+        // todo: this should clean mLoadedCallbackMap!
 	}
 
+    if (!gLandmarkList.mWaitList.empty())
+    {
+        // start new download from wait list
+        landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
+        LLUUID asset_uuid = *iter;
+        gLandmarkList.mWaitList.erase(iter);
+        gAssetStorage->getAssetData(asset_uuid,
+            LLAssetType::AT_LANDMARK,
+            LLLandmarkList::processGetAssetReply,
+            NULL);
+        gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+    }
 }
 
 BOOL LLLandmarkList::isAssetInLoadedCallbackMap(const LLUUID& asset_uuid)
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index 3356f866ce453aa83c8ebaef1e783e84fd7a8d0a..2e7bd2561013d67165f4a783c5322bd09a81db61 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -70,9 +70,10 @@ class LLLandmarkList
 	typedef std::map<LLUUID, LLLandmark*> landmark_list_t;
 	landmark_list_t mList;
 
-	typedef std::set<LLUUID> landmark_bad_list_t;
-	landmark_bad_list_t mBadList;
-	
+	typedef std::set<LLUUID> landmark_uuid_list_t;
+	landmark_uuid_list_t mBadList;
+	landmark_uuid_list_t mWaitList;
+
 	typedef std::map<LLUUID,F32> landmark_requested_list_t;
 	landmark_requested_list_t mRequestedList;
 	
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 0c64531783b6cfa32c73626fd068dc313bfb4373..354f5a453bb3d336ffdb1ba7fcd2dae99ecf0790 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -761,8 +761,8 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group)
 	{
 		std::string file_name;
 		gCacheName->getGroupName(avatar_id, file_name);
-		file_name = makeLogFileName(file_name);
-		return isTranscriptFileFound(makeLogFileName(file_name));
+		file_name = makeLogFileName(file_name + GROUP_CHAT_SUFFIX);
+		return isTranscriptFileFound(file_name);
 	}
 	return false;
 }
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index f158aae3d2a5fe1922cee511ac39c2712e67b59c..c3e39429a200d2b918b801bdff115358916a5fac 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -447,6 +447,7 @@ BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
 	}
 
 	mMouseCur = mMouseDown;
+	mAgentSelfAtAxis = gAgent.getAtAxis(); // no point checking if avatar was selected, just save the value
 
 	// Route future Mouse messages here preemptively.  (Release on mouse up.)
 	setMouseCapture( TRUE );
@@ -610,6 +611,26 @@ void LLManipRotate::drag( S32 x, S32 y )
 			else
 			{
 				object->setRotation(new_rot, damped);
+                LLVOAvatar* avatar = object->asAvatar();
+                if (avatar && avatar->isSelf()
+                    && LLSelectMgr::getInstance()->mAllowSelectAvatar
+                    && !object->getParent())
+                {
+                    // Normal avatars use object's orienttion, but self uses
+                    // separate LLCoordFrame
+                    // See LVOAvatar::updateOrientation()
+                    if (gAgentCamera.getFocusOnAvatar())
+                    {
+                        //Don't rotate camera with avatar
+                        gAgentCamera.setFocusOnAvatar(false, false, false);
+                    }
+
+                    LLVector3 at_axis = mAgentSelfAtAxis;
+                    at_axis *= mRotation;
+                    at_axis.mV[VZ] = 0.f;
+                    at_axis.normalize();
+                    gAgent.resetAxes(at_axis);
+                }
 				rebuild(object);
 			}
 
@@ -717,7 +738,7 @@ void LLManipRotate::drag( S32 x, S32 y )
 		LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
 		if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
 			((root_object == NULL) || !root_object->isPermanentEnforced()) &&
-			!cur->isAvatar())
+			(!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar))
 		{
 			selectNode->mLastRotation = cur->getRotation();
 			selectNode->mLastPositionLocal = cur->getPosition();
diff --git a/indra/newview/llmaniprotate.h b/indra/newview/llmaniprotate.h
index e8f1c24c584bbcac14622c20936d8966a9117b32..dc36ef796add1a959d66eec191b3602802750552 100644
--- a/indra/newview/llmaniprotate.h
+++ b/indra/newview/llmaniprotate.h
@@ -95,6 +95,7 @@ class LLManipRotate : public LLManip
 	
 	LLVector3			mMouseDown;
 	LLVector3			mMouseCur;
+	LLVector3			mAgentSelfAtAxis; // Own agent uses separate rotation method
 	F32					mRadiusMeters;
 	
 	LLVector3			mCenterToCam;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index c5ced425f65ac026021a2e97f682c2f5b8942c46..b63dabe93c2803e3eb1d604ab48a443348d77c44 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1553,7 +1553,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 
 				if (!zero)
 				{ //attempt to parse
-					if (physicsShapeReceived(mesh_id, buffer, size))
+					if (physicsShapeReceived(mesh_id, buffer, size) == MESH_OK)
 					{
 						delete[] buffer;
 						return true;
@@ -1647,7 +1647,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c
 			LLMeshRepository::sCacheBytesRead += bytes;	
 			++LLMeshRepository::sCacheReads;
 			file.read(buffer, bytes);
-			if (headerReceived(mesh_params, buffer, bytes))
+			if (headerReceived(mesh_params, buffer, bytes) == MESH_OK)
 			{
 				// Found mesh in VFS cache
 				return true;
@@ -1794,7 +1794,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
 	return retval;
 }
 
-bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
+EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
 {
 	const LLUUID mesh_id = mesh_params.getSculptID();
 	LLSD header;
@@ -1802,30 +1802,39 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
 	U32 header_size = 0;
 	if (data_size > 0)
 	{
-		std::string res_str((char*) data, data_size);
+        std::istringstream stream;
+        try
+        {
+            std::string res_str((char*)data, data_size);
 
-		std::string deprecated_header("<? LLSD/Binary ?>");
+            std::string deprecated_header("<? LLSD/Binary ?>");
 
-		if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
-		{
-			res_str = res_str.substr(deprecated_header.size()+1, data_size);
-			header_size = deprecated_header.size()+1;
-		}
-		data_size = res_str.size();
+            if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
+            {
+                res_str = res_str.substr(deprecated_header.size() + 1, data_size);
+                header_size = deprecated_header.size() + 1;
+            }
+            data_size = res_str.size();
 
-		std::istringstream stream(res_str);
+            stream.str(res_str);
+        }
+        catch (std::bad_alloc&)
+        {
+            // out of memory, we won't be able to process this mesh
+            return MESH_OUT_OF_MEMORY;
+        }
 
 		if (!LLSDSerialize::fromBinary(header, stream, data_size))
 		{
 			LL_WARNS(LOG_MESH) << "Mesh header parse error.  Not a valid mesh asset!  ID:  " << mesh_id
 							   << LL_ENDL;
-			return false;
+			return MESH_PARSE_FAILURE;
 		}
 
 		if (!header.isMap())
 		{
 			LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;
-			return false;
+			return MESH_INVALID;
 		}
 
 		if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)
@@ -1871,7 +1880,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
 		}
 	}
 
-	return true;
+	return MESH_OK;
 }
 
 EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
@@ -1916,18 +1925,25 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
 
 	if (data_size > 0)
 	{
-		std::string res_str((char*) data, data_size);
-
-		std::istringstream stream(res_str);
+        try
+        {
+            std::string res_str((char*)data, data_size);
+            std::istringstream stream(res_str);
 
-		U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
-		if (uzip_result != LLUZipHelper::ZR_OK)
-		{
-			LL_WARNS(LOG_MESH) << "Mesh skin info parse error.  Not a valid mesh asset!  ID:  " << mesh_id
-							   << " uzip result" << uzip_result
-							   << LL_ENDL;
-			return false;
-		}
+            U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
+            if (uzip_result != LLUZipHelper::ZR_OK)
+            {
+                LL_WARNS(LOG_MESH) << "Mesh skin info parse error.  Not a valid mesh asset!  ID:  " << mesh_id
+                    << " uzip result" << uzip_result
+                    << LL_ENDL;
+                return false;
+            }
+        }
+        catch (std::bad_alloc&)
+        {
+            LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL;
+            return false;
+        }
 	}
 	
 	{
@@ -1949,19 +1965,26 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
 	LLSD decomp;
 
 	if (data_size > 0)
-	{ 
-		std::string res_str((char*) data, data_size);
-
-		std::istringstream stream(res_str);
+    {
+        try
+        {
+            std::string res_str((char*)data, data_size);
+            std::istringstream stream(res_str);
 
-		U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
-		if (uzip_result != LLUZipHelper::ZR_OK)
-		{
-			LL_WARNS(LOG_MESH) << "Mesh decomposition parse error.  Not a valid mesh asset!  ID:  " << mesh_id
-							   << " uzip result: " << uzip_result
-							   << LL_ENDL;
-			return false;
-		}
+            U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
+            if (uzip_result != LLUZipHelper::ZR_OK)
+            {
+                LL_WARNS(LOG_MESH) << "Mesh decomposition parse error.  Not a valid mesh asset!  ID:  " << mesh_id
+                    << " uzip result: " << uzip_result
+                    << LL_ENDL;
+                return false;
+            }
+        }
+        catch (std::bad_alloc&)
+        {
+            LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL;
+            return false;
+        }
 	}
 	
 	{
@@ -1976,7 +1999,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
 	return true;
 }
 
-bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
+EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
 {
 	LLSD physics_shape;
 
@@ -1993,8 +2016,19 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32
 		volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
 		volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
 		LLPointer<LLVolume> volume = new LLVolume(volume_params,0);
-		std::string mesh_string((char*) data, data_size);
-		std::istringstream stream(mesh_string);
+
+        std::istringstream stream;
+        try
+        {
+            std::string mesh_string((char*)data, data_size);
+            stream.str(mesh_string);
+        }
+        catch (std::bad_alloc&)
+        {
+            // out of memory, we won't be able to process this mesh
+            delete d;
+            return MESH_OUT_OF_MEMORY;
+        }
 
 		if (volume->unpackVolumeFaces(stream, data_size))
 		{
@@ -2033,7 +2067,7 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32
 		LLMutexLock lock(mMutex);
 		mDecompositionQ.push_back(d);
 	}
-	return true;
+	return MESH_OK;
 }
 
 LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures,
@@ -3142,15 +3176,21 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 									  U8 * data, S32 data_size)
 {
 	LLUUID mesh_id = mMeshParams.getSculptID();
-	bool success = (! MESH_HEADER_PROCESS_FAILED)
-		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
-		&& gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+    bool success = (!MESH_HEADER_PROCESS_FAILED)
+        && ((data != NULL) == (data_size > 0)); // if we have data but no size or have size but no data, something is wrong;
 	llassert(success);
+    EMeshProcessingResult res = MESH_UNKNOWN;
+    if (success)
+    {
+        res = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+        success = (res == MESH_OK);
+    }
 	if (! success)
 	{
 		// *TODO:  Get real reason for parse failure here.  Might we want to retry?
 		LL_WARNS(LOG_MESH) << "Unable to parse mesh header.  ID:  " << mesh_id
-						   << ", Unknown reason.  Not retrying."
+						   << ", Size: " << data_size
+						   << ", Reason: " << res << " Not retrying."
 						   << LL_ENDL;
 
 		// Can't get the header so none of the LODs will be available
@@ -3430,7 +3470,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3
 {
 	if ((!MESH_PHYS_SHAPE_PROCESS_FAILED)
 		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
-		&& gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size))
+		&& gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size) == MESH_OK)
 	{
 		// good fetch from sim, write to VFS for caching
 		LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index bba0c9f2cb1542b56f5cbf326089407a468e0bf9..9a627dabcbe5b36e08c3b7be77ec31aa6e82c688 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -57,6 +57,8 @@ typedef enum e_mesh_processing_result_enum
     MESH_NO_DATA = 1,
     MESH_OUT_OF_MEMORY,
     MESH_HTTP_REQUEST_FAILED,
+    MESH_PARSE_FAILURE,
+    MESH_INVALID,
     MESH_UNKNOWN
 } EMeshProcessingResult;
 
@@ -336,11 +338,11 @@ class LLMeshRepoThread : public LLThread
 
 	bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true);
 	bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true);
-	bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
+	EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
 	EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
 	bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
-	bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
+	EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	LLSD& getMeshHeader(const LLUUID& mesh_id);
 
 	void notifyLoadedMeshes();
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 852ba846ffa321e5613d368dba0605b4b58fcb92..272e7ae351442aab4b131678335af77dc1c47478 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1047,6 +1047,7 @@ void LLOutfitGallery::updateSnapshotFolderObserver()
 void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
 {
     LLViewerInventoryCategory* category = gInventory.getCategory(category_id);
+    if (category)
     {
         bool photo_loaded = false;
         LLInventoryModel::cat_array_t sub_cat_array;
diff --git a/indra/newview/llpanelexperiences.cpp b/indra/newview/llpanelexperiences.cpp
index 37981b36a95395af41021be548644bf0fa31347d..91d3b523fbc62cbc82ea1c108936f2c40d3ebf80 100644
--- a/indra/newview/llpanelexperiences.cpp
+++ b/indra/newview/llpanelexperiences.cpp
@@ -93,9 +93,20 @@ void LLPanelExperiences::setExperienceList( const LLSD& experiences )
 
         item->init(public_key);
         mExperiencesList->addItem(item, public_key);
+
+        const LLSD& experience_details = LLExperienceCache::instance().get(public_key);
+        if (experience_details.isUndefined())
+        {
+            LLExperienceCache::instance().get(public_key, boost::bind(&LLPanelExperiences::sortExperiencesList, this));
+        }
     }
 
-	mExperiencesList->sort();
+    sortExperiencesList();
+}
+
+void LLPanelExperiences::sortExperiencesList()
+{
+    mExperiencesList->sort();
 }
 
 void LLPanelExperiences::getExperienceIdsList(std::vector<LLUUID>& result)
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index f29fdfdecb3b8ba0f40eea167989ec3e4df75036..9d5afd1a6af5ef3c47d26cdb061f98b9e7510833 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -60,6 +60,8 @@ class LLPanelExperiences
     void setExperienceList(const LLSD& experiences);
     void getExperienceIdsList(std::vector<LLUUID>& result);
 
+    void sortExperiencesList();
+
     LLExperienceItem* getSelectedExperienceItem();
     void removeExperiences( const LLSD& ids );
     void removeExperience( const LLUUID& id);
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 5742b5ad1a5b7c40ce245db871037072c35fb664..23394b26f226b019ecb263a84cc8a1694f2fb3ff 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1027,21 +1027,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
 					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
 
-					bool allAttachments = true;
-					for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
-						iter != LLSelectMgr::getInstance()->getSelection()->end();iter++)
-					{
-						LLSelectNode* node = *iter;
-						LLViewerObject* object = node->getObject();
-						if (!object->isAttachment())
-						{
-							allAttachments = false;
-							break;
-						}
-					}
-
-					texture_ctrl->setBakeTextureEnabled(allAttachments);
-					
+					texture_ctrl->setBakeTextureEnabled(TRUE);
 				}
 				else if (id.isNull())
 					{
@@ -1066,21 +1052,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 					getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
 					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
 					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
-
-					bool allAttachments = true;
-					for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
-						iter != LLSelectMgr::getInstance()->getSelection()->end();iter++)
-					{
-						LLSelectNode* node = *iter;
-						LLViewerObject* object = node->getObject();
-						if (!object->isAttachment())
-						{
-							allAttachments = false;
-							break;
-				}
-			}
-
-					texture_ctrl->setBakeTextureEnabled(allAttachments);
+					
+					texture_ctrl->setBakeTextureEnabled(TRUE);
 				}
 				
 			}
@@ -1109,6 +1082,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 
 			bool enabled = (editable && isIdenticalPlanarTexgen());
 			childSetValue("checkbox planar align", align_planar && enabled);
+			childSetVisible("checkbox planar align", enabled);
 			childSetEnabled("checkbox planar align", enabled);
 			childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
 
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index cea7054d6a5825da37ef205c36f5040c8cb04627..7a6631448b087eb0ac977cc07ee17bd25a52efac 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -36,12 +36,15 @@
 #include "llpanellandmarks.h"
 #include "llplacesinventorybridge.h"
 #include "llviewerfoldertype.h"
+#include "llsdserialize.h"
 
 
 #define DEBUGGING_FRESHNESS	0
 
 const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
+const std::string NEW_INBOX_FILENAME("inbox_new_items.xml");
+
 //
 // statics
 //
@@ -57,7 +60,9 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_
 
 LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
 :	LLInventoryPanel(p)
-{}
+{
+	LLInboxNewItemsStorage::getInstance()->load();
+}
 
 LLInboxInventoryPanel::~LLInboxInventoryPanel()
 {}
@@ -127,7 +132,7 @@ void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)
     }
 
     // Compute freshness if our parent is the root folder for the inbox
-    if (mParentFolder == mRoot)
+    if ((mParentFolder == mRoot) && !mFresh)
     {
         computeFreshness();
     }
@@ -145,6 +150,12 @@ void LLInboxFolderViewFolder::draw()
 	setBadgeVisibility(mFresh);
 
 	LLFolderViewFolder::draw();
+
+	if (mFresh)
+	{
+		reshapeBadge(getRect());
+	}
+
 }
 
 BOOL LLInboxFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
@@ -167,11 +178,12 @@ void LLInboxFolderViewFolder::selectItem()
 
 void LLInboxFolderViewFolder::computeFreshness()
 {
+	LLFolderViewModelItemInventory* view_model = static_cast<LLFolderViewModelItemInventory*>(getViewModelItem());
 	const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
 
 	if (last_expansion_utc > 0)
 	{
-		mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
+		mFresh = (view_model->getCreationDate() > last_expansion_utc) || LLInboxNewItemsStorage::getInstance()->isItemFresh(view_model->getUUID());
 
 #if DEBUGGING_FRESHNESS
 		if (mFresh)
@@ -184,6 +196,11 @@ void LLInboxFolderViewFolder::computeFreshness()
 	{
 		mFresh = true;
 	}
+
+	if (mFresh)
+	{
+		LLInboxNewItemsStorage::getInstance()->addFreshItem(view_model->getUUID());
+	}
 }
 
 void LLInboxFolderViewFolder::deFreshify()
@@ -191,6 +208,7 @@ void LLInboxFolderViewFolder::deFreshify()
 	mFresh = false;
 
 	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+	LLInboxNewItemsStorage::getInstance()->removeItem(static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getUUID());
 }
 
 //
@@ -271,5 +289,55 @@ void LLInboxFolderViewItem::deFreshify()
 	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 }
 
+LLInboxNewItemsStorage::LLInboxNewItemsStorage()
+{
+}
+
+// static
+void LLInboxNewItemsStorage::destroyClass()
+{
+	LLInboxNewItemsStorage::getInstance()->saveNewItemsIds();
+}
+
+void LLInboxNewItemsStorage::saveNewItemsIds()
+{
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, NEW_INBOX_FILENAME);
+	if (!filename.empty())
+	{
+		LLSD uuids_data;
+		for (std::set<LLUUID>::const_iterator it = mNewItemsIDs.begin(); it != mNewItemsIDs.end(); it++)
+		{
+			uuids_data.append((*it));
+		}
 
+		llofstream file;
+		file.open(filename.c_str());
+		if ( file.is_open() )
+		{
+			LLSDSerialize::toPrettyXML(uuids_data, file);
+			file.close();
+		}
+	}
+}
+
+void LLInboxNewItemsStorage::load()
+{
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, NEW_INBOX_FILENAME);
+	if (!filename.empty())
+	{
+		llifstream in_file;
+		in_file.open(filename.c_str());
+
+		LLSD uuids_data;
+		if (in_file.is_open())
+		{
+			LLSDSerialize::fromXML(uuids_data, in_file);
+			in_file.close();
+			for (LLSD::array_iterator i = uuids_data.beginArray(); i != uuids_data.endArray(); ++i)
+			{
+				mNewItemsIDs.insert((*i).asUUID());
+			}
+		}
+	}
+}
 // eof
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index 0b27818c956ee0f6b41e2a8fe427baf31fdb45ca..3e508e801bab77fce0baf8a090e752b54d5200d8 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -113,4 +113,23 @@ class LLInboxFolderViewItem : public LLFolderViewItem, public LLBadgeOwner
 	bool mFresh;
 };
 
+class LLInboxNewItemsStorage : public LLSingleton<LLInboxNewItemsStorage>
+	, public LLDestroyClass<LLInboxNewItemsStorage>
+{
+	LLSINGLETON(LLInboxNewItemsStorage);
+	LOG_CLASS(LLInboxNewItemsStorage);
+public:
+	static void destroyClass();
+	void saveNewItemsIds();
+
+	void load();
+	
+	void addFreshItem(const LLUUID& id) { mNewItemsIDs.insert(id); }
+	void removeItem(const LLUUID& id) { mNewItemsIDs.erase(id); }
+	bool isItemFresh(const LLUUID& id) { return (mNewItemsIDs.find(id) != mNewItemsIDs.end()); }
+
+private:
+	std::set<LLUUID> mNewItemsIDs;
+};
+
 #endif //LL_INBOXINVENTORYPANEL_H
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 8019335f974836b1f4e77f65694a0348b6f7e8ed..8fff52ca4e0109466aacdb76a53d8c76a0b761e4 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -55,6 +55,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
 	mMyOutfitsPanel(NULL),
 	mCurrentOutfitPanel(NULL),
 	mActivePanel(NULL),
+	mAppearanceTabs(NULL),
 	mInitialized(false)
 {
 	gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this));
@@ -312,6 +313,7 @@ void LLPanelOutfitsInventory::initTabPanels()
 
 void LLPanelOutfitsInventory::onTabChange()
 {
+	if (!mAppearanceTabs) return;
 	mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel());
 	if (!mActivePanel) return;
 
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 55c84815aa860e190b18761b9150485f61744f0c..2bd78f40ba6dafddaaf595199f4a82069201c968 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -73,6 +73,7 @@ bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model);
 const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM };
 const int LLPanelPrimMediaControls::kNumZoomLevels = 2;
 
+const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f;
 //
 // LLPanelPrimMediaControls
 //
@@ -93,6 +94,7 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :
 	mZoomObjectID(LLUUID::null),
 	mZoomObjectFace(0),
 	mVolumeSliderVisible(0),
+	mZoomedCameraPos(),
 	mWindowShade(NULL),
 	mHideImmediately(false),
     mSecureURL(false),
@@ -256,7 +258,7 @@ void LLPanelPrimMediaControls::focusOnTarget()
 	LLViewerMediaImpl* media_impl = getTargetMediaImpl();
 	if(media_impl)
 	{
-		if(!media_impl->hasFocus())
+		if (!media_impl->hasFocus())
 		{	
 			// The current target doesn't have media focus -- focus on it.
 			LLViewerObject* objectp = getTargetObject();
@@ -307,7 +309,8 @@ void LLPanelPrimMediaControls::updateShape()
 
 	bool can_navigate = parcel->getMediaAllowNavigate();
 	bool enabled = false;
-	bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace);
+	bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace) && !isZoomDistExceeding();
+	
 	// There is no such thing as "has_focus" being different from normal controls set
 	// anymore (as of user feedback from bri 10/09).  So we cheat here and force 'has_focus'
 	// to 'true' (or, actually, we use a setting)
@@ -1141,7 +1144,7 @@ void LLPanelPrimMediaControls::updateZoom()
 	if (zoom_padding > 0.0f)
 	{	
 		// since we only zoom into medium for now, always set zoom_in constraint to true
-		LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true);
+		mZoomedCameraPos = LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true);
 	}
 	
 	// Remember the object ID/face we zoomed into, so we can update the zoom icon appropriately
@@ -1401,6 +1404,10 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible()
 	return mVolumeSliderVisible > 0;
 }
 
+bool LLPanelPrimMediaControls::isZoomDistExceeding()
+{
+	return (gAgentCamera.getCameraPositionGlobal() - mZoomedCameraPos).normalize() >= EXCEEDING_ZOOM_DISTANCE;
+}
 
 void LLPanelPrimMediaControls::clearFaceOnFade()
 {
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index d4301aaf7ccbddb157114cba9e39ef30d4830d65..86fc03655389f24e5138dd6345249e735e453661 100644
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -119,6 +119,8 @@ class LLPanelPrimMediaControls : public LLPanel
 	void showVolumeSlider();
 	void hideVolumeSlider();
 	bool shouldVolumeSliderBeVisible();
+
+	bool isZoomDistExceeding();
 	
 	static void onScrollUp(void* user_data);
 	static void onScrollUpHeld(void* user_data);
@@ -183,6 +185,8 @@ class LLPanelPrimMediaControls : public LLPanel
 	F32 mZoomMediumPadding;
 	F32 mZoomFarPadding;
 	S32 mTopWorldViewAvoidZone;
+
+	LLVector3d mZoomedCameraPos;
 	
 	LLUICtrl *mMediaPanelScroll;
 	LLButton *mScrollUpCtrl;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index a23830e8e1764e17eda4bc0e8a8338ca6fbef1a7..1c14acd843489d115c4ee39360295dbf23094b81 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -43,9 +43,8 @@ static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_invent
 static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER;
 
 LLPlacesInventoryPanel::LLPlacesInventoryPanel(const Params& p) : 
-	LLInventoryPanel(p),
+    LLAssetFilteredInventoryPanel(p),
 	mSavedFolderState(NULL)
-
 {
 	mInvFVBridgeBuilder = &PLACES_INVENTORY_BUILDER;
 	mSavedFolderState = new LLSaveFolderState();
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 27d9b83bd170731c599cb7db6d9e76741160cde1..562943841519033fdc8c35a7ee24501e3747de84 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -32,14 +32,16 @@
 class LLLandmarksPanel;
 class LLFolderView;
 
-class LLPlacesInventoryPanel : public LLInventoryPanel
+class LLPlacesInventoryPanel : public LLAssetFilteredInventoryPanel
 {
 public:
 	struct Params 
-		:	public LLInitParam::Block<Params, LLInventoryPanel::Params>
+		:	public LLInitParam::Block<Params, LLAssetFilteredInventoryPanel::Params>
 	{
 		Params()
-		{}
+		{
+           filter_asset_type = "landmark";
+       }
 	};
 
 	LLPlacesInventoryPanel(const Params& p);
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
index d5b384ceb9559e25052fedd444581e918ed42d79..0de30e9e014eaabd8805c5a393e87efe6d59ae90 100644
--- a/indra/newview/llpresetsmanager.h
+++ b/indra/newview/llpresetsmanager.h
@@ -33,6 +33,7 @@
 #include <map>
 
 static const std::string PRESETS_DEFAULT = "Default";
+static const std::string PRESETS_DEFAULT_UPPER = "DEFAULT";
 static const std::string PRESETS_DIR = "presets";
 static const std::string PRESETS_GRAPHIC = "graphic";
 static const std::string PRESETS_CAMERA = "camera";
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index e9feae3457bec753b914eec5d3969f3dbcf11469..3e3ab3a6764ef1177f91d3f4409f449d607c8993 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -404,28 +404,30 @@ void LLProgressView::initLogos()
     // with no internal paddings so it gets additional padding
     icon_width = 77;
     icon_height = 21;
-    S32 pad_y = 4;
+    S32 pad_fmod_y = 4;
     texture_start_x++;
     loadLogo(temp_str + "fmod_logo.png",
         image_codec,
-        LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y),
+        LLRect(texture_start_x, texture_start_y + pad_fmod_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_fmod_y),
         default_clip,
         default_clip);
 
     texture_start_x += icon_width + default_pad + 1;
-#endif
+#endif //LL_FMODSTUDIO
+#ifdef LL_HAVOK
     // original image size is 342x113, central element is on a larger side
     // plus internal padding, so it gets slightly more height than desired 32
     icon_width = 88;
     icon_height = 29;
-    pad_y = -1;
+    S32 pad_havok_y = -1;
     loadLogo(temp_str + "havok_logo.png",
         image_codec,
-        LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y),
+        LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y),
         default_clip,
         default_clip);
 
     texture_start_x += icon_width + default_pad;
+#endif //LL_HAVOK
 
     // 108x41
     icon_width = 74;
@@ -545,6 +547,7 @@ void LLProgressView::onCancelButtonClicked(void*)
 	// cancel is pressed while teleporting inside region (EXT-4911)
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
+		LL_INFOS() << "User requesting quit during login" << LL_ENDL;
 		LLAppViewer::instance()->requestQuit();
 	}
 	else
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 10e510b8428a777587476c42062ef26004bb58e8..26a2df8270365c72775cc9597026c2efe70dba75 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -154,3 +154,10 @@ void LLCredential::authenticatorType(std::string &idType)
 		
 	}
 }
+
+LLCertException::LLCertException(const LLSD& cert_data, const std::string& msg)
+  : LLException(msg),
+    mCertData(cert_data)
+{
+    LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;
+}
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index 69b6b32923505fd7aaee0774e0e5b6fc07f9e584..14059f828a424dea7cbb8569c7d5c316046c63b7 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -75,6 +75,7 @@
 
 #define CERT_EXTENDED_KEY_USAGE "extendedKeyUsage"
 #define CERT_EKU_SERVER_AUTH SN_server_auth
+#define CERT_EKU_TLS_SERVER_AUTH LN_server_auth
 
 #define CERT_SUBJECT_KEY_IDENTFIER "subjectKeyIdentifier"
 #define CERT_AUTHORITY_KEY_IDENTIFIER "authorityKeyIdentifier"
@@ -334,17 +335,23 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred);
 class LLCertException: public LLException
 {
 public:
-	LLCertException(const LLSD& cert_data, const std::string& msg): LLException(msg),
-        mCertData(cert_data)
-	{
-		LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;
-	}
+    LLCertException(const LLSD& cert_data, const std::string& msg);
 	virtual ~LLCertException() throw() {}
 	LLSD getCertData() const { return mCertData; }
 protected:
 	LLSD mCertData;
 };
 
+class LLAllocationCertException : public LLCertException
+{
+public:
+    LLAllocationCertException(const LLSD& cert_data) : LLCertException(cert_data, "CertAllocationFailure")
+    {
+    }
+    virtual ~LLAllocationCertException() throw() {}
+protected:
+};
+
 class LLInvalidCertificate : public LLCertException
 {
 public:
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 55e49100c3538a9bfb9ad2e80cf6d00a63626dcd..737ef30ada9490ca8eab7a4b715ba69451ace857 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -78,16 +78,16 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert,
 	BIO * pem_bio = BIO_new_mem_buf((void*)pem_cert.c_str(), pem_cert.length());
 	if(pem_bio == NULL)
 	{
-		LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
-		LLTHROW(LLInvalidCertificate(LLSD::emptyMap()));
+        LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
+        LLTHROW(LLAllocationCertException(LLSD::emptyMap()));
 	}
 	mCert = NULL;
 	PEM_read_bio_X509(pem_bio, &mCert, 0, NULL);
 	BIO_free(pem_bio);
 	if (!mCert)
 	{
-		LL_WARNS("SECAPI") << "Could not decode certificate to x509." << LL_ENDL;
-		LLTHROW(LLInvalidCertificate(LLSD::emptyMap()));
+        LL_WARNS("SECAPI") << "Could not decode certificate to x509." << LL_ENDL;
+        LLTHROW(LLInvalidCertificate(LLSD::emptyMap()));
 	}
 }
 
@@ -924,9 +924,13 @@ void _validateCert(int validation_policy,
 			LLTHROW(LLCertKeyUsageValidationException(current_cert_info));
 		}
 		// only validate EKU if the cert has it
-		if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE) && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray() &&	   
-		   (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE], 
-									LLSD((std::string)CERT_EKU_SERVER_AUTH))))
+        if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE)
+           && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray()
+           && (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE],
+                                         LLSD((std::string)CERT_EKU_TLS_SERVER_AUTH)))
+           && (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE], 
+                                         LLSD((std::string)CERT_EKU_SERVER_AUTH)))
+           )
 		{
 			LLTHROW(LLCertKeyUsageValidationException(current_cert_info));
 		}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 56068b3bbb3d44d52c1836d8449baa71bed4da78..50884762a850854bff8ae28798080ce06fbf3383 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -303,6 +303,27 @@ void LLSelectMgr::updateEffects()
 	}
 }
 
+void LLSelectMgr::resetObjectOverrides()
+{
+    resetObjectOverrides(getSelection());
+}
+
+void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
+{
+    struct f : public LLSelectedNodeFunctor
+    {
+        virtual bool apply(LLSelectNode* node)
+        {
+            node->mLastPositionLocal.setVec(0, 0, 0);
+            node->mLastRotation = LLQuaternion();
+            node->mLastScale.setVec(0, 0, 0);
+            return true;
+        }
+    } func;
+
+    selected_handle->applyToNodes(&func);
+}
+
 void LLSelectMgr::overrideObjectUpdates()
 {
 	//override any position updates from simulator on objects being edited
@@ -3910,11 +3931,11 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
 	return TRUE;
 }
 
-BOOL LLSelectMgr::isSelfAvatarSelected()
+BOOL LLSelectMgr::isMovableAvatarSelected()
 {
 	if (mAllowSelectAvatar)
 	{
-		return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
+		return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject()->isAvatar()) && getSelection()->getFirstMoveableNode(TRUE);
 	}
 	return FALSE;
 }
@@ -5130,18 +5151,27 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
 
 	bool link_operation = message_name == "ObjectLink";
 
-	//clear update override data (allow next update through)
-	struct f : public LLSelectedNodeFunctor
-	{
-		virtual bool apply(LLSelectNode* node)
-		{
-			node->mLastPositionLocal.setVec(0,0,0);
-			node->mLastRotation = LLQuaternion();
-			node->mLastScale.setVec(0,0,0);
-			return true;
-		}
-	} func;
-	selected_handle->applyToNodes(&func);
+    if (mAllowSelectAvatar)
+    {
+        if (selected_handle->getObjectCount() == 1
+            && selected_handle->getFirstObject() != NULL
+            && selected_handle->getFirstObject()->isAvatar())
+        {
+            // Server doesn't move avatars at the moment, it is a local debug feature,
+            // but server does update position regularly, so do not drop mLastPositionLocal
+            // Position override for avatar gets reset in LLAgentCamera::resetView().
+        }
+        else
+        {
+            // drop mLastPositionLocal (allow next update through)
+            resetObjectOverrides(selected_handle);
+        }
+    }
+    else
+    {
+        //clear update override data (allow next update through)
+        resetObjectOverrides(selected_handle);
+    }
 
 	std::queue<LLSelectNode*> nodes_to_send;
 
@@ -6851,51 +6881,26 @@ void LLSelectMgr::pauseAssociatedAvatars()
 			
         mSelectedObjects->mSelectType = getSelectTypeForObject(object);
 
-        bool is_attached = false;
-        if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && 
-            isAgentAvatarValid())
+        LLVOAvatar* parent_av = NULL;
+        if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT)
         {
             // Selection can be obsolete, confirm that this is an attachment
-            LLViewerObject* parent = (LLViewerObject*)object->getParent();
-            while (parent != NULL)
-            {
-                if (parent->isAvatar())
-                {
-                    is_attached = true;
-                    break;
-                }
-                else
-                {
-                    parent = (LLViewerObject*)parent->getParent();
-                }
-            }
+            // and find parent avatar
+            parent_av = object->getAvatarAncestor();
         }
 
-
-        if (is_attached)
+        // Can be both an attachment and animated object
+        if (parent_av)
         {
-            if (object->isAnimatedObject())
-            {
-                // Is an animated object attachment.
-                // Pause both the control avatar and the avatar it's attached to.
-                if (object->getControlAvatar())
-                {
-                    mPauseRequests.push_back(object->getControlAvatar()->requestPause());
-                }
-                mPauseRequests.push_back(gAgentAvatarp->requestPause());
-            }
-            else
-            {
-                // Is a regular attachment. Pause the avatar it's attached to.
-                mPauseRequests.push_back(gAgentAvatarp->requestPause());
-            }
+            // It's an attachment. Pause the avatar it's attached to.
+            mPauseRequests.push_back(parent_av->requestPause());
         }
-        else if (object && object->isAnimatedObject() && object->getControlAvatar())
+
+        if (object->isAnimatedObject() && object->getControlAvatar())
         {
-            // Is a non-attached animated object. Pause the control avatar.
+            // It's an animated object. Pause the control avatar.
             mPauseRequests.push_back(object->getControlAvatar()->requestPause());
         }
-
     }
 }
 
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 3bed484b588a0897fc2180c4d824ac738a787a3e..57fdfce15208cafaf3c39b6fff8ccfa214f11478 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -458,6 +458,13 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	void clearSelections();
 	void update();
 	void updateEffects(); // Update HUD effects
+
+	// When we edit object's position/rotation/scale we set local
+	// overrides and ignore any updates (override received valeus).
+	// When we send data to server, we send local values and reset
+	// overrides
+	void resetObjectOverrides();
+	void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
 	void overrideObjectUpdates();
 
 	// Returns the previous value of mForceSelection
@@ -725,7 +732,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 
 	LLPermissions* findObjectPermissions(const LLViewerObject* object);
 
-	BOOL isSelfAvatarSelected();
+	BOOL isMovableAvatarSelected();
 
 	void selectDelete();							// Delete on simulator
 	void selectForceDelete();			// just delete, no into trash
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 97b5b2a57dc57ef1e48b5990cc009900d6f751e7..1e5b893cbc8e5c218d54284aef9e5dcc7c78b50e 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -678,8 +678,17 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
 	{
     shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);        
 
+    // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
     LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
-    vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta());
+    LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() );
+
+    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+    // Keep in Sync!
+    // * indra\newview\llsettingsvo.cpp
+    // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl
+    // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+    cloud_scroll[0] = -cloud_scroll[0];
+    vect_c_p_d1 += cloud_scroll;
     shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV);
 
     LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 77bbcdada65d5dfd00113c36a336a551ce3cc563..afb25778aa257db495b7f5c0e9b104b52cfab674 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -556,7 +556,9 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
 	if (!getSpatialPartition()->mRenderByGroup && 
 		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE &&
 		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
-		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
+		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE &&
+		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR &&
+		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV)
 	{
 		setState(GEOM_DIRTY);
 		gPipeline.markRebuild(this, TRUE);
@@ -3448,7 +3450,7 @@ class LLOctreeRenderNonOccluded : public OctreeTraveler
 						U8 index = facep->getTextureIndex();
 						if (facep->mDrawInfo)
 						{
-							if (index < 255)
+							if (index < FACE_DO_NOT_BATCH_TEXTURES)
 							{
 								if (facep->mDrawInfo->mTextureList.size() <= index)
 								{
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 7e65da42f7e471d9760d6920529d254b8834d676..919f386d29b5095dd3fa1f4a34ffc8301a138e07 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -685,6 +685,18 @@ class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
 	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
 };
 
+class LLAvatarBridge : public LLVolumeBridge
+{
+public:
+	LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+};
+
+class LLControlAVBridge : public LLVolumeBridge
+{
+public:
+	LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+};
+
 class LLHUDBridge : public LLVolumeBridge
 {
 public:
@@ -702,6 +714,18 @@ class LLBridgePartition : public LLSpatialPartition
 	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) {  }
 };
 
+class LLAvatarPartition : public LLBridgePartition
+{
+public:
+	LLAvatarPartition(LLViewerRegion* regionp);
+};
+
+class LLControlAVPartition : public LLBridgePartition
+{
+public:
+	LLControlAVPartition(LLViewerRegion* regionp);
+};
+
 class LLHUDPartition : public LLBridgePartition
 {
 public:
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6d20dcf18881b016e475a531c616298925f499f6..3ef2d47d372d946c98dad71c6957c11d8d462bbd 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -917,9 +917,9 @@ bool idle_startup()
 		}
 
 		// Set PerAccountSettingsFile to the default value.
-		gSavedSettings.setString("PerAccountSettingsFile",
-			gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, 
-				LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")));
+		std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"));
+		gSavedSettings.setString("PerAccountSettingsFile", settings_per_account);
+		gDebugInfo["PerAccountSettingsFilename"] = settings_per_account;
 
 		// Note: can't store warnings files per account because some come up before login
 		
@@ -1105,6 +1105,8 @@ bool idle_startup()
 				// Its either downloading or declined.
 				// If optional was skipped this case shouldn't 
 				// be reached.
+
+				LL_INFOS("LLStartup") << "Forcing a quit due to update." << LL_ENDL;
 				LLLoginInstance::getInstance()->disconnect();
 				LLAppViewer::instance()->forceQuit();
 			}
@@ -1125,7 +1127,24 @@ bool idle_startup()
 					{
 						// This was a certificate error, so grab the certificate
 						// and throw up the appropriate dialog.
-						LLPointer<LLCertificate> certificate = gSecAPIHandler->getCertificate(response["certificate"]);
+                        LLPointer<LLCertificate> certificate;
+                        try
+                        {
+                            certificate = gSecAPIHandler->getCertificate(response["certificate"]);
+                        }
+                        catch (LLCertException &cert_exception)
+                        {
+                            LL_WARNS("LLStartup", "SECAPI") << "Caught " << cert_exception.what() << " certificate expception on getCertificate("<< response["certificate"] << ")" << LL_ENDL;
+                            LLSD args;
+                            args["REASON"] = LLTrans::getString(cert_exception.what());
+
+                            LLNotificationsUtil::add("GeneralCertificateErrorShort", args, response,
+                                general_cert_done);
+
+                            reset_login();
+                            gSavedSettings.setBOOL("AutoLogin", FALSE);
+                            show_connect_box = true;
+                        }
 						if(certificate)
 						{
 							LLSD args = transform_cert_args(certificate);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 6a0464c657dcab89060297840918b2dff8f9012a..6ccb2f68e59d52618e8a21e09d3342a013e428ad 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -139,17 +139,17 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
 
 		if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
 		{
-			if ( mBakeTextureEnabled && mModeSelector->getSelectedIndex() != 2)
+			if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2)
 			{
-				mModeSelector->setSelectedIndex(2, 0);
+				mModeSelector->selectByValue(2);
 				onModeSelect(0,this);
 			}
 		}
 		else
 		{
-			if (mModeSelector->getSelectedIndex() == 2)
+			if (mModeSelector->getValue().asInteger() == 2)
 			{
-				mModeSelector->setSelectedIndex(0, 0);
+				mModeSelector->selectByValue(0);
 				onModeSelect(0,this);
 			}
 			
@@ -346,7 +346,7 @@ BOOL LLFloaterTexturePicker::postBuild()
 	}
 	mTentativeLabel = getChild<LLTextBox>("Multiple");
 
-	mResolutionLabel = getChild<LLTextBox>("unknown");
+	mResolutionLabel = getChild<LLTextBox>("size_lbl");
 
 
 	childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
@@ -362,9 +362,9 @@ BOOL LLFloaterTexturePicker::postBuild()
 
 	mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
 
-	mModeSelector = getChild<LLRadioGroup>("mode_selection");
+	mModeSelector = getChild<LLComboBox>("mode_selection");
 	mModeSelector->setCommitCallback(onModeSelect, this);
-	mModeSelector->setSelectedIndex(0, 0);
+	mModeSelector->selectByValue(0);
 
 	if(mInventoryPanel)
 	{
@@ -431,7 +431,7 @@ BOOL LLFloaterTexturePicker::postBuild()
 	getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this);
 	getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this);
 
-	setBakeTextureEnabled(FALSE);
+	setBakeTextureEnabled(TRUE);
 	return TRUE;
 }
 
@@ -755,7 +755,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
 {
 	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
-	int index = self->mModeSelector->getSelectedIndex();
+    int index = self->mModeSelector->getValue().asInteger();
 
 	self->getChild<LLButton>("Default")->setVisible(index == 0 ? TRUE : FALSE);
 	self->getChild<LLButton>("Blank")->setVisible(index == 0 ? TRUE : FALSE);
@@ -1082,7 +1082,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 
 void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
 {
-	mModeSelector->setIndexEnabled(1,enabled);
+    mModeSelector->setEnabledByValue(1, enabled);
 }
 
 void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
@@ -1090,18 +1090,18 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
 	BOOL changed = (enabled != mBakeTextureEnabled);
 
 	mBakeTextureEnabled = enabled;
-	mModeSelector->setIndexEnabled(2, enabled);
+	mModeSelector->setEnabledByValue(2, enabled);
 
-	if (!mBakeTextureEnabled && (mModeSelector->getSelectedIndex() == 2))
+	if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2))
 	{
-		mModeSelector->setSelectedIndex(0, 0);
+		mModeSelector->selectByValue(0);
 	}
 	
 	if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
 	{
-		if (mModeSelector->getSelectedIndex() != 2)
+		if (mModeSelector->getValue().asInteger() != 2)
 		{
-			mModeSelector->setSelectedIndex(2, 0);
+			mModeSelector->selectByValue(2);
 		}
 	}
 	onModeSelect(0, this);
@@ -1156,8 +1156,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
 	mImageAssetID(p.image_id),
 	mDefaultImageAssetID(p.default_image_id),
 	mDefaultImageName(p.default_image_name),
-	mFallbackImage(p.fallback_image),
-	mBakeTextureEnabled(FALSE)
+	mFallbackImage(p.fallback_image)
 {
 
 	// Default of defaults is white image for diff tex
@@ -1350,7 +1349,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
 		}
 		if (texture_floaterp)
 		{
-			texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
+			texture_floaterp->setBakeTextureEnabled(TRUE);
 		}
 
 		LLFloater* root_floater = gFloaterView->getParentFloater(this);
@@ -1529,7 +1528,6 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
 
 void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
 {
-	mBakeTextureEnabled = enabled;
 	LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
 	if (floaterp)
 	{
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index b2a34a37c4809fa2746cd0343aa8b8884c6e2ff4..92f6f89af62ab1a947a795f403adc4bbe4146867 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -36,7 +36,6 @@
 #include "llstring.h"
 #include "lluictrl.h"
 #include "llpermissionsflags.h"
-#include "llradiogroup.h"
 #include "lltextbox.h" // for params
 #include "llviewerinventory.h"
 #include "llviewborder.h" // for params
@@ -44,7 +43,7 @@
 #include "llviewertexture.h"
 #include "llwindow.h"
 
-class LLButton;
+class LLComboBox;
 class LLFloaterTexturePicker;
 class LLInventoryItem;
 class LLViewerFetchedTexture;
@@ -239,7 +238,6 @@ class LLTextureCtrl
 	BOOL					 	mShowLoadingPlaceholder;
 	std::string				 	mLoadingPlaceholderString;
 	S32						 	mLabelWidth;
-	BOOL						mBakeTextureEnabled;
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -367,7 +365,7 @@ class LLFloaterTexturePicker : public LLFloater
 	LLSaveFolderState	mSavedFolderState;
 	BOOL				mSelectedItemPinned;
 
-	LLRadioGroup*		mModeSelector;
+	LLComboBox*			mModeSelector;
 	LLScrollListCtrl*	mLocalScrollCtrl;
 
 private:
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 0d2edc0268e2be3382e1869830523b2f7574b5c4..1c4187d30f0c8b6d1aec2b78dec95027535c3221 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -549,7 +549,7 @@ void LLGLTexMemBar::draw()
     U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
     U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
 
-	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+	text = llformat("GL Tot: %d/%d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
 					total_mem.value(),
 					max_total_mem.value(),
 					bound_mem.value(),
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index a4806ceaf64df5834687b2bbbe401f9778b62d86..f01b374db117fe9f4789959ff8ca96a2844eb194 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -142,8 +142,9 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
 
 	// call the base class to propogate info to sim
 	LLTool::handleMouseDown(x, y, mask);
-	
-	if (!gAgent.leftButtonGrabbed())
+
+	// leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account
+	if (!gAgent.leftButtonGrabbed() || ((mask & DEFAULT_GRAB_MASK) != 0 && !gAgentCamera.cameraMouselook()))
 	{
 		// can grab transparent objects (how touch event propagates, scripters rely on this)
 		gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h
index 02ed5c26d752c9ffb3eeddaf0cf73ca7002a8f1f..ce0de0f946c883a2a63be332ce16623389a1a421 100644
--- a/indra/newview/lltoolgrab.h
+++ b/indra/newview/lltoolgrab.h
@@ -44,6 +44,7 @@ class LLPickInfo;
 void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset);
 void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick);
 
+const MASK DEFAULT_GRAB_MASK = MASK_CONTROL;
 
 /**
  * LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index f499c34ca4b11e05b839a2aec479d14cfe74f733..864ce09430ab0f3eba5ad1b06f5ab1f2385ea3a3 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -671,7 +671,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 	else
 	{
 		// perform a separate pick that detects transparent objects since they respond to 1-click actions
-		LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
+		LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
 
 		LLViewerObject* click_action_object = click_action_pick.getObject();
 
@@ -1449,7 +1449,7 @@ LLTool* LLToolPie::getOverrideTool(MASK mask)
 {
 	if (gSavedSettings.getBOOL("EnableGrab"))
 	{
-		if (mask == MASK_CONTROL)
+		if (mask == DEFAULT_GRAB_MASK)
 		{
 			return LLToolGrab::getInstance();
 		}
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index cacdee7e83951de2ed9b709a2dab1154d40abc58..54f80a2995242302329fd9ca02b595c591243c81 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -49,6 +49,7 @@
 /// LLViewerAssetRequest
 ///----------------------------------------------------------------------------
 
+ // There is also PoolSizeVAssetStorage value in setting that should mirror this name
 static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage";
 
 /**
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index f025863072df5c4f058f529b9f51c7284beeb96a..caf79edfe4ac12c73b93617344806c2358d4c300 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -710,9 +710,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		LLGLState::checkTextureChannels();
 		LLGLState::checkClientArrays();
 
-		BOOL to_texture = gPipeline.canUseVertexShaders() &&
-						LLPipeline::sRenderGlow;
-
 		LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
 		
 		{ 
@@ -919,31 +916,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 		stop_glerror();
 
-		if (to_texture)
-		{
-			gGL.setColorMask(true, true);
-					
-			if (LLPipeline::sRenderDeferred)
-			{
-				gPipeline.mDeferredScreen.bindTarget();
-				glClearColor(1,0,1,1);
-				gPipeline.mDeferredScreen.clear();
-			}
-			else
-			{
-				gPipeline.mScreen.bindTarget();
-				if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
-				{
-					const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
-					glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
-				}
-				gPipeline.mScreen.clear();
-			}
-			
-			gGL.setColorMask(true, false);
-		}
-		
-		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
+        gGL.setColorMask(true, true);
+
+        if (LLPipeline::sRenderDeferred)
+        {
+            gPipeline.mDeferredScreen.bindTarget();
+            glClearColor(1, 0, 1, 1);
+            gPipeline.mDeferredScreen.clear();
+        }
+        else
+        {
+            gPipeline.mScreen.bindTarget();
+            if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
+            {
+                const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
+                glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
+            }
+            gPipeline.mScreen.clear();
+        }
+
+        gGL.setColorMask(true, false);
+
+        LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
 		
 		if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
 				&& !gRestoreGL)
@@ -1005,38 +999,20 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			}
 		}
 
-		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		
-		
-		if (to_texture)
-		{
-			if (LLPipeline::sRenderDeferred)
-			{
-				gPipeline.mDeferredScreen.flush();
-				if(LLRenderTarget::sUseFBO)
-				{
-					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), 
-															  gPipeline.mDeferredScreen.getHeight(), 0, 0, 
-															  gPipeline.mDeferredScreen.getWidth(), 
-															  gPipeline.mDeferredScreen.getHeight(), 
-															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-				}
-			}
-			else
-			{
-				gPipeline.mScreen.flush();
-				if(LLRenderTarget::sUseFBO)
-				{				
-					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(), 
-															  gPipeline.mScreen.getHeight(), 0, 0, 
-															  gPipeline.mScreen.getWidth(), 
-															  gPipeline.mScreen.getHeight(), 
-															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-				}
-			}
-		}
+		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
 
-		if (LLPipeline::sRenderDeferred)
-		{
+        LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen);
+        rt.flush();
+
+        if (rt.sUseFBO)
+        {
+            LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
+                                                      rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
+                                                      GL_NEAREST);
+        }
+
+        if (LLPipeline::sRenderDeferred)
+        {
 			gPipeline.renderDeferredLighting(&gPipeline.mScreen);
 		}
 
@@ -1300,19 +1276,12 @@ void render_ui(F32 zoom_factor, int subfield)
 		gGL.popMatrix();
 	}
 
-	{
-		BOOL to_texture = gPipeline.canUseVertexShaders() &&
-							LLPipeline::sRenderGlow;
+    // Finalize scene
+    gPipeline.renderFinalize();
 
-		if (to_texture)
-		{
-			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
-		}
-		
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
-		render_hud_elements();
-		render_hud_attachments();
-	}
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
+    render_hud_elements();
+	render_hud_attachments();
 
 	LLGLSDefault gls_default;
 	LLGLSUIDefault gls_ui;
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 6990f56a080c3116066bcee0814f222c0a077913..fdfd22c1170da310609a381ff2cd172f968e7271 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -253,7 +253,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 	//----------------------------------------------------------------
 	llassert( !(mTexture.notNull() && mLayerSet) );  // mutually exclusive
 
-	LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
 	LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(mLayerSet);
 	if (mTestImageName)
 	{
@@ -280,22 +279,15 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 			gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
 		}
 	}
-	else
-	if ( !is_dummy && mTexture.notNull() )
+	else if ( !is_dummy && mTexture.notNull() )
 	{
-		if(mTexture->hasGLTexture())
-		{
-			old_mode = mTexture->getAddressMode();
-		}
 		gGL.getTexUnit(diffuse_channel)->bind(mTexture);
-		gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 	}
 	else
 	{
 		gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
 	}
 	
-	
 	U32 mask = sRenderMask;
 
 	U32 start = mMesh->mFaceVertexOffset;
@@ -341,12 +333,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 		gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT);
 	}
 
-	if (mTexture.notNull() && !is_dummy)
-	{
-		gGL.getTexUnit(diffuse_channel)->bind(mTexture);
-		gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode);
-	}
-
 	return triangle_count;
 }
 
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 71ae7bfbc3bccecbc0a60df8106729edd0b7d2ec..10099eda5b00c622bd8d676c9b2bb9b7edcb6da2 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -205,8 +205,9 @@ bool LLViewerMediaFocus::getFocus()
 }
 
 // This function selects an ideal viewing distance based on the focused object, pick normal, and padding value
-void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only)
+LLVector3d LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only)
 {
+	LLVector3d camera_pos;
 	if (object)
 	{
 		gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
@@ -254,7 +255,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
 		distance += depth * 0.5;
 
 		// Finally animate the camera to this new position and focal point
-		LLVector3d camera_pos, target_pos;
+		LLVector3d target_pos;
 		// The target lookat position is the center of the selection (in global coords)
 		target_pos = center;
 		// Target look-from (camera) position is "distance" away from the target along the normal 
@@ -287,7 +288,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
 		if (zoom_in_only &&
 		    (dist_vec_squared(gAgentCamera.getCameraPositionGlobal(), target_pos) < dist_vec_squared(camera_pos, target_pos)))
 		{
-			return;
+			return camera_pos;
 		}
 
 		gAgentCamera.setCameraPosAndFocusGlobal(camera_pos, target_pos, object->getID() );
@@ -298,6 +299,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
 		// If we have no object, focus back on the avatar.
 		gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
 	}
+	return camera_pos;
 }
 void LLViewerMediaFocus::onFocusReceived()
 {
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index fa469c36e3a1f5c81361951538816730c1103eee..effd08a559b77858abff7acb90d5ac69b41f94e5 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -63,7 +63,7 @@ class LLViewerMediaFocus :
 
 	void update();
 	
-	static void setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only = false);
+	static LLVector3d setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only = false);
 	static F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth);
 
 	bool isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 4e635a88ce84b6f9e2a9136596e00ba69dbaccf2..2d8757b6732545d90c549f951edcacbe15995d4b 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -740,6 +740,10 @@ U32 render_type_from_string(std::string render_type)
 	{
 		return LLPipeline::RENDER_TYPE_AVATAR;
 	}
+	else if ("controlAV" == render_type) // Animesh
+	{
+		return LLPipeline::RENDER_TYPE_CONTROL_AV;
+	}
 	else if ("surfacePatch" == render_type)
 	{
 		return LLPipeline::RENDER_TYPE_TERRAIN;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 9c56766d0dafb010a960f9d6be868f3726f3e7ae..7d8c6e68eab00167ff405f77c64d2af63adae4c5 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2219,8 +2219,12 @@ class LLPostponedServerObjectNotification: public LLPostponedNotification
 	}
 };
 
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM");
+
 void process_improved_im(LLMessageSystem *msg, void **user_data)
 {
+    LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM);
+
     LLUUID from_id;
     BOOL from_group;
     LLUUID to_id;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 9c91cde09a22468964e811104d8d1b6188e096b7..aa775b2babb19abe34726ebe625239b3ea963006 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -284,6 +284,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mOnActiveList(FALSE),
 	mOnMap(FALSE),
 	mStatic(FALSE),
+	mSeatCount(0),
 	mNumFaces(0),
 	mRotTime(0.f),
 	mAngularVelocityRot(),
@@ -895,7 +896,12 @@ void LLViewerObject::addChild(LLViewerObject *childp)
 	if(childp->setParent(this))
 	{
 		mChildList.push_back(childp);
-        childp->afterReparent();
+		childp->afterReparent();
+
+		if (childp->isAvatar())
+		{
+			mSeatCount++;
+		}
 	}
 }
 
@@ -924,6 +930,11 @@ void LLViewerObject::removeChild(LLViewerObject *childp)
 			{
 				childp->setParent(NULL);			
 			}
+
+			if (childp->isAvatar())
+			{
+				mSeatCount--;
+			}
 			break;
 		}
 	}
@@ -981,21 +992,10 @@ BOOL LLViewerObject::isChild(LLViewerObject *childp) const
 	return FALSE;
 }
 
-
 // returns TRUE if at least one avatar is sitting on this object
 BOOL LLViewerObject::isSeat() const
 {
-	for (child_list_t::const_iterator iter = mChildList.begin();
-		 iter != mChildList.end(); iter++)
-	{
-		LLViewerObject* child = *iter;
-		if (child->isAvatar())
-		{
-			return TRUE;
-		}
-	}
-	return FALSE;
-
+	return mSeatCount > 0;
 }
 
 BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 03c5403a1e596ae3cb016006d4edf0143f755897..12a9b47307ee5bc307cb715c9c97ea69c69e9b78 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -832,6 +832,7 @@ class LLViewerObject
 	BOOL			mOnActiveList;
 	BOOL			mOnMap;						// On the map.
 	BOOL			mStatic;					// Object doesn't move.
+	S32				mSeatCount;
 	S32				mNumFaces;
 
 	F32				mRotTime;					// Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index c966b7d4f93712af29cdd9e7ca5db60be82f221a..d5365e4ee831fd79944d5a2c3e0fff9af7e3311e 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1906,7 +1906,10 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
                             || music_url.substr(0, 8) == "https://")
                         {
                             LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender());
-                            optionally_start_music(music_url, parcel->mLocalID, region->getRegionID());
+                            if (region)
+                            {
+                                optionally_start_music(music_url, parcel->mLocalID, region->getRegionID());
+                            }
                         }
                         else
                         {
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e67826454b91686891477c85d1491bafe9f80bb6..a30c5156fab60b0bedaf46652c5bda7ad265ba94 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -102,6 +102,7 @@ const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
 BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;
 S32  LLViewerRegion::sLastCameraUpdated = 0;
 S32  LLViewerRegion::sNewObjectCreationThrottle = -1;
+LLViewerRegion::vocache_entry_map_t LLViewerRegion::sRegionCacheCleanup;
 
 typedef std::map<std::string, std::string> CapabilityMap;
 
@@ -298,6 +299,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
 
         ++mSeedCapAttempts;
 
+        if (LLApp::isExiting())
+        {
+            return;
+        }
+
         regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
         if (!regionp) //region was removed
         {
@@ -412,6 +418,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
             break;  // no retry
         }
 
+        if (LLApp::isExiting())
+        {
+            break;
+        }
+
         regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
         if (!regionp) //region was removed
         {
@@ -515,6 +526,11 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region
             continue;  
         }
 
+        if (LLApp::isExiting())
+        {
+            break;
+        }
+
         // remove the http_result from the llsd
         result.erase("http_result");
 
@@ -609,6 +625,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mImpl->mObjectPartition.push_back(new LLGrassPartition(this));		//PARTITION_GRASS
 	mImpl->mObjectPartition.push_back(new LLVolumePartition(this));	//PARTITION_VOLUME
 	mImpl->mObjectPartition.push_back(new LLBridgePartition(this));	//PARTITION_BRIDGE
+	mImpl->mObjectPartition.push_back(new LLAvatarPartition(this));	//PARTITION_AVATAR
+	mImpl->mObjectPartition.push_back(new LLControlAVPartition(this));	//PARTITION_CONTROL_AV
 	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE
 	mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
 	mImpl->mObjectPartition.push_back(NULL);					//PARTITION_NONE
@@ -633,6 +651,9 @@ void LLViewerRegion::initStats()
 	mAlive = false;					// can become false if circuit disconnects
 }
 
+static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects");
+static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache");
+
 LLViewerRegion::~LLViewerRegion() 
 {
 	mDead = TRUE;
@@ -647,7 +668,10 @@ LLViewerRegion::~LLViewerRegion()
 	disconnectAllNeighbors();
 	LLViewerPartSim::getInstance()->cleanupRegion(this);
 
-	gObjectList.killObjects(this);
+    {
+        LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS);
+        gObjectList.killObjects(this);
+    }
 
 	delete mImpl->mCompositionp;
 	delete mParcelOverlay;
@@ -658,7 +682,10 @@ LLViewerRegion::~LLViewerRegion()
 #endif	
 	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
 
-	saveObjectCache();
+    {
+        LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE);
+        saveObjectCache();
+    }
 
 	delete mImpl;
 	mImpl = NULL;
@@ -727,6 +754,8 @@ void LLViewerRegion::saveObjectCache()
 		mCacheDirty = FALSE;
 	}
 
+	// Map of LLVOCacheEntry takes time to release, store map for cleanup on idle
+	sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end());
 	mImpl->mCacheMap.clear();
 }
 
@@ -1488,6 +1517,16 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)
 	return;
 }
 
+// static
+void LLViewerRegion::idleCleanup(F32 max_update_time)
+{
+    LLTimer update_timer;
+    while (!sRegionCacheCleanup.empty() && (max_update_time - update_timer.getElapsedTimeF32() > 0))
+    {
+        sRegionCacheCleanup.erase(sRegionCacheCleanup.begin());
+    }
+}
+
 //update the throttling number for new object creation
 void LLViewerRegion::calcNewObjectCreationThrottle()
 {
@@ -3144,7 +3183,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
 	{
 		mCapabilitiesReceivedSignal(getRegionID());
 
-		//LLFloaterPermsDefault::sendInitialPerms();
+		LLFloaterPermsDefault::sendInitialPerms();
 
 		// This is a single-shot signal. Forget callbacks to save resources.
 		mCapabilitiesReceivedSignal.disconnect_all_slots();
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 1b226ac2c69e2e0b0aab63a14675945f37202618..477aabb971f5d82d938c6784546300e6ffc51756 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -86,6 +86,8 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 		PARTITION_GRASS,
 		PARTITION_VOLUME,
 		PARTITION_BRIDGE,
+		PARTITION_AVATAR,
+		PARTITION_CONTROL_AV, // Animesh
 		PARTITION_HUD_PARTICLE,
 		PARTITION_VO_CACHE,
 		PARTITION_NONE,
@@ -230,6 +232,9 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	F32	getWidth() const						{ return mWidth; }
 
+	// regions are expensive to release, this function gradually releases cache from memory
+	static void idleCleanup(F32 max_update_time);
+
 	void idleUpdate(F32 max_update_time);
 	void lightIdleUpdate();
 	bool addVisibleGroup(LLViewerOctreeGroup* group);
@@ -548,6 +553,9 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	LLSD mSimulatorFeatures;
 
+    typedef std::map<U32, LLPointer<LLVOCacheEntry> >	   vocache_entry_map_t;
+    static vocache_entry_map_t sRegionCacheCleanup;
+
 	// the materials capability throttle
 	LLFrameTimer mMaterialsCapThrottleTimer;
 	LLFrameTimer mRenderInfoRequestTimer;
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
index 7f7d190b92f7f773d39c48055dbd833eb174619a..c501dd00350a7dea48f940d935952c87259c8610 100644
--- a/indra/newview/llviewertexlayer.cpp
+++ b/indra/newview/llviewertexlayer.cpp
@@ -54,7 +54,7 @@ LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner,
 										 S32 width, S32 height) :
 	// ORDER_LAST => must render these after the hints are created.
 	LLTexLayerSetBuffer(owner),
-	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
+    LLViewerDynamicTexture(width, height, 4, LLViewerDynamicTexture::ORDER_LAST, FALSE),
 	mNeedsUpdate(TRUE),
 	mNumLowresUpdates(0)
 {
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 0cc1e0df06aaf1c95aae7d801199ece5397c7d0e..5b83cf7163edbeb10fb5c651c6f8b0d10780752d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1396,6 +1396,7 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
 
 void LLViewerWindow::handleQuit(LLWindow *window)
 {
+	LL_INFOS() << "Window forced quit" << LL_ENDL;
 	LLAppViewer::instance()->forceQuit();
 }
 
@@ -3924,12 +3925,12 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 
 					BOOL draw_handles = TRUE;
 
-					if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected())
+					if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
 					{
 						draw_handles = FALSE;
 					}
 
-					if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move)
+					if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
 					{
 						draw_handles = FALSE;
 					}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index d567623ac04a64659cad560789383f2d99258af8..10f51f78965d80d538ffcb4436d84efd4abf6975 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2414,6 +2414,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
 }
 
 static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE("Avatar Update");
+static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE_COMPLEXITY("Avatar Update Complexity");
 static LLTrace::BlockTimerStatHandle FTM_JOINT_UPDATE("Update Joints");
 
 //------------------------------------------------------------------------
@@ -2456,14 +2457,13 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 		return;
 	}	
 
-	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))
+	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
 		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf())
 	{
 		return;
 	}
 
     // Update should be happening max once per frame.
-	const S32 upd_freq = 4; // force update every upd_freq frames.
 	if ((mLastAnimExtents[0]==LLVector3())||
 		(mLastAnimExtents[1])==LLVector3())
 	{
@@ -2471,6 +2471,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 	}
 	else
 	{
+		const S32 upd_freq = 4; // force update every upd_freq frames.
 		mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0);
 	}
     
@@ -2555,8 +2556,41 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 	}
 		
 	idleUpdateNameTag( mLastRootPos );
+
+    // Complexity has stale mechanics, but updates still can be very rapid
+    // so spread avatar complexity calculations over frames to lesen load from
+    // rapid updates and to make sure all avatars are not calculated at once.
+    S32 compl_upd_freq = 20;
+    if (isControlAvatar())
+    {
+        // animeshes do not (or won't) have impostors nor change outfis,
+        // no need for high frequency
+        compl_upd_freq = 100;
+    }
+    else if (mLastRezzedStatus <= 0) //cloud or  init
+    {
+        compl_upd_freq = 60;
+    }
+    else if (isSelf())
+    {
+        compl_upd_freq = 5;
+    }
+    else if (mLastRezzedStatus == 1) //'grey', not fully loaded
+    {
+        compl_upd_freq = 40;
+    }
+    else if (isInMuteList()) //cheap, buffers value from search
+    {
+        compl_upd_freq = 100;
+    }
+
+    if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)
+    {
+        LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE_COMPLEXITY);
 	idleUpdateRenderComplexity();
 }
+    idleUpdateDebugInfo();
+}
 
 void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 {
@@ -2866,7 +2900,10 @@ F32 LLVOAvatar::calcMorphAmount()
 void LLVOAvatar::idleUpdateLipSync(bool voice_enabled)
 {
 	// Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
-	if ( voice_enabled && (LLVoiceClient::getInstance()->lipSyncEnabled()) && LLVoiceClient::getInstance()->getIsSpeaking( mID ) )
+    if ( voice_enabled
+        && mLastRezzedStatus > 0 // no point updating lip-sync for clouds
+        && (LLVoiceClient::getInstance()->lipSyncEnabled())
+        && LLVoiceClient::getInstance()->getIsSpeaking( mID ) )
 	{
 		F32 ooh_morph_amount = 0.0f;
 		F32 aah_morph_amount = 0.0f;
@@ -3214,7 +3251,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			std::string title_str = title->getString();
 			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
 			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
-				LLFontGL::getFontSansSerifSmall());
+				LLFontGL::getFontSansSerifSmall(), true);
 		}
 
 		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames", true);
@@ -3234,7 +3271,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			if (show_display_names)
 			{
 				addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
-					LLFontGL::getFontSansSerif());
+					LLFontGL::getFontSansSerif(), true);
 			}
 			// Suppress SLID display if display name matches exactly (ugh)
 			if (show_usernames && !av_name.isDisplayNameDefault())
@@ -3242,14 +3279,14 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				// *HACK: Desaturate the color
 				LLColor4 username_color = name_tag_color * 0.83f;
 				addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
-					LLFontGL::getFontSansSerifSmall());
+					LLFontGL::getFontSansSerifSmall(), true);
 			}
 		}
 		else
 		{
 			const LLFontGL* font = LLFontGL::getFontSansSerif();
 			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
-			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
+			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true);
 		}
 
 		mNameAway = is_away;
@@ -3341,7 +3378,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 	}
 }
 
-void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font)
+void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses)
 {
 	llassert(mNameText);
 	if (mVisibleChat)
@@ -3350,7 +3387,7 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,
 	}
 	else
 	{
-		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);
+		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses);
 	}
     mNameIsSet |= !line.empty();
 }
@@ -3900,6 +3937,11 @@ void LLVOAvatar::computeUpdatePeriod()
 		{ //background avatars are REALLY slow updating impostors
 			mUpdatePeriod = 16;
 		}
+		else if (mLastRezzedStatus <= 0)
+		{
+			// Don't update cloud avatars too often
+			mUpdatePeriod = 8;
+		}
 		else if ( shouldImpostor(3) )
 		{ //back 25% of max visible avatars are slow updating impostors
 			mUpdatePeriod = 8;
@@ -4286,15 +4328,15 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
     // Set mUpdatePeriod and visible based on distance and other criteria.
 	//--------------------------------------------------------------------
     computeUpdatePeriod();
-    visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
+    bool needs_update = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0;
 
 	//--------------------------------------------------------------------
-    // Early out if not visible and not self
+	// Early out if does not need update and not self
 	// don't early out for your own avatar, as we rely on your animations playing reliably
 	// for example, the "turn around" animation when entering customize avatar needs to trigger
 	// even when your avatar is offscreen
 	//--------------------------------------------------------------------
-	if (!visible && !isSelf())
+	if (!needs_update && !isSelf())
 	{
 		updateMotions(LLCharacter::HIDDEN_UPDATE);
 		return FALSE;
@@ -4343,12 +4385,17 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	mSpeed = speed;
 
 	// update animations
-	if (mSpecialRenderMode == 1) // Animation Preview
+	if (!visible)
+	{
+		updateMotions(LLCharacter::HIDDEN_UPDATE);
+	}
+	else if (mSpecialRenderMode == 1) // Animation Preview
 	{
 		updateMotions(LLCharacter::FORCE_UPDATE);
 	}
 	else
 	{
+		// Might be better to do HIDDEN_UPDATE if cloud
 		updateMotions(LLCharacter::NORMAL_UPDATE);
 	}
 
@@ -4376,10 +4423,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	// Update child joints as needed.
 	mRoot->updateWorldMatrixChildren();
 
+    if (visible)
+    {
 	// System avatar mesh vertices need to be reskinned.
 	mNeedsSkin = TRUE;
+    }
 
-	return TRUE;
+	return visible;
 }
 
 //-----------------------------------------------------------------------------
@@ -6834,13 +6884,13 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
 	pipeline->allocDrawable(this);
 	mDrawable->setLit(FALSE);
 
-	LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*) gPipeline.getPool(LLDrawPool::POOL_AVATAR);
+	LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR);
 
 	// Only a single face (one per avatar)
 	//this face will be splitted into several if its vertex buffer is too long.
 	mDrawable->setState(LLDrawable::ACTIVE);
 	mDrawable->addFace(poolp, NULL);
-	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
+	mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR);
 	
 	mNumInitFaces = mDrawable->getNumFaces() ;
 
@@ -6865,7 +6915,7 @@ static LLTrace::BlockTimerStatHandle FTM_UPDATE_AVATAR("Update Avatar");
 BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
 {
 	LL_RECORD_BLOCK_TIME(FTM_UPDATE_AVATAR);
- 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
+	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)))
 	{
 		return TRUE;
 	}
@@ -10021,7 +10071,7 @@ void LLVOAvatar::onActiveOverrideMeshesChanged()
 U32 LLVOAvatar::getPartitionType() const
 { 
 	// Avatars merely exist as drawables in the bridge partition
-	return LLViewerRegion::PARTITION_BRIDGE;
+	return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR;
 }
 
 //static
@@ -10142,7 +10192,10 @@ void LLVOAvatar::idleUpdateRenderComplexity()
 
     // Render Complexity
     calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed	
+}
 
+void LLVOAvatar::idleUpdateDebugInfo()
+{
 	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO))
 	{
 		std::string info_line;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index ca6ac5c90244a4014bb3938e1227392d9f6de790..71a81c2e3d002d9c3de43665c61e6c89ffe363b6 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -284,8 +284,9 @@ class LLVOAvatar :
 	static void		invalidateNameTag(const LLUUID& agent_id);
 	// force all name tags to rebuild, useful when display names turned on/off
 	static void		invalidateNameTags();
-	void			addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);
+	void			addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses = false);
 	void 			idleUpdateRenderComplexity();
+	void 			idleUpdateDebugInfo();
     void 			accountRenderComplexityForObject(const LLViewerObject *attached_object,
                                                      const F32 max_attachment_complexity,
                                                      LLVOVolume::texture_cost_t& textures,
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 16b27fd1445cd3283639c6087b3d50e7d5396f2a..aea12380e84c47ec87779c090ec4ba355bf45b6f 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2667,11 +2667,6 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
 		{
 			gAgentCamera.changeCameraToCustomizeAvatar();
 		}
-
-#if 0
-		gAgentAvatarp->clearVisualParamWeights();
-		gAgentAvatarp->idleUpdateAppearanceAnimation();
-#endif
 		
 		gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
 		gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 07660ca6ac16efc94a662da152592ef40c066abf..689eeee0e3f3f3649325e9d362abd9b396f651f9 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -347,36 +347,24 @@ void LLVOCacheEntry::dump() const
 
 BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
 {
-	BOOL success;
-	success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
-	if(success)
-	{
-		success = check_write(apr_file, (void*)&mCRC, sizeof(U32));
-	}
-	if(success)
-	{
-		success = check_write(apr_file, (void*)&mHitCount, sizeof(S32));
-	}
-	if(success)
-	{
-		success = check_write(apr_file, (void*)&mDupeCount, sizeof(S32));
-	}
-	if(success)
-	{
-		success = check_write(apr_file, (void*)&mCRCChangeCount, sizeof(S32));
-	}
-	if(success)
-	{
-		S32 size = mDP.getBufferSize();
-		success = check_write(apr_file, (void*)&size, sizeof(S32));
-	
-		if(success)
-		{
-			success = check_write(apr_file, (void*)mBuffer, size);
-		}
-	}
-
-	return success ;
+    static const S32 data_buffer_size = 6 * sizeof(S32);
+    static U8 data_buffer[data_buffer_size];
+    S32 size = mDP.getBufferSize();
+
+    memcpy(data_buffer, &mLocalID, sizeof(U32));
+    memcpy(data_buffer + sizeof(U32), &mCRC, sizeof(U32));
+    memcpy(data_buffer + (2 * sizeof(U32)), &mHitCount, sizeof(S32));
+    memcpy(data_buffer + (3 * sizeof(U32)), &mDupeCount, sizeof(S32));
+    memcpy(data_buffer + (4 * sizeof(U32)), &mCRCChangeCount, sizeof(S32));
+    memcpy(data_buffer + (5 * sizeof(U32)), &size, sizeof(S32));
+
+    BOOL success = check_write(apr_file, (void*)data_buffer, data_buffer_size);
+    if (success)
+    {
+        success = check_write(apr_file, (void*)mBuffer, size);
+    }
+
+    return success;
 }
 
 //static 
@@ -1537,7 +1525,8 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
 		{
 			S32 num_entries = cache_entry_map.size() ;
 			success = check_write(&apr_file, &num_entries, sizeof(S32));
-	
+
+			// This can have a lot of entries, so might be better to dump them into buffer first and write in one go.
 			for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
 			{
 				if(!removal_enabled || iter->second->isValid())
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 42a1cf95a77bc29549451614909546ae69baed30..976ef61d8ea32f4fa3d2d6511b56b410b62d8b4a 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -274,6 +274,8 @@ static void killGateway()
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
+bool LLVivoxVoiceClient::sShuttingDown = false;
+
 LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mSessionTerminateRequested(false),
 	mRelogRequested(false),
@@ -381,6 +383,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
 	{
 		mAvatarNameCacheConnection.disconnect();
 	}
+    sShuttingDown = true;
 }
 
 //---------------------------------------------------
@@ -411,8 +414,11 @@ void LLVivoxVoiceClient::terminate()
 	}
 	else
 	{
+		mRelogRequested = false;
 		killGateway();
 	}
+
+    sShuttingDown = true;
 }
 
 //---------------------------------------------------
@@ -660,12 +666,18 @@ void LLVivoxVoiceClient::voiceControlCoro()
 
     U32 retry = 0;
 
-    while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+    while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && !sShuttingDown)
     {
         LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
         llcoro::suspendUntilTimeout(1.0);
     }
 
+    if (sShuttingDown)
+    {
+        mIsCoroutineActive = false;
+        return;
+    }
+
     do
     {
         bool success = startAndConnectSession();
@@ -691,7 +703,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
             << "disconnected"
             << " RelogRequested=" << mRelogRequested
             << LL_ENDL;            
-        if (mRelogRequested)
+        if (mRelogRequested && !sShuttingDown)
         {
             if (!success)
             {
@@ -706,14 +718,14 @@ void LLVivoxVoiceClient::voiceControlCoro()
                 LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
             }
 
-            while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+            while (isGatewayRunning() || (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && !sShuttingDown))
             {
                 LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL;
                 llcoro::suspendUntilTimeout(1.0);
             }
         }
     }
-    while (mVoiceEnabled && mRelogRequested);
+    while (mVoiceEnabled && mRelogRequested && !sShuttingDown);
     mIsCoroutineActive = false;
     LL_INFOS("Voice") << "exiting" << LL_ENDL;
 }
@@ -758,7 +770,7 @@ bool LLVivoxVoiceClient::endAndDisconnectSession()
 
 bool LLVivoxVoiceClient::callbackEndDaemon(const LLSD& data)
 {
-    if (!LLAppViewer::isExiting() && mVoiceEnabled)
+    if (!sShuttingDown && mVoiceEnabled)
     {
         LL_WARNS("Voice") << "SLVoice terminated " << ll_stream_notation_sd(data) << LL_ENDL;
         terminateAudioSession(false);
@@ -915,7 +927,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
     LL_DEBUGS("Voice") << "Connecting to vivox daemon:" << mDaemonHost << LL_ENDL;
 
     LLVoiceVivoxStats::getInstance()->reset();
-    while (!mConnected)
+    while (!mConnected && !sShuttingDown)
     {
         LLVoiceVivoxStats::getInstance()->connectionAttemptStart();
         LL_DEBUGS("Voice") << "Attempting to connect to vivox daemon: " << mDaemonHost << LL_ENDL;
@@ -934,6 +946,11 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
     }
     
     //---------------------------------------------------------------------
+    if (sShuttingDown && !mConnected)
+    {
+        return false;
+    }
+
     llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
 
     while (!mPump)
@@ -970,7 +987,7 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
 {
     LL_INFOS("Voice") << "Provisioning voice account." << LL_ENDL;
 
-    while (!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived())
+    while ((!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived()) && !sShuttingDown)
     {
         LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
         // *TODO* Pump a message for wake up.
@@ -1014,10 +1031,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
         {
             provisioned = true;
         }        
-    } while (!provisioned && retryCount <= PROVISION_RETRY_MAX);
+    } while (!provisioned && retryCount <= PROVISION_RETRY_MAX && !sShuttingDown);
+
+    if (sShuttingDown && !provisioned)
+    {
+        return false;
+    }
 
     LLVoiceVivoxStats::getInstance()->provisionAttemptEnd(provisioned);
-    if (! provisioned )
+    if (!provisioned)
     {
         LL_WARNS("Voice") << "Could not access voice provision cap after " << retryCount << " attempts." << LL_ENDL;
         return false;
@@ -1058,6 +1080,11 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
         LL_WARNS("Voice") << "cannot establish connection; enabled "<<mVoiceEnabled<<" initialized "<<mIsInitialized<<LL_ENDL;
         return false;
     }
+
+    if (sShuttingDown)
+    {
+        return false;
+    }
     
     LLSD result;
     bool connected(false);
@@ -1078,7 +1105,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
             connected = LLSD::Boolean(result["connector"]);
             if (!connected)
             {
-                if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX)
+                if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX && !sShuttingDown)
                 {
                     F32 timeout = LLSD::Real(result["retry"]);
                     timeout *= retries;
@@ -1106,7 +1133,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
         LL_DEBUGS("Voice") << (connected ? "" : "not ") << "connected, "
                            << (giving_up ? "" : "not ") << "giving up"
                            << LL_ENDL;
-    } while (!connected && !giving_up);
+    } while (!connected && !giving_up && !sShuttingDown);
 
     if (giving_up)
     {
@@ -1193,7 +1220,7 @@ bool LLVivoxVoiceClient::loginToVivox()
         {
             std::string loginresp = result["login"];
 
-            if ((loginresp == "retry") || (loginresp == "timeout"))
+            if (((loginresp == "retry") || (loginresp == "timeout")) && !sShuttingDown)
             {
                 LL_WARNS("Voice") << "login failed with status '" << loginresp << "' "
                                   << " count " << loginRetryCount << "/" << LOGIN_RETRY_MAX
@@ -1235,9 +1262,14 @@ bool LLVivoxVoiceClient::loginToVivox()
             {
                 account_login = true;
             }
+            else if (sShuttingDown)
+            {
+                mIsLoggingIn = false;
+                return false;
+            }
         }
 
-    } while (!response_ok || !account_login);
+    } while ((!response_ok || !account_login) && !sShuttingDown);
 
     mRelogRequested = false;
     mIsLoggedIn = true;
@@ -1690,12 +1722,12 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
     // the region chat.
     mSessionTerminateRequested = false;
 
-    bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested  && !LLApp::isExiting());
+    bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested  && !sShuttingDown);
     LL_DEBUGS("Voice") << "exiting"
                        << " VoiceEnabled " << mVoiceEnabled
                        << " IsInitialized " << mIsInitialized
                        << " RelogRequested " << mRelogRequested
-                       << " AppExiting " << LLApp::isExiting()
+                       << " ShuttingDown " << (sShuttingDown ? "TRUE" : "FALSE")
                        << " returning " << status
                        << LL_ENDL;
     return status;
@@ -1733,6 +1765,12 @@ bool LLVivoxVoiceClient::waitForChannel()
             mIsProcessingChannels = true;
             llcoro::suspend();
 
+            if (sShuttingDown)
+            {
+                mRelogRequested = false;
+                break;
+            }
+
             if (mTuningMode)
             {
                 performMicTuning();
@@ -1777,7 +1815,14 @@ bool LLVivoxVoiceClient::waitForChannel()
             {
                 llcoro::suspendUntilTimeout(1.0);
             }
-        } while (mVoiceEnabled && !mRelogRequested);
+
+            if (sShuttingDown)
+            {
+                mRelogRequested = false;
+                break;
+            }
+
+        } while (mVoiceEnabled && !mRelogRequested && !sShuttingDown);
 
         LL_DEBUGS("Voice")
             << "leaving inner waitForChannel loop"
@@ -1799,14 +1844,14 @@ bool LLVivoxVoiceClient::waitForChannel()
                 return false;
             }
         }
-    } while (mVoiceEnabled && mRelogRequested && isGatewayRunning());
+    } while (mVoiceEnabled && mRelogRequested && isGatewayRunning() && !sShuttingDown);
 
     LL_DEBUGS("Voice")
         << "exiting"
         << " RelogRequested=" << mRelogRequested
         << " VoiceEnabled=" << mVoiceEnabled
         << LL_ENDL;
-    return true;
+    return !sShuttingDown;
 }
 
 bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 210c7264527fe8f591e007c6eb8c411221f8bfd1..699c85066bcd9ff6db96e7eab976483d1adab3d6 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -912,6 +912,8 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
     bool    mIsProcessingChannels;
     bool    mIsCoroutineActive;
 
+    static bool sShuttingDown; // corutines can last longer than vivox so we need a static variable as a shutdown flag
+
     LLEventMailDrop mVivoxPump;
 };
 
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 98eb2d3cdc69c8a57ac20df46b03a673f29c4398..ef39faa8142fabbc1f1e62a55c79c7a35ae01610 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4585,8 +4585,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
 					{
 						U8 mode = mat->getDiffuseAlphaMode();
 
-						if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE ||
-							mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
+						if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE
+							|| mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+							|| (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0))
 						{
 							ignore_alpha = true;
 						}
@@ -4892,6 +4893,14 @@ U32 LLVOVolume::getPartitionType() const
 	{
 		return LLViewerRegion::PARTITION_HUD;
 	}
+	if (isAnimatedObject() && getControlAvatar())
+	{
+		return LLViewerRegion::PARTITION_CONTROL_AV;
+	}
+	if (isAttachment())
+	{
+		return LLViewerRegion::PARTITION_AVATAR;
+	}
 
 	return LLViewerRegion::PARTITION_VOLUME;
 }
@@ -4922,6 +4931,20 @@ LLVolumeGeometryManager()
 	mSlopRatio = 0.25f;
 }
 
+LLAvatarBridge::LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+	: LLVolumeBridge(drawablep, regionp)
+{
+	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
+	mPartitionType = LLViewerRegion::PARTITION_AVATAR;
+}
+
+LLControlAVBridge::LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+	: LLVolumeBridge(drawablep, regionp)
+{
+	mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV;
+	mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV;
+}
+
 bool can_batch_texture(LLFace* facep)
 {
 	if (facep->getTextureEntry()->getBumpmap())
@@ -5100,7 +5123,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 	}
 
 
-	if (index < 255 && idx >= 0)
+	if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
 	{
 		if (mat || draw_vec[idx]->mMaterial)
 		{ //can't batch textures when materials are present (yet)
@@ -5146,7 +5169,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		draw_vec[idx]->mEnd += facep->getGeomCount();
 		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
 
-		if (index < 255 && index >= draw_vec[idx]->mTextureList.size())
+		if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size())
 		{
 			draw_vec[idx]->mTextureList.resize(index+1);
 			draw_vec[idx]->mTextureList[index] = tex;
@@ -5233,7 +5256,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 			draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;
 		}
 
-		if (index < 255)
+		if (index < FACE_DO_NOT_BATCH_TEXTURES)
 		{ //initialize texture list for texture batching
 			draw_info->mTextureList.resize(index+1);
 			draw_info->mTextureList[index] = tex;
@@ -5266,7 +5289,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
 				LLDrawPool* drawpool = face->getPool();
 				if (drawpool)
 				{
-					if (drawpool->getType() == LLDrawPool::POOL_AVATAR)
+					if (drawpool->getType() == LLDrawPool::POOL_AVATAR
+						|| drawpool->getType() == LLDrawPool::POOL_CONTROL_AV)
 					{
 						return (LLDrawPoolAvatar*) drawpool;
 					}
@@ -5545,7 +5569,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 						//remove face from old pool if it exists
 						LLDrawPool* old_pool = facep->getPool();
-						if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+						if (old_pool
+							&& (old_pool->getType() == LLDrawPool::POOL_AVATAR || old_pool->getType() == LLDrawPool::POOL_CONTROL_AV))
 						{
 							((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
 						}
@@ -6365,7 +6390,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 
 					//face has no texture index
 					facep->mDrawInfo = NULL;
-					facep->setTextureIndex(255);
+					facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
 
 					if (geom_count + facep->getGeomCount() > max_vertices)
 					{ //cut batches on geom count too big
@@ -6429,7 +6454,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 			facep->setGeomIndex(index_offset);
 			facep->setVertexBuffer(buffer);	
 			
-			if (batch_textures && facep->getTextureIndex() == 255)
+			if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES)
 			{
 				LL_ERRS() << "Invalid texture index." << LL_ENDL;
 			}
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 368a3f23351822c03944e403660f887091bd756f..d428cb15682779e6369abe6a167c1eccf483a4bb 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -99,6 +99,9 @@ LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline)
 
 inline F32 LLVOWLSky::calcPhi(U32 i)
 {
+    // Calc: PI/8 * 1-((1-t^4)*(1-t^4))  { 0<t<1 }
+    // Demos: \pi/8*\left(1-((1-x^{4})*(1-x^{4}))\right)\ \left\{0<x\le1\right\}
+
 	// i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f]
 	F32 t = float(i) / float(getNumStacks());
 
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8989bae96a7fd5ed8329ca5b9ef04c8e99219bc8..a1a1db35d64f600ff2fdc1594323dd3f5b6569ca 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -730,11 +730,20 @@ void LLWorld::updateRegions(F32 max_update_time)
 		{
 			//perform some necessary but very light updates.
 			(*iter)->lightIdleUpdate();
-		}		
+		}
+	}
+
+	if(max_time > 0.f)
+	{
+		max_time = llmin((F32)(max_update_time - update_timer.getElapsedTimeF32()), max_update_time * 0.25f);
+	}
+	if(max_time > 0.f)
+	{
+		LLViewerRegion::idleCleanup(max_time);
 	}
 
 	sample(sNumActiveCachedObjects, mNumOfActiveCachedObjects);
-		}
+}
 
 void LLWorld::clearAllVisibleObjects()
 {
@@ -1208,11 +1217,14 @@ class LLEstablishAgentCommunication : public LLHTTPNode
 	}
 };
 
+static LLTrace::BlockTimerStatHandle FTM_DISABLE_REGION("Disable Region");
 // disable the circuit to this simulator
 // Called in response to "DisableSimulator" message.
 void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
-{	
-	LLHost host = mesgsys->getSender();
+{
+    LL_RECORD_BLOCK_TIME(FTM_DISABLE_REGION);
+
+    LLHost host = mesgsys->getSender();
 
 	//LL_INFOS() << "Disabling simulator with message from " << host << LL_ENDL;
 	LLWorld::getInstance()->removeRegion(host);
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 8e2539606bf8b1c76bbef88cf297c48959dc404b..32c8ce66a01834353042787d838abc97725e93ed 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -240,16 +240,16 @@ void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle,
 
 	if (!status)
 	{
+        mImpl->setHttpStatus(status);
+        LLSD errordata = status.getErrorData();
+        mImpl->mErrorCertData = errordata;
+
 		if ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) &&
 			(status.toULong() != CURLE_SSL_CACERT))
 		{
 			// if we have a curl error that's not already been handled
-			// (a non cert error), then generate the error message as
+			// (a non cert error), then generate the warning message as
 			// appropriate
-			mImpl->setHttpStatus(status);
-			LLSD errordata = status.getErrorData();
-            mImpl->mErrorCertData = errordata;
-
 			LL_WARNS() << "LLXMLRPCTransaction error "
 				<< status.toHex() << ": " << status.toString() << LL_ENDL;
 			LL_WARNS() << "LLXMLRPCTransaction request URI: "
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 01438bfb9f989e34f8292d97ae3005ee123e1e46..f565573935f9aea24d21e95503627ff506a57845 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1049,25 +1049,19 @@ void LLPipeline::updateRenderBump()
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 }
 
-//static
+// static
 void LLPipeline::updateRenderDeferred()
 {
-	bool deferred = (bool(RenderDeferred && 
-					 LLRenderTarget::sUseFBO &&
-					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	 
-					 LLPipeline::sRenderBump &&
-					 RenderAvatarVP &&
-					 WindLightUseAtmosShaders)) &&
-					!gUseWireframe;
-
-	sRenderDeferred = deferred;	
-	if (deferred)
-	{ //must render glow when rendering deferred since post effect pass is needed to present any lighting at all
-		sRenderGlow = true;
-	}
+    sRenderDeferred = !gUseWireframe &&
+                      RenderDeferred &&
+                      LLRenderTarget::sUseFBO &&
+                      LLPipeline::sRenderBump &&
+                      RenderAvatarVP &&
+                      WindLightUseAtmosShaders &&
+                      (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
 }
 
-//static
+// static
 void LLPipeline::refreshCachedSettings()
 {
 	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
@@ -1259,24 +1253,20 @@ void LLPipeline::createGLBuffers()
 
 	GLuint resX = gViewerWindow->getWorldViewWidthRaw();
 	GLuint resY = gViewerWindow->getWorldViewHeightRaw();
-	
-	if (LLPipeline::sRenderGlow)
-	{ //screen space glow buffers
-		const U32 glow_res = llmax(1, 
-			llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
 
-		for (U32 i = 0; i < 3; i++)
-		{
-			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
-		}
+    // allocate screen space glow buffers
+    const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
+    for (U32 i = 0; i < 3; i++)
+    {
+        mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE);
+    }
 
-		allocateScreenBuffer(resX,resY);
-		mScreenWidth = 0;
-		mScreenHeight = 0;
-	}
-	
-	if (sRenderDeferred)
-	{
+    allocateScreenBuffer(resX, resY);
+    mScreenWidth = 0;
+    mScreenHeight = 0;
+
+    if (sRenderDeferred)
+    {
 		if (!mNoiseMap)
 		{
 			const U32 noiseRes = 128;
@@ -1609,6 +1599,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
 		break;
 
 	case LLDrawPool::POOL_AVATAR:
+	case LLDrawPool::POOL_CONTROL_AV:
 		break; // Do nothing
 
 	case LLDrawPool::POOL_SKY:
@@ -1995,7 +1986,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
 		drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
 		if (done)
 		{
-			if (drawablep->isRoot())
+			if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE))
 			{
 				drawablep->makeStatic();
 			}
@@ -3362,6 +3353,7 @@ static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order");
 void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 {
 	if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
+					  LLPipeline::RENDER_TYPE_CONTROL_AV,
 					  LLPipeline::RENDER_TYPE_GROUND,
 					  LLPipeline::RENDER_TYPE_TERRAIN,
 					  LLPipeline::RENDER_TYPE_TREE,
@@ -5774,6 +5766,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
 		break;
 
 	case LLDrawPool::POOL_AVATAR:
+	case LLDrawPool::POOL_CONTROL_AV:
 		break; // Do nothing
 
 	case LLDrawPool::POOL_SKY:
@@ -5922,6 +5915,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
 		break;
 
 	case LLDrawPool::POOL_AVATAR:
+	case LLDrawPool::POOL_CONTROL_AV:
 		break; // Do nothing
 
 	case LLDrawPool::POOL_SKY:
@@ -6427,41 +6421,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 		light->setAmbient(LLColor4::black);
 		light->setSpecular(LLColor4::black);
 	}
-	if (gAgentAvatarp &&
-		gAgentAvatarp->mSpecialRenderMode == 3)
-	{
-		LLColor4  light_color = LLColor4::white;
-		light_color.mV[3] = 0.0f;
-
-		LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin());
-		LLVector4 light_pos_gl(light_pos, 1.0f);
-
-		F32 light_radius = 16.f;
-
-			F32 x = 3.f;
-		float linatten = x / (light_radius); // % of brightness at radius
-
-		if (LLPipeline::sRenderDeferred)
-		{
-			/*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
-			light_color.mV[1] = powf(light_color.mV[1], 2.2f);
-			light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
-		}
-
-		mHWLightColors[2] = light_color;
-		LLLightState* light = gGL.getLight(2);
 
-		light->setPosition(light_pos_gl);
-		light->setDiffuse(light_color);
-        light->setDiffuseB(light_color * 0.25f);
-		light->setAmbient(LLColor4::black);
-		light->setSpecular(LLColor4::black);
-		light->setQuadraticAttenuation(0.f);
-		light->setConstantAttenuation(0.f);
-		light->setLinearAttenuation(linatten);
-		light->setSpotExponent(0.f);
-		light->setSpotCutoff(180.f);
-	}
+    // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode),
+    // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20
 
 	// Init GL state
 	if (!LLGLSLShader::sNoFixedFunction)
@@ -7151,7 +7113,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
 		for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
 		{
 			if ((j == LLViewerRegion::PARTITION_VOLUME) || 
-				(j == LLViewerRegion::PARTITION_BRIDGE) || 
+				(j == LLViewerRegion::PARTITION_BRIDGE) ||
+				(j == LLViewerRegion::PARTITION_CONTROL_AV) ||
 				(j == LLViewerRegion::PARTITION_TERRAIN) ||
 				(j == LLViewerRegion::PARTITION_TREE) ||
 				(j == LLViewerRegion::PARTITION_GRASS))  // only check these partitions for now
@@ -7213,7 +7176,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
 		{
 			LLViewerRegion* region = *iter;
 
-			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
+			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);
 			if (part && hasRenderType(part->mDrawableType))
 			{
 				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
@@ -7539,641 +7502,633 @@ void LLPipeline::bindScreenToTexture()
 
 static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
 
-void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
+void LLPipeline::renderFinalize()
 {
-	if (!(gPipeline.canUseVertexShaders() &&
-		sRenderGlow))
-	{
-		return;
-	}
+    LLVertexBuffer::unbind();
+    LLGLState::checkStates();
+    LLGLState::checkTextureChannels();
 
-	LLVertexBuffer::unbind();
-	LLGLState::checkStates();
-	LLGLState::checkTextureChannels();
+    assertInitialized();
 
-	assertInitialized();
+    if (gUseWireframe)
+    {
+        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    }
 
-	if (gUseWireframe)
-	{
-		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-	}
+    LLVector2 tc1(0, 0);
+    LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2);
 
-	LLVector2 tc1(0,0);
-	LLVector2 tc2((F32) mScreen.getWidth()*2,
-				  (F32) mScreen.getHeight()*2);
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+    gGL.color4f(1, 1, 1, 1);
+    LLGLDepthTest depth(GL_FALSE);
+    LLGLDisable blend(GL_BLEND);
+    LLGLDisable cull(GL_CULL_FACE);
 
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
-	gGL.color4f(1,1,1,1);
-	LLGLDepthTest depth(GL_FALSE);
-	LLGLDisable blend(GL_BLEND);
-	LLGLDisable cull(GL_CULL_FACE);
-	
-	enableLightsFullbright();
+    enableLightsFullbright();
 
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+    gGL.pushMatrix();
+    gGL.loadIdentity();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.pushMatrix();
+    gGL.loadIdentity();
 
-	LLGLDisable test(GL_ALPHA_TEST);
+    LLGLDisable test(GL_ALPHA_TEST);
 
-	gGL.setColorMask(true, true);
-	glClearColor(0,0,0,0);
-		
-	{
-		{
-			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
-			mGlow[2].bindTarget();
-			mGlow[2].clear();
-		}
-		
-		gGlowExtractProgram.bind();
-		F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
-		F32 maxAlpha = RenderGlowMaxExtractAlpha;		
-		F32 warmthAmount = RenderGlowWarmthAmount;	
-		LLVector3 lumWeights = RenderGlowLumWeights;
-		LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
-
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
-		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
-		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
-		LLGLEnable blend_on(GL_BLEND);
-		LLGLEnable test(GL_ALPHA_TEST);
-		
-		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-		
-		mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
-		
-		gGL.color4f(1,1,1,1);
-		gPipeline.enableLightsFullbright();
-		gGL.begin(LLRender::TRIANGLE_STRIP);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		
-		gGL.getTexUnit(0)->unbind(mScreen.getUsage());
+    gGL.setColorMask(true, true);
+    glClearColor(0, 0, 0, 0);
 
-		mGlow[2].flush();
-	}
+    if (sRenderGlow)
+    {
+        {
+            LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
+            mGlow[2].bindTarget();
+            mGlow[2].clear();
+        }
 
-	tc1.setVec(0,0);
-	tc2.setVec(2,2);
+        gGlowExtractProgram.bind();
+        F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
+        F32 maxAlpha = RenderGlowMaxExtractAlpha;
+        F32 warmthAmount = RenderGlowWarmthAmount;
+        LLVector3 lumWeights = RenderGlowLumWeights;
+        LLVector3 warmthWeights = RenderGlowWarmthWeights;
+
+        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
+        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+                                      lumWeights.mV[2]);
+        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+                                      warmthWeights.mV[2]);
+        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+        
+        {
+            LLGLEnable blend_on(GL_BLEND);
+            LLGLEnable test(GL_ALPHA_TEST);
 
-	// power of two between 1 and 1024
-	U32 glowResPow = RenderGlowResolutionPow;
-	const U32 glow_res = llmax(1, 
-		llmin(1024, 1 << glowResPow));
+            gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 
-	S32 kernel = RenderGlowIterations*2;
-	F32 delta = RenderGlowWidth / glow_res;
-	// Use half the glow width if we have the res set to less than 9 so that it looks
-	// almost the same in either case.
-	if (glowResPow < 9)
-	{
-		delta *= 0.5f;
-	}
-	F32 strength = RenderGlowStrength;
+            mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
 
-	gGlowProgram.bind();
-	gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+            gGL.color4f(1, 1, 1, 1);
+            gPipeline.enableLightsFullbright();
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+            gGL.vertex2f(-1, -1);
 
-	for (S32 i = 0; i < kernel; i++)
-	{
-		{
-			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
-			mGlow[i%2].bindTarget();
-			mGlow[i%2].clear();
-		}
-			
-		if (i == 0)
-		{
-			gGL.getTexUnit(0)->bind(&mGlow[2]);
-		}
-		else
-		{
-			gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]);
-		}
+            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+            gGL.vertex2f(-1, 3);
 
-		if (i%2 == 0)
-		{
-			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
-		}
-		else
-		{
-			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
-		}
+            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+            gGL.vertex2f(3, -1);
 
-		gGL.begin(LLRender::TRIANGLE_STRIP);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		
-		mGlow[i%2].flush();
-	}
+            gGL.end();
 
-	gGlowProgram.unbind();
+            gGL.getTexUnit(0)->unbind(mScreen.getUsage());
 
-	/*if (LLRenderTarget::sUseFBO)
-	{
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
-		glBindFramebuffer(GL_FRAMEBUFFER, 0);
-	}*/
+            mGlow[2].flush();
 
-	gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-	gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-	gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-	gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+            tc1.setVec(0, 0);
+            tc2.setVec(2, 2); 
+        }
 
-	tc2.setVec((F32) mScreen.getWidth(),
-			(F32) mScreen.getHeight());
+        // power of two between 1 and 1024
+        U32 glowResPow = RenderGlowResolutionPow;
+        const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
 
-	gGL.flush();
-	
-	LLVertexBuffer::unbind();
+        S32 kernel = RenderGlowIterations * 2;
+        F32 delta = RenderGlowWidth / glow_res;
+        // Use half the glow width if we have the res set to less than 9 so that it looks
+        // almost the same in either case.
+        if (glowResPow < 9)
+        {
+            delta *= 0.5f;
+        }
+        F32 strength = RenderGlowStrength;
 
-	if (LLPipeline::sRenderDeferred)
-	{
+        gGlowProgram.bind();
+        gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
 
-		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
-			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
-							RenderDepthOfField;
+        for (S32 i = 0; i < kernel; i++)
+        {
+            {
+                LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
+                mGlow[i % 2].bindTarget();
+                mGlow[i % 2].clear();
+            }
 
+            if (i == 0)
+            {
+                gGL.getTexUnit(0)->bind(&mGlow[2]);
+            }
+            else
+            {
+                gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
+            }
 
-		bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
+            if (i % 2 == 0)
+            {
+                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+            }
+            else
+            {
+                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+            }
 
-		gViewerWindow->setup3DViewport();
-				
-		if (dof_enabled)
-		{
-			LLGLSLShader* shader = &gDeferredPostProgram;
-			LLGLDisable blend(GL_BLEND);
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+            gGL.vertex2f(-1, -1);
 
-			//depth of field focal plane calculations
-			static F32 current_distance = 16.f;
-			static F32 start_distance = 16.f;
-			static F32 transition_time = 1.f;
+            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+            gGL.vertex2f(-1, 3);
 
-			LLVector3 focus_point;
+            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+            gGL.vertex2f(3, -1);
 
-			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
-			if (obj && obj->mDrawable && obj->isSelected())
-			{ //focus on selected media object
-				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
-				if (obj && obj->mDrawable)
-				{
-					LLFace* face = obj->mDrawable->getFace(face_idx);
-					if (face)
-					{
-						focus_point = face->getPositionAgent();
-					}
-				}
-			}
-		
-			if (focus_point.isExactlyZero())
-			{
-				if (LLViewerJoystick::getInstance()->getOverrideCamera())
-				{ //focus on point under cursor
-					focus_point.set(gDebugRaycastIntersection.getF32ptr());
-				}
-				else if (gAgentCamera.cameraMouselook())
-				{ //focus on point under mouselook crosshairs
-					LLVector4a result;
-					result.clear();
+            gGL.end();
 
-					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
-													NULL,
-													&result);
+            mGlow[i % 2].flush();
+        }
 
-					focus_point.set(result.getF32ptr());
-				}
-				else
-				{
-					//focus on alt-zoom target
-					LLViewerRegion* region = gAgent.getRegion();
-					if (region)
-					{
-						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal());
-					}
-				}
-			}
+        gGlowProgram.unbind();
+    }
+    else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+    {
+        mGlow[1].bindTarget();
+        mGlow[1].clear();
+        mGlow[1].flush();
+    }
 
-			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
-			F32 target_distance = 16.f;
-			if (!focus_point.isExactlyZero())
-			{
-				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye);
-			}
+    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
 
-			if (transition_time >= 1.f &&
-				fabsf(current_distance-target_distance)/current_distance > 0.01f)
-			{ //large shift happened, interpolate smoothly to new target distance
-				transition_time = 0.f;
-				start_distance = current_distance;
-			}
-			else if (transition_time < 1.f)
-			{ //currently in a transition, continue interpolating
-				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value();
-				transition_time = llmin(transition_time, 1.f);
+    tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight());
 
-				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
-				current_distance = start_distance + (target_distance-start_distance)*t;
-			}
-			else
-			{ //small or no change, just snap to target distance
-				current_distance = target_distance;
-			}
+    gGL.flush();
 
-			//convert to mm
-			F32 subject_distance = current_distance*1000.f;
-			F32 fnumber = CameraFNumber;
-			F32 default_focal_length = CameraFocalLength;
+    LLVertexBuffer::unbind();
 
-			F32 fov = LLViewerCamera::getInstance()->getView();
-		
-			const F32 default_fov = CameraFieldOfView * F_PI/180.f;
-		
-			//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
-		
-			F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
+    if (LLPipeline::sRenderDeferred)
+    {
 
-			F32 focal_length = dv/(2*tanf(fov/2.f));
-		 
-			//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
-	
-			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
-			// where	 N = fnumber
-			//			 s2 = dot distance
-			//			 s1 = subject distance
-			//			 f = focal length
-			//	
+        bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+                           (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+                           RenderDepthOfField;
 
-			F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
-			blur_constant /= 1000.f; //convert to meters for shader
-			F32 magnification = focal_length/(subject_distance-focal_length);
+        bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
 
-			{ //build diffuse+bloom+CoF
-				mDeferredLight.bindTarget();
-				shader = &gDeferredCoFProgram;
+        gViewerWindow->setup3DViewport();
 
-				bindDeferredShader(*shader);
+        if (dof_enabled)
+        {
+            LLGLSLShader *shader = &gDeferredPostProgram;
+            LLGLDisable blend(GL_BLEND);
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-				if (channel > -1)
-				{
-					mScreen.bindTexture(0, channel);
-				}
+            // depth of field focal plane calculations
+            static F32 current_distance = 16.f;
+            static F32 start_distance = 16.f;
+            static F32 transition_time = 1.f;
 
-				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f);
-				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
-				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle));
-				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+            LLVector3 focus_point;
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1,-1);
-		
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1,3);
-		
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3,-1);
-		
-				gGL.end();
+            LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+            if (obj && obj->mDrawable && obj->isSelected())
+            { // focus on selected media object
+                S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+                if (obj && obj->mDrawable)
+                {
+                    LLFace *face = obj->mDrawable->getFace(face_idx);
+                    if (face)
+                    {
+                        focus_point = face->getPositionAgent();
+                    }
+                }
+            }
 
-				unbindDeferredShader(*shader);
-				mDeferredLight.flush();
-			}
+            if (focus_point.isExactlyZero())
+            {
+                if (LLViewerJoystick::getInstance()->getOverrideCamera())
+                { // focus on point under cursor
+                    focus_point.set(gDebugRaycastIntersection.getF32ptr());
+                }
+                else if (gAgentCamera.cameraMouselook())
+                { // focus on point under mouselook crosshairs
+                    LLVector4a result;
+                    result.clear();
 
-			U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale);
-			U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale);
-			
-			{ //perform DoF sampling at half-res (preserve alpha channel)
-				mScreen.bindTarget();
-				glViewport(0,0, dof_width, dof_height);
-				gGL.setColorMask(true, false);
+                    gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result);
 
-				shader = &gDeferredPostProgram;
-				bindDeferredShader(*shader);
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
-				if (channel > -1)
-				{
-					mDeferredLight.bindTexture(0, channel);
-				}
+                    focus_point.set(result.getF32ptr());
+                }
+                else
+                {
+                    // focus on alt-zoom target
+                    LLViewerRegion *region = gAgent.getRegion();
+                    if (region)
+                    {
+                        focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+                    }
+                }
+            }
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1,-1);
-		
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1,3);
-		
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3,-1);
-		
-				gGL.end();
+            LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+            F32 target_distance = 16.f;
+            if (!focus_point.isExactlyZero())
+            {
+                target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+            }
 
-				unbindDeferredShader(*shader);
-				mScreen.flush();
-				gGL.setColorMask(true, true);
-			}
-	
-			{ //combine result based on alpha
-				if (multisample)
-				{
-					mDeferredLight.bindTarget();
-					glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
-				}
-				else
-				{
-					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-				}
+            if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+            { // large shift happened, interpolate smoothly to new target distance
+                transition_time = 0.f;
+                start_distance = current_distance;
+            }
+            else if (transition_time < 1.f)
+            { // currently in a transition, continue interpolating
+                transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+                transition_time = llmin(transition_time, 1.f);
 
-				shader = &gDeferredDoFCombineProgram;
-				bindDeferredShader(*shader);
-				
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-				if (channel > -1)
-				{
-					mScreen.bindTexture(0, channel);
-				}
+                F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+                current_distance = start_distance + (target_distance - start_distance) * t;
+            }
+            else
+            { // small or no change, just snap to target distance
+                current_distance = target_distance;
+            }
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1);
-				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1);
+            // convert to mm
+            F32 subject_distance = current_distance * 1000.f;
+            F32 fnumber = CameraFNumber;
+            F32 default_focal_length = CameraFocalLength;
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1,-1);
-		
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1,3);
-		
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3,-1);
-		
-				gGL.end();
+            F32 fov = LLViewerCamera::getInstance()->getView();
 
-				unbindDeferredShader(*shader);
+            const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
 
-				if (multisample)
-				{
-					mDeferredLight.flush();
-				}
-			}
-		}
-		else
-		{
-			if (multisample)
-			{
-				mDeferredLight.bindTarget();
-			}
-			LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
-			
-			bindDeferredShader(*shader);
-							
-			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-			if (channel > -1)
-			{
-				mScreen.bindTexture(0, channel);
-			}
+            // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
 
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-			gGL.vertex2f(-1,-1);
-		
-			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-			gGL.vertex2f(-1,3);
-		
-			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-			gGL.vertex2f(3,-1);
-		
-			gGL.end();
+            F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
 
-			unbindDeferredShader(*shader);
+            F32 focal_length = dv / (2 * tanf(fov / 2.f));
 
-			if (multisample)
-			{
-				mDeferredLight.flush();
-			}
-		}
+            // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
 
-		if (multisample)
-		{
-			//bake out texture2D with RGBL for FXAA shader
-			mFXAABuffer.bindTarget();
-			
-			S32 width = mScreen.getWidth();
-			S32 height = mScreen.getHeight();
-			glViewport(0, 0, width, height);
+            // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+            // where	 N = fnumber
+            //			 s2 = dot distance
+            //			 s1 = subject distance
+            //			 f = focal length
+            //
 
-			LLGLSLShader* shader = &gGlowCombineFXAAProgram;
+            F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+            blur_constant /= 1000.f; // convert to meters for shader
+            F32 magnification = focal_length / (subject_distance - focal_length);
 
-			shader->bind();
-			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+            { // build diffuse+bloom+CoF
+                mDeferredLight.bindTarget();
+                shader = &gDeferredCoFProgram;
 
-			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
-			if (channel > -1)
-			{
-				mDeferredLight.bindTexture(0, channel);
-			}
-						
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.vertex2f(-1,-1);
-			gGL.vertex2f(-1,3);
-			gGL.vertex2f(3,-1);
-			gGL.end();
+                bindDeferredShader(*shader);
 
-			gGL.flush();
+                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+                if (channel > -1)
+                {
+                    mScreen.bindTexture(0, channel);
+                }
 
-			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
-			shader->unbind();
-			
-			mFXAABuffer.flush();
+                shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+                shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+                shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+                shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
 
-			shader = &gFXAAProgram;
-			shader->bind();
+                gGL.begin(LLRender::TRIANGLE_STRIP);
+                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+                gGL.vertex2f(-1, -1);
 
-			channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
-			if (channel > -1)
-			{
-				mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
-			}
-			
-			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
-			F32 scale_x = (F32) width/mFXAABuffer.getWidth();
-			F32 scale_y = (F32) height/mFXAABuffer.getHeight();
-			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
-			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y);
-			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y);
-			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y);
-			
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.vertex2f(-1,-1);
-			gGL.vertex2f(-1,3);
-			gGL.vertex2f(3,-1);
-			gGL.end();
+                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+                gGL.vertex2f(-1, 3);
 
-			gGL.flush();
-			shader->unbind();
-		}
-	}
-	else
-	{
-		U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
-		LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
-		buff->allocateBuffer(3,0,TRUE);
+                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+                gGL.vertex2f(3, -1);
 
-		LLStrider<LLVector3> v;
-		LLStrider<LLVector2> uv1;
-		LLStrider<LLVector2> uv2;
+                gGL.end();
 
-		buff->getVertexStrider(v);
-		buff->getTexCoord0Strider(uv1);
-		buff->getTexCoord1Strider(uv2);
-		
-		uv1[0] = LLVector2(0, 0);
-		uv1[1] = LLVector2(0, 2);
-		uv1[2] = LLVector2(2, 0);
-		
-		uv2[0] = LLVector2(0, 0);
-		uv2[1] = LLVector2(0, tc2.mV[1]*2.f);
-		uv2[2] = LLVector2(tc2.mV[0]*2.f, 0);
-		
-		v[0] = LLVector3(-1,-1,0);
-		v[1] = LLVector3(-1,3,0);
-		v[2] = LLVector3(3,-1,0);
-				
-		buff->flush();
+                unbindDeferredShader(*shader);
+                mDeferredLight.flush();
+            }
 
-		LLGLDisable blend(GL_BLEND);
+            U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale);
+            U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale);
 
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gGlowCombineProgram.bind();
-		}
-		else
-		{
-			//tex unit 0
-			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
-			//tex unit 1
-			gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
-		}
-		
-		gGL.getTexUnit(0)->bind(&mGlow[1]);
-		gGL.getTexUnit(1)->bind(&mScreen);
-		
-		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-		
-		buff->setBuffer(mask);
-		buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
-		
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gGlowCombineProgram.unbind();
-		}
-		else
-		{
-			gGL.getTexUnit(1)->disable();
-			gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+            { // perform DoF sampling at half-res (preserve alpha channel)
+                mScreen.bindTarget();
+                glViewport(0, 0, dof_width, dof_height);
+                gGL.setColorMask(true, false);
 
-			gGL.getTexUnit(0)->activate();
-			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-		}
-		
-	}
+                shader = &gDeferredPostProgram;
+                bindDeferredShader(*shader);
+                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+                if (channel > -1)
+                {
+                    mDeferredLight.bindTexture(0, channel);
+                }
 
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
 
-	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSplatTextureRectProgram.bind();
-		}
+                gGL.begin(LLRender::TRIANGLE_STRIP);
+                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+                gGL.vertex2f(-1, -1);
 
-		gGL.setColorMask(true, false);
+                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+                gGL.vertex2f(-1, 3);
 
-		LLVector2 tc1(0,0);
-		LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,
-				  (F32) gViewerWindow->getWorldViewHeightRaw()*2);
+                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+                gGL.vertex2f(3, -1);
 
-		LLGLEnable blend(GL_BLEND);
-		gGL.color4f(1,1,1,0.75f);
+                gGL.end();
 
-		gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+                unbindDeferredShader(*shader);
+                mScreen.flush();
+                gGL.setColorMask(true, true);
+            }
 
-		gGL.begin(LLRender::TRIANGLES);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		gGL.flush();
+            { // combine result based on alpha
+                if (multisample)
+                {
+                    mDeferredLight.bindTarget();
+                    glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+                }
+                else
+                {
+                    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+                    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+                    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+                    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+                    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+                }
 
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSplatTextureRectProgram.unbind();
-		}
-	}
+                shader = &gDeferredDoFCombineProgram;
+                bindDeferredShader(*shader);
 
-	
-	if (LLRenderTarget::sUseFBO)
-	{ //copy depth buffer from mScreen to framebuffer
-		LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 
-			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-	}
-	
+                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+                if (channel > -1)
+                {
+                    mScreen.bindTexture(0, channel);
+                }
 
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.popMatrix();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.popMatrix();
+                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+                shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1);
+                shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1);
 
-	LLVertexBuffer::unbind();
+                gGL.begin(LLRender::TRIANGLE_STRIP);
+                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+                gGL.vertex2f(-1, -1);
 
-	LLGLState::checkStates();
-	LLGLState::checkTextureChannels();
+                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+                gGL.vertex2f(-1, 3);
+
+                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+                gGL.vertex2f(3, -1);
+
+                gGL.end();
+
+                unbindDeferredShader(*shader);
+
+                if (multisample)
+                {
+                    mDeferredLight.flush();
+                }
+            }
+        }
+        else
+        {
+            if (multisample)
+            {
+                mDeferredLight.bindTarget();
+            }
+            LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
+
+            bindDeferredShader(*shader);
+
+            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+            if (channel > -1)
+            {
+                mScreen.bindTexture(0, channel);
+            }
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+            gGL.vertex2f(-1, -1);
+
+            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+            gGL.vertex2f(-1, 3);
+
+            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+            gGL.vertex2f(3, -1);
+
+            gGL.end();
+
+            unbindDeferredShader(*shader);
+
+            if (multisample)
+            {
+                mDeferredLight.flush();
+            }
+        }
+
+        if (multisample)
+        {
+            // bake out texture2D with RGBL for FXAA shader
+            mFXAABuffer.bindTarget();
+
+            S32 width = mScreen.getWidth();
+            S32 height = mScreen.getHeight();
+            glViewport(0, 0, width, height);
+
+            LLGLSLShader *shader = &gGlowCombineFXAAProgram;
+
+            shader->bind();
+            shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+
+            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+            if (channel > -1)
+            {
+                mDeferredLight.bindTexture(0, channel);
+            }
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.vertex2f(-1, -1);
+            gGL.vertex2f(-1, 3);
+            gGL.vertex2f(3, -1);
+            gGL.end();
+
+            gGL.flush();
 
+            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+            shader->unbind();
+
+            mFXAABuffer.flush();
+
+            shader = &gFXAAProgram;
+            shader->bind();
+
+            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
+            if (channel > -1)
+            {
+                mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+            }
+
+            gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+            gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+            gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+            gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+            glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
+            F32 scale_x = (F32) width / mFXAABuffer.getWidth();
+            F32 scale_y = (F32) height / mFXAABuffer.getHeight();
+            shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
+            shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
+            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
+                              0.5f / width * scale_x, 0.5f / height * scale_y);
+            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
+                              2.f / width * scale_x, 2.f / height * scale_y);
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.vertex2f(-1, -1);
+            gGL.vertex2f(-1, 3);
+            gGL.vertex2f(3, -1);
+            gGL.end();
+
+            gGL.flush();
+            shader->unbind();
+        }
+    }
+    else // not deferred
+    {
+        U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
+        LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
+        buff->allocateBuffer(3, 0, TRUE);
+
+        LLStrider<LLVector3> v;
+        LLStrider<LLVector2> uv1;
+        LLStrider<LLVector2> uv2;
+
+        buff->getVertexStrider(v);
+        buff->getTexCoord0Strider(uv1);
+        buff->getTexCoord1Strider(uv2);
+
+        uv1[0] = LLVector2(0, 0);
+        uv1[1] = LLVector2(0, 2);
+        uv1[2] = LLVector2(2, 0);
+
+        uv2[0] = LLVector2(0, 0);
+        uv2[1] = LLVector2(0, tc2.mV[1] * 2.f);
+        uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0);
+
+        v[0] = LLVector3(-1, -1, 0);
+        v[1] = LLVector3(-1, 3, 0);
+        v[2] = LLVector3(3, -1, 0);
+
+        buff->flush();
+
+        LLGLDisable blend(GL_BLEND);
+
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gGlowCombineProgram.bind();
+        }
+        else
+        {
+            // tex unit 0
+            gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
+            // tex unit 1
+            gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR,
+                                                    LLTexUnit::TBS_PREV_COLOR);
+        }
+
+        gGL.getTexUnit(0)->bind(&mGlow[1]);
+        gGL.getTexUnit(1)->bind(&mScreen);
+
+        LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+        buff->setBuffer(mask);
+        buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
+
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gGlowCombineProgram.unbind();
+        }
+        else
+        {
+            gGL.getTexUnit(1)->disable();
+            gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+            gGL.getTexUnit(0)->activate();
+            gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+        }
+    }
+
+    gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+    if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+    {
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gSplatTextureRectProgram.bind();
+        }
+
+        gGL.setColorMask(true, false);
+
+        LLVector2 tc1(0, 0);
+        LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2,
+                      (F32) gViewerWindow->getWorldViewHeightRaw() * 2);
+
+        LLGLEnable blend(GL_BLEND);
+        gGL.color4f(1, 1, 1, 0.75f);
+
+        gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+
+        gGL.begin(LLRender::TRIANGLES);
+        gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+        gGL.vertex2f(-1, -1);
+
+        gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+        gGL.vertex2f(-1, 3);
+
+        gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+        gGL.vertex2f(3, -1);
+
+        gGL.end();
+        gGL.flush();
+
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gSplatTextureRectProgram.unbind();
+        }
+    }
+
+    if (LLRenderTarget::sUseFBO)
+    { // copy depth buffer from mScreen to framebuffer
+        LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0,
+                                                  mScreen.getWidth(), mScreen.getHeight(),
+                                                  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+    }
+
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+    gGL.popMatrix();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.popMatrix();
+
+    LLVertexBuffer::unbind();
+
+    LLGLState::checkStates();
+    LLGLState::checkTextureChannels();
 }
 
 static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred");
@@ -8453,292 +8408,301 @@ static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");
 static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");
 static LLTrace::BlockTimerStatHandle FTM_POST("Post");
 
-
-void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
+void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
 {
-	if (!sCull)
-	{
-		return;
-	}
+    if (!sCull)
+    {
+        return;
+    }
 
-    LLRenderTarget* deferred_target       = &mDeferredScreen;
-    LLRenderTarget* deferred_depth_target = &mDeferredDepth;
-    LLRenderTarget* deferred_light_target = &mDeferredLight;
+    LLRenderTarget *deferred_target       = &mDeferredScreen;
+    LLRenderTarget *deferred_depth_target = &mDeferredDepth;
+    LLRenderTarget *deferred_light_target = &mDeferredLight;
 
-	{
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
-		LLViewerCamera* camera = LLViewerCamera::getInstance();
-		{
-			LLGLDepthTest depth(GL_TRUE);
-            deferred_depth_target->copyContents(*deferred_target, 0, 0, deferred_target->getWidth(), deferred_target->getHeight(),
-                            0, 0, deferred_depth_target->getWidth(), deferred_depth_target->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);  
-		}
+    {
+        LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
+        LLViewerCamera *camera = LLViewerCamera::getInstance();
+        {
+            LLGLDepthTest depth(GL_TRUE);
+            deferred_depth_target->copyContents(*deferred_target,
+                                                0,
+                                                0,
+                                                deferred_target->getWidth(),
+                                                deferred_target->getHeight(),
+                                                0,
+                                                0,
+                                                deferred_depth_target->getWidth(),
+                                                deferred_depth_target->getHeight(),
+                                                GL_DEPTH_BUFFER_BIT,
+                                                GL_NEAREST);
+        }
 
-		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+        LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 
-		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
-		{
-			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
-		}
+        if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+        {
+            gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+        }
 
-		//ati doesn't seem to love actually using the stencil buffer on FBO's
-		LLGLDisable stencil(GL_STENCIL_TEST);
-		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
-		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+        // ati doesn't seem to love actually using the stencil buffer on FBO's
+        LLGLDisable stencil(GL_STENCIL_TEST);
+        // glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
+        // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 
-		gGL.setColorMask(true, true);
-		
-		//draw a cube around every light
-		LLVertexBuffer::unbind();
+        gGL.setColorMask(true, true);
 
-		LLGLEnable cull(GL_CULL_FACE);
-		LLGLEnable blend(GL_BLEND);
+        // draw a cube around every light
+        LLVertexBuffer::unbind();
+
+        LLGLEnable cull(GL_CULL_FACE);
+        LLGLEnable blend(GL_BLEND);
 
         glh::matrix4f mat = copy_matrix(gGLModelView);
 
-		LLStrider<LLVector3> vert; 
-		mDeferredVB->getVertexStrider(vert);
-		
-		vert[0].set(-1,1,0);
-		vert[1].set(-1,-3,0);
-		vert[2].set(3,1,0);
-		
-        setupHWLights(NULL); //to set mSun/MoonDir;
+        LLStrider<LLVector3> vert;
+        mDeferredVB->getVertexStrider(vert);
+
+        vert[0].set(-1, 1, 0);
+        vert[1].set(-1, -3, 0);
+        vert[2].set(3, 1, 0);
+
+        setupHWLights(NULL);  // to set mSun/MoonDir;
 
         glh::vec4f tc(mSunDir.mV);
-			mat.mult_matrix_vec(tc);
-			mTransformedSunDir.set(tc.v);
+        mat.mult_matrix_vec(tc);
+        mTransformedSunDir.set(tc.v);
 
         glh::vec4f tc_moon(mMoonDir.mV);
         mat.mult_matrix_vec(tc_moon);
         mTransformedMoonDir.set(tc_moon.v);
 
-		gGL.pushMatrix();
-		gGL.loadIdentity();
-		gGL.matrixMode(LLRender::MM_PROJECTION);
-		gGL.pushMatrix();
-		gGL.loadIdentity();
+        gGL.pushMatrix();
+        gGL.loadIdentity();
+        gGL.matrixMode(LLRender::MM_PROJECTION);
+        gGL.pushMatrix();
+        gGL.loadIdentity();
 
-		if (RenderDeferredSSAO || RenderShadowDetail > 0)
-		{
+        if (RenderDeferredSSAO || RenderShadowDetail > 0)
+        {
             deferred_light_target->bindTarget();
-			{ //paint shadow/SSAO light map (direct lighting lightmap)
-				LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
+            {  // paint shadow/SSAO light map (direct lighting lightmap)
+                LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
                 bindDeferredShader(gDeferredSunProgram, deferred_light_target);
-				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-				glClearColor(1,1,1,1);
+                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+                glClearColor(1, 1, 1, 1);
                 deferred_light_target->clear(GL_COLOR_BUFFER_BIT);
-				glClearColor(0,0,0,0);
+                glClearColor(0, 0, 0, 0);
 
                 glh::matrix4f inv_trans = get_current_modelview().inverse().transpose();
 
-				const U32 slice = 32;
-				F32 offset[slice*3];
-				for (U32 i = 0; i < 4; i++)
-				{
-					for (U32 j = 0; j < 8; j++)
-					{
-						glh::vec3f v;
-						v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
-						v.normalize();
-						inv_trans.mult_matrix_vec(v);
-						v.normalize();
-						offset[(i*8+j)*3+0] = v.v[0];
-						offset[(i*8+j)*3+1] = v.v[2];
-						offset[(i*8+j)*3+2] = v.v[1];
-					}
-				}
+                const U32 slice = 32;
+                F32       offset[slice * 3];
+                for (U32 i = 0; i < 4; i++)
+                {
+                    for (U32 j = 0; j < 8; j++)
+                    {
+                        glh::vec3f v;
+                        v.set_value(sinf(6.284f / 8 * j), cosf(6.284f / 8 * j), -(F32) i);
+                        v.normalize();
+                        inv_trans.mult_matrix_vec(v);
+                        v.normalize();
+                        offset[(i * 8 + j) * 3 + 0] = v.v[0];
+                        offset[(i * 8 + j) * 3 + 1] = v.v[2];
+                        offset[(i * 8 + j) * 3 + 2] = v.v[1];
+                    }
+                }
 
-				gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
-                gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_light_target->getWidth(), deferred_light_target->getHeight());
-				
-				{
-					LLGLDisable blend(GL_BLEND);
-					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
-					stop_glerror();
-					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-					stop_glerror();
-				}
-				
-				unbindDeferredShader(gDeferredSunProgram);
-			}
+                gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
+                gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES,
+                                              deferred_light_target->getWidth(),
+                                              deferred_light_target->getHeight());
+
+                {
+                    LLGLDisable   blend(GL_BLEND);
+                    LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+                    stop_glerror();
+                    mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                    stop_glerror();
+                }
+
+                unbindDeferredShader(gDeferredSunProgram);
+            }
             deferred_light_target->flush();
-		}
-		
-		if (RenderDeferredSSAO)
-		{ //soften direct lighting lightmap
-			LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
-			//blur lightmap
+        }
+
+        if (RenderDeferredSSAO)
+        {  // soften direct lighting lightmap
+            LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
+            // blur lightmap
             screen_target->bindTarget();
-			glClearColor(1,1,1,1);
+            glClearColor(1, 1, 1, 1);
             screen_target->clear(GL_COLOR_BUFFER_BIT);
-			glClearColor(0,0,0,0);
-			
-			bindDeferredShader(gDeferredBlurLightProgram);
-			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-			LLVector3 go = RenderShadowGaussian;
-			const U32 kern_length = 4;
-			F32 blur_size = RenderShadowBlurSize;
-			F32 dist_factor = RenderShadowBlurDistFactor;
+            glClearColor(0, 0, 0, 0);
 
-			// sample symmetrically with the middle sample falling exactly on 0.0
-			F32 x = 0.f;
+            bindDeferredShader(gDeferredBlurLightProgram);
+            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+            LLVector3 go          = RenderShadowGaussian;
+            const U32 kern_length = 4;
+            F32       blur_size   = RenderShadowBlurSize;
+            F32       dist_factor = RenderShadowBlurDistFactor;
 
-			LLVector3 gauss[32]; // xweight, yweight, offset
+            // sample symmetrically with the middle sample falling exactly on 0.0
+            F32 x = 0.f;
 
-			for (U32 i = 0; i < kern_length; i++)
-			{
-				gauss[i].mV[0] = llgaussian(x, go.mV[0]);
-				gauss[i].mV[1] = llgaussian(x, go.mV[1]);
-				gauss[i].mV[2] = x;
-				x += 1.f;
-			}
+            LLVector3 gauss[32];  // xweight, yweight, offset
+
+            for (U32 i = 0; i < kern_length; i++)
+            {
+                gauss[i].mV[0] = llgaussian(x, go.mV[0]);
+                gauss[i].mV[1] = llgaussian(x, go.mV[1]);
+                gauss[i].mV[2] = x;
+                x += 1.f;
+            }
+
+            gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+            gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+            gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+            gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f));
+
+            {
+                LLGLDisable   blend(GL_BLEND);
+                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+                stop_glerror();
+                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                stop_glerror();
+            }
 
-			gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
-			gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
-			gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
-			gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f));
-		
-			{
-				LLGLDisable blend(GL_BLEND);
-				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
-				stop_glerror();
-				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-				stop_glerror();
-			}
-			
             screen_target->flush();
-			unbindDeferredShader(gDeferredBlurLightProgram);
+            unbindDeferredShader(gDeferredBlurLightProgram);
 
             bindDeferredShader(gDeferredBlurLightProgram, screen_target);
 
-			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
             deferred_light_target->bindTarget();
 
-			gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
+            gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
 
-			{
-				LLGLDisable blend(GL_BLEND);
-				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
-				stop_glerror();
-				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-				stop_glerror();
-			}
+            {
+                LLGLDisable   blend(GL_BLEND);
+                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+                stop_glerror();
+                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                stop_glerror();
+            }
             deferred_light_target->flush();
-			unbindDeferredShader(gDeferredBlurLightProgram);
-		}
+            unbindDeferredShader(gDeferredBlurLightProgram);
+        }
 
-		stop_glerror();
-		gGL.popMatrix();
-		stop_glerror();
-		gGL.matrixMode(LLRender::MM_MODELVIEW);
-		stop_glerror();
-		gGL.popMatrix();
-		stop_glerror();
+        stop_glerror();
+        gGL.popMatrix();
+        stop_glerror();
+        gGL.matrixMode(LLRender::MM_MODELVIEW);
+        stop_glerror();
+        gGL.popMatrix();
+        stop_glerror();
 
         screen_target->bindTarget();
-		// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
-		glClearColor(0,0,0,0);
+        // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+        glClearColor(0, 0, 0, 0);
         screen_target->clear(GL_COLOR_BUFFER_BIT);
-		
-		if (RenderDeferredAtmospheric)
-		{ //apply sunlight contribution 
-            LLGLSLShader& soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
 
-			LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
-            bindDeferredShader(soften_shader);  
+        if (RenderDeferredAtmospheric)
+        {  // apply sunlight contribution
+            LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
 
-            LLEnvironment& environment = LLEnvironment::instance();
+            LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
+            bindDeferredShader(soften_shader);
+
+            LLEnvironment &environment = LLEnvironment::instance();
             soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
             soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
 
-			{
-				LLGLDepthTest depth(GL_FALSE);
-				LLGLDisable blend(GL_BLEND);
-				LLGLDisable test(GL_ALPHA_TEST);
+            {
+                LLGLDepthTest depth(GL_FALSE);
+                LLGLDisable   blend(GL_BLEND);
+                LLGLDisable   test(GL_ALPHA_TEST);
 
-				//full screen blit
-				gGL.pushMatrix();
-				gGL.loadIdentity();
-				gGL.matrixMode(LLRender::MM_PROJECTION);
-				gGL.pushMatrix();
-				gGL.loadIdentity();
+                // full screen blit
+                gGL.pushMatrix();
+                gGL.loadIdentity();
+                gGL.matrixMode(LLRender::MM_PROJECTION);
+                gGL.pushMatrix();
+                gGL.loadIdentity();
 
-				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-				
-				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
-				gGL.popMatrix();
-				gGL.matrixMode(LLRender::MM_MODELVIEW);
-				gGL.popMatrix();
-			}
+                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-			unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
-		}
+                gGL.popMatrix();
+                gGL.matrixMode(LLRender::MM_MODELVIEW);
+                gGL.popMatrix();
+            }
 
-		{ //render non-deferred geometry (fullbright, alpha, etc)
-			LLGLDisable blend(GL_BLEND);
-			LLGLDisable stencil(GL_STENCIL_TEST);
-			gGL.setSceneBlendType(LLRender::BT_ALPHA);
+            unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
+        }
 
-			gPipeline.pushRenderTypeMask();
-			
-			gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
-										LLPipeline::RENDER_TYPE_CLOUDS,
-										LLPipeline::RENDER_TYPE_WL_SKY,
-										LLPipeline::END_RENDER_TYPES);
-								
-			
-			renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
-			gPipeline.popRenderTypeMask();
-		}
+        {  // render non-deferred geometry (fullbright, alpha, etc)
+            LLGLDisable blend(GL_BLEND);
+            LLGLDisable stencil(GL_STENCIL_TEST);
+            gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
-		bool render_local = RenderLocalLights;
-				
-		if (render_local)
-		{
-			gGL.setSceneBlendType(LLRender::BT_ADD);
-			std::list<LLVector4> fullscreen_lights;
-			LLDrawable::drawable_list_t spot_lights;
-			LLDrawable::drawable_list_t fullscreen_spot_lights;
+            gPipeline.pushRenderTypeMask();
 
-			for (U32 i = 0; i < 2; i++)
-			{
-				mTargetShadowSpotLight[i] = NULL;
-			}
+            gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+                                        LLPipeline::RENDER_TYPE_CLOUDS,
+                                        LLPipeline::RENDER_TYPE_WL_SKY,
+                                        LLPipeline::END_RENDER_TYPES);
 
-			std::list<LLVector4> light_colors;
+            renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
+            gPipeline.popRenderTypeMask();
+        }
 
-			LLVertexBuffer::unbind();
+        bool render_local = RenderLocalLights;
 
-			{
-				bindDeferredShader(gDeferredLightProgram);
-				
-				if (mCubeVB.isNull())
-				{
-					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
-				}
+        if (render_local)
+        {
+            gGL.setSceneBlendType(LLRender::BT_ADD);
+            std::list<LLVector4>        fullscreen_lights;
+            LLDrawable::drawable_list_t spot_lights;
+            LLDrawable::drawable_list_t fullscreen_spot_lights;
 
-				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-				
-				LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
-				{
-					LLDrawable* drawablep = *iter;
-					
-					LLVOVolume* volume = drawablep->getVOVolume();
-					if (!volume)
-					{
-						continue;
-					}
+            for (U32 i = 0; i < 2; i++)
+            {
+                mTargetShadowSpotLight[i] = NULL;
+            }
 
-					if (volume->isAttachment())
-					{
-						if (!sRenderAttachedLights)
-						{
-							continue;
-						}
-					}
+            std::list<LLVector4> light_colors;
+
+            LLVertexBuffer::unbind();
+
+            {
+                bindDeferredShader(gDeferredLightProgram);
+
+                if (mCubeVB.isNull())
+                {
+                    mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+                }
+
+                mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+                LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+                for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
+                {
+                    LLDrawable *drawablep = *iter;
+
+                    LLVOVolume *volume = drawablep->getVOVolume();
+                    if (!volume)
+                    {
+                        continue;
+                    }
+
+                    if (volume->isAttachment())
+                    {
+                        if (!sRenderAttachedLights)
+                        {
+                            continue;
+                        }
+                    }
 
                     const LLViewerObject *vobj = drawablep->getVObj();
                     if (vobj)
@@ -8756,325 +8720,324 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
                         continue;
                     }
 
-					LLVector4a center;
-					center.load3(position.mV);
-					const F32* c = center.getF32ptr();
-					F32 s = volume->getLightRadius()*1.5f;
+                    LLVector4a center;
+                    center.load3(position.mV);
+                    const F32 *c = center.getF32ptr();
+                    F32        s = volume->getLightRadius() * 1.5f;
 
-                    //send light color to shader in linear space
+                    // send light color to shader in linear space
                     LLColor3 col = volume->getLightLinearColor();
-					
-					if (col.magVecSquared() < 0.001f)
-					{
-						continue;
-					}
 
-					if (s <= 0.001f)
-					{
-						continue;
-					}
+                    if (col.magVecSquared() < 0.001f)
+                    {
+                        continue;
+                    }
 
-					LLVector4a sa;
-					sa.splat(s);
-					if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
-					{
-						continue;
-					}
+                    if (s <= 0.001f)
+                    {
+                        continue;
+                    }
 
-					sVisibleLightCount++;
-										
-					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
-						camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
-						camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
-						camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
-						camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
-						camera->getOrigin().mV[2] < c[2] - s - 0.2f)
-					{ //draw box if camera is outside box
-						if (render_local)
-						{
-							if (volume->isLightSpotlight())
-							{
-								drawablep->getVOVolume()->updateSpotLightPriority();
-								spot_lights.push_back(drawablep);
-								continue;
-							}
-							
-							LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
-							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
-							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
-							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+                    LLVector4a sa;
+                    sa.splat(s);
+                    if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
+                    {
+                        continue;
+                    }
+
+                    sVisibleLightCount++;
+
+                    if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
+                        camera->getOrigin().mV[1] > c[1] + s + 0.2f || camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
+                        camera->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] < c[2] - s - 0.2f)
+                    {  // draw box if camera is outside box
+                        if (render_local)
+                        {
+                            if (volume->isLightSpotlight())
+                            {
+                                drawablep->getVOVolume()->updateSpotLightPriority();
+                                spot_lights.push_back(drawablep);
+                                continue;
+                            }
+
+                            LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
+                            gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+                            gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+                            gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
                             gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
-							gGL.syncMatrices();
-							
-							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
-							stop_glerror();
-						}
-					}
-					else
-					{	
-						if (volume->isLightSpotlight())
-						{
-							drawablep->getVOVolume()->updateSpotLightPriority();
-							fullscreen_spot_lights.push_back(drawablep);
-							continue;
-						}
+                            gGL.syncMatrices();
 
-						glh::vec3f tc(c);
-						mat.mult_matrix_vec(tc);
-					
-						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
+                            mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+                            stop_glerror();
+                        }
+                    }
+                    else
+                    {
+                        if (volume->isLightSpotlight())
+                        {
+                            drawablep->getVOVolume()->updateSpotLightPriority();
+                            fullscreen_spot_lights.push_back(drawablep);
+                            continue;
+                        }
+
+                        glh::vec3f tc(c);
+                        mat.mult_matrix_vec(tc);
+
+                        fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
                         light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)));
-					}
-				}
-				unbindDeferredShader(gDeferredLightProgram);
-			}
+                    }
+                }
 
-			if (!spot_lights.empty())
-			{
-				LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-				bindDeferredShader(gDeferredSpotLightProgram);
+                // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode),
+                // prev site of appended deferred character light, removed by SL-13522 09/20
 
-				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+                unbindDeferredShader(gDeferredLightProgram);
+            }
 
-				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+            if (!spot_lights.empty())
+            {
+                LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+                bindDeferredShader(gDeferredSpotLightProgram);
 
-				for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
-				{
-					LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
-					LLDrawable* drawablep = *iter;
+                mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
-					LLVOVolume* volume = drawablep->getVOVolume();
+                gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 
-					LLVector4a center;
-					center.load3(drawablep->getPositionAgent().mV);
-					const F32* c = center.getF32ptr();
-					F32 s = volume->getLightRadius()*1.5f;
+                for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
+                {
+                    LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
+                    LLDrawable *drawablep = *iter;
 
-					sVisibleLightCount++;
+                    LLVOVolume *volume = drawablep->getVOVolume();
 
-					setupSpotLight(gDeferredSpotLightProgram, drawablep);
-					
-                    //send light color to shader in linear space
+                    LLVector4a center;
+                    center.load3(drawablep->getPositionAgent().mV);
+                    const F32 *c = center.getF32ptr();
+                    F32        s = volume->getLightRadius() * 1.5f;
+
+                    sVisibleLightCount++;
+
+                    setupSpotLight(gDeferredSpotLightProgram, drawablep);
+
+                    // send light color to shader in linear space
                     LLColor3 col = volume->getLightLinearColor();
-					
-					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
-					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
-					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+
+                    gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+                    gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+                    gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
                     gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
-					gGL.syncMatrices();
-										
-					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
-				}
-				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
-				unbindDeferredShader(gDeferredSpotLightProgram);
-			}
+                    gGL.syncMatrices();
 
-			//reset mDeferredVB to fullscreen triangle
-			mDeferredVB->getVertexStrider(vert);
-			vert[0].set(-1,1,0);
-			vert[1].set(-1,-3,0);
-			vert[2].set(3,1,0);
+                    mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+                }
+                gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+                unbindDeferredShader(gDeferredSpotLightProgram);
+            }
 
-			{
-				LLGLDepthTest depth(GL_FALSE);
+            // reset mDeferredVB to fullscreen triangle
+            mDeferredVB->getVertexStrider(vert);
+            vert[0].set(-1, 1, 0);
+            vert[1].set(-1, -3, 0);
+            vert[2].set(3, 1, 0);
 
-				//full screen blit
-				gGL.pushMatrix();
-				gGL.loadIdentity();
-				gGL.matrixMode(LLRender::MM_PROJECTION);
-				gGL.pushMatrix();
-				gGL.loadIdentity();
+            {
+                LLGLDepthTest depth(GL_FALSE);
 
-				U32 count = 0;
+                // full screen blit
+                gGL.pushMatrix();
+                gGL.loadIdentity();
+                gGL.matrixMode(LLRender::MM_PROJECTION);
+                gGL.pushMatrix();
+                gGL.loadIdentity();
 
-				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
-				LLVector4 light[max_count];
-				LLVector4 col[max_count];
+                U32 count = 0;
 
-				F32 far_z = 0.f;
+                const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
+                LLVector4 light[max_count];
+                LLVector4 col[max_count];
 
-				while (!fullscreen_lights.empty())
-				{
-					LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
-					light[count] = fullscreen_lights.front();
-					fullscreen_lights.pop_front();
-					col[count] = light_colors.front();
-					light_colors.pop_front();
-
-					far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
-					count++;
-					if (count == max_count || fullscreen_lights.empty())
-					{
-						U32 idx = count-1;
-						bindDeferredShader(gDeferredMultiLightProgram[idx]);
-						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
-						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
-						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
-						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
-						far_z = 0.f;
-						count = 0; 
-      mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-						unbindDeferredShader(gDeferredMultiLightProgram[idx]);
-					}
-				}
-				
-				bindDeferredShader(gDeferredMultiSpotLightProgram);
+                F32 far_z = 0.f;
 
-				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+                while (!fullscreen_lights.empty())
+                {
+                    LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
+                    light[count] = fullscreen_lights.front();
+                    fullscreen_lights.pop_front();
+                    col[count] = light_colors.front();
+                    light_colors.pop_front();
+
+                    far_z = llmin(light[count].mV[2] - light[count].mV[3], far_z);
+                    count++;
+                    if (count == max_count || fullscreen_lights.empty())
+                    {
+                        U32 idx = count - 1;
+                        bindDeferredShader(gDeferredMultiLightProgram[idx]);
+                        gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light);
+                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col);
+                        gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+                        far_z = 0.f;
+                        count = 0;
+                        mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+                        mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                        unbindDeferredShader(gDeferredMultiLightProgram[idx]);
+                    }
+                }
 
-				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+                bindDeferredShader(gDeferredMultiSpotLightProgram);
 
-				for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
-				{
-					LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
-					LLDrawable* drawablep = *iter;
-					
-					LLVOVolume* volume = drawablep->getVOVolume();
+                gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
-					LLVector3 center = drawablep->getPositionAgent();
-					F32* c = center.mV;
-                    F32 light_size_final = volume->getLightRadius()*1.5f;
-                    F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
+                for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
+                {
+                    LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
+                    LLDrawable *drawablep           = *iter;
+                    LLVOVolume *volume              = drawablep->getVOVolume();
+                    LLVector3   center              = drawablep->getPositionAgent();
+                    F32 *       c                   = center.mV;
+                    F32         light_size_final    = volume->getLightRadius() * 1.5f;
+                    F32         light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
 
-					sVisibleLightCount++;
+                    sVisibleLightCount++;
 
-					glh::vec3f tc(c);
-					mat.mult_matrix_vec(tc);
-					
-					setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+                    glh::vec3f tc(c);
+                    mat.mult_matrix_vec(tc);
 
-                    //send light color to shader in linear space
+                    setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+
+                    // send light color to shader in linear space
                     LLColor3 col = volume->getLightLinearColor();
-					
-					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+
+                    gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
                     gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final);
-					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+                    gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
                     gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final);
-					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-				}
+                    mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                }
 
-				gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
-				unbindDeferredShader(gDeferredMultiSpotLightProgram);
+                gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+                unbindDeferredShader(gDeferredMultiSpotLightProgram);
 
-				gGL.popMatrix();
-				gGL.matrixMode(LLRender::MM_MODELVIEW);
-				gGL.popMatrix();
-			}
-		}
+                gGL.popMatrix();
+                gGL.matrixMode(LLRender::MM_MODELVIEW);
+                gGL.popMatrix();
+            }
+        }
 
-		gGL.setColorMask(true, true);
-	}
+        gGL.setColorMask(true, true);
+    }
 
     screen_target->flush();
 
-	//gamma correct lighting
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
+    // gamma correct lighting
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+    gGL.pushMatrix();
+    gGL.loadIdentity();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.pushMatrix();
+    gGL.loadIdentity();
 
-	{
-		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+    {
+        LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
-		LLVector2 tc1(0,0);
-        LLVector2 tc2((F32) screen_target->getWidth()*2,
-                  (F32) screen_target->getHeight()*2);
+        LLVector2 tc1(0, 0);
+        LLVector2 tc2((F32) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2);
 
         screen_target->bindTarget();
-		// Apply gamma correction to the frame here.
-		gDeferredPostGammaCorrectProgram.bind();
-		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-		S32 channel = 0;
-        channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
-		if (channel > -1)
-		{
+        // Apply gamma correction to the frame here.
+        gDeferredPostGammaCorrectProgram.bind();
+        // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+        S32 channel = 0;
+        channel     = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
+        if (channel > -1)
+        {
             screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
-		}
-		
+        }
+
         gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
-		
-		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
 
-		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
-		
-		gGL.begin(LLRender::TRIANGLE_STRIP);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		
+        F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+        gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+
+        gGL.begin(LLRender::TRIANGLE_STRIP);
+        gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+        gGL.vertex2f(-1, -1);
+
+        gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+        gGL.vertex2f(-1, 3);
+
+        gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+        gGL.vertex2f(3, -1);
+
+        gGL.end();
+
         gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
-		gDeferredPostGammaCorrectProgram.unbind();
+        gDeferredPostGammaCorrectProgram.unbind();
         screen_target->flush();
-	}
+    }
 
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.popMatrix();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.popMatrix();	
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+    gGL.popMatrix();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.popMatrix();
 
     screen_target->bindTarget();
 
-	{ //render non-deferred geometry (alpha, fullbright, glow)
-		LLGLDisable blend(GL_BLEND);
-		LLGLDisable stencil(GL_STENCIL_TEST);
+    {  // render non-deferred geometry (alpha, fullbright, glow)
+        LLGLDisable blend(GL_BLEND);
+        LLGLDisable stencil(GL_STENCIL_TEST);
+
+        pushRenderTypeMask();
+        andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+                          LLPipeline::RENDER_TYPE_FULLBRIGHT,
+                          LLPipeline::RENDER_TYPE_VOLUME,
+                          LLPipeline::RENDER_TYPE_GLOW,
+                          LLPipeline::RENDER_TYPE_BUMP,
+                          LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+                          LLPipeline::RENDER_TYPE_PASS_ALPHA,
+                          LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+                          LLPipeline::RENDER_TYPE_PASS_BUMP,
+                          LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
+                          LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+                          LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+                          LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+                          LLPipeline::RENDER_TYPE_PASS_GLOW,
+                          LLPipeline::RENDER_TYPE_PASS_GRASS,
+                          LLPipeline::RENDER_TYPE_PASS_SHINY,
+                          LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
+                          LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+                          LLPipeline::RENDER_TYPE_AVATAR,
+                          LLPipeline::RENDER_TYPE_CONTROL_AV,
+                          LLPipeline::RENDER_TYPE_ALPHA_MASK,
+                          LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+                          END_RENDER_TYPES);
+
+        renderGeomPostDeferred(*LLViewerCamera::getInstance());
+        popRenderTypeMask();
+    }
 
-		pushRenderTypeMask();
-		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
-						 LLPipeline::RENDER_TYPE_FULLBRIGHT,
-						 LLPipeline::RENDER_TYPE_VOLUME,
-						 LLPipeline::RENDER_TYPE_GLOW,
-						 LLPipeline::RENDER_TYPE_BUMP,
-						 LLPipeline::RENDER_TYPE_PASS_SIMPLE,
-						 LLPipeline::RENDER_TYPE_PASS_ALPHA,
-						 LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
-						 LLPipeline::RENDER_TYPE_PASS_BUMP,
-						 LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
-						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
-						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
-						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
-						 LLPipeline::RENDER_TYPE_PASS_GLOW,
-						 LLPipeline::RENDER_TYPE_PASS_GRASS,
-						 LLPipeline::RENDER_TYPE_PASS_SHINY,
-						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
-						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
-						 LLPipeline::RENDER_TYPE_AVATAR,
-						 LLPipeline::RENDER_TYPE_ALPHA_MASK,
-						 LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
-						 END_RENDER_TYPES);
-		
-		renderGeomPostDeferred(*LLViewerCamera::getInstance());
-		popRenderTypeMask();
-	}
+    {
+        // render highlights, etc.
+        renderHighlights();
+        mHighlightFaces.clear();
 
-	{
-		//render highlights, etc.
-		renderHighlights();
-		mHighlightFaces.clear();
+        renderDebug();
 
-		renderDebug();
+        LLVertexBuffer::unbind();
 
-		LLVertexBuffer::unbind();
-
-		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
-		{
-			// Render debugging beacons.
-			gObjectList.renderObjectBeacons();
-			gObjectList.resetObjectBeacons();
+        if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+        {
+            // Render debugging beacons.
+            gObjectList.renderObjectBeacons();
+            gObjectList.resetObjectBeacons();
             gSky.addSunMoonBeacons();
-		}
-	}
+        }
+    }
 
-	screen_target->flush();                        
+    screen_target->flush();
 }
 
 void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
@@ -9291,7 +9254,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 		
 		gPipeline.pushRenderTypeMask();
 
-        glh::matrix4f projection = get_current_projection();
+        glh::matrix4f saved_modelview  = get_current_modelview();
+        glh::matrix4f saved_projection = get_current_projection();
 		glh::matrix4f mat;
 
         S32 detail = RenderReflectionDetail;
@@ -9330,8 +9294,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 			//disable occlusion culling for reflection map for now
 			LLPipeline::sUseOcclusion = 0;
 
-        glh::matrix4f current = get_current_modelview();
-
         if (!camera_is_underwater)
         {   //generate planar reflection map
 
@@ -9340,15 +9302,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
             gGL.matrixMode(LLRender::MM_MODELVIEW);
             gGL.pushMatrix();
 
-            glh::matrix4f mat;
-            camera.getOpenGLTransform(mat.m);
+            mat.set_scale(glh::vec3f(1, 1, -1));
+            mat.set_translate(glh::vec3f(0,0,water_height*2.f));
+            mat = saved_modelview * mat;
 
-            glh::matrix4f scal;
-            scal.set_scale(glh::vec3f(1, 1, -1));
-            mat = scal * mat;
-
-            // convert from CFR to OGL coord sys...
-            mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
 
             mReflectionModelView = mat;
 
@@ -9357,6 +9314,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
 			LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
 
+            glh::vec3f    origin(0, 0, 0);
+            glh::matrix4f inv_mat = mat.inverse();
+            inv_mat.mult_matrix_vec(origin);
+
+            camera.setOrigin(origin.v);
+
 			glCullFace(GL_FRONT);
 
 			if (LLDrawPoolWater::sNeedsReflectionUpdate)
@@ -9401,7 +9364,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 						clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
 						if (detail < 3)
 						{
-							clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
+                            clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, END_RENDER_TYPES);
 							if (detail < 2)
 							{
 								clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
@@ -9409,7 +9372,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 						}
 					}
 
-                    LLGLUserClipPlane clip_plane(plane, mReflectionModelView, projection);
+                    LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
 					LLGLDisable cull(GL_CULL_FACE);
                     updateCull(camera, mReflectedObjects, -water_clip, &plane);
                     stateSort(camera, mReflectedObjects);
@@ -9423,7 +9386,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
             gGL.matrixMode(LLRender::MM_MODELVIEW);
 			gGL.popMatrix();
             
-            set_current_modelview(current);         
+            set_current_modelview(saved_modelview);
 		}
 
         //LLPipeline::sUseOcclusion = occlusion;
@@ -9479,7 +9442,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
                 //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,
                 // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map
                 LLPlane plane(-pnorm, water_dist);
-                LLGLUserClipPlane clip_plane(plane, current, projection);
+                LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
 
 				gGL.setColorMask(true, true);
 				mWaterDis.clear();
@@ -10116,6 +10079,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 					LLPipeline::RENDER_TYPE_BUMP,
 					LLPipeline::RENDER_TYPE_VOLUME,
 					LLPipeline::RENDER_TYPE_AVATAR,
+					LLPipeline::RENDER_TYPE_CONTROL_AV,
 					LLPipeline::RENDER_TYPE_TREE, 
 					LLPipeline::RENDER_TYPE_TERRAIN,
 					LLPipeline::RENDER_TYPE_WATER,
@@ -10909,7 +10873,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 	
 	if (visually_muted || too_complex)
 	{
-		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
+		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
+							LLPipeline::RENDER_TYPE_CONTROL_AV,
+							END_RENDER_TYPES);
 	}
 	else
 	{
@@ -10932,6 +10898,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 						LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
 						LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
 			LLPipeline::RENDER_TYPE_AVATAR,
+			LLPipeline::RENDER_TYPE_CONTROL_AV,
 			LLPipeline::RENDER_TYPE_ALPHA_MASK,
 			LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
 			LLPipeline::RENDER_TYPE_INVISIBLE,
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 68ce3fe88dea8dd719ecc65df0e930cf4898a75a..600bdd9d06dc1aba6baba86a462f9fca789267ea 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -139,7 +139,7 @@ class LLPipeline
 	void resetVertexBuffers(LLDrawable* drawable);
 	void generateImpostor(LLVOAvatar* avatar);
 	void bindScreenToTexture();
-	void renderBloom(bool for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
+	void renderFinalize();
 
 	void init();
 	void cleanup();
@@ -453,6 +453,7 @@ class LLPipeline
 		RENDER_TYPE_BUMP						= LLDrawPool::POOL_BUMP,
 		RENDER_TYPE_MATERIALS					= LLDrawPool::POOL_MATERIALS,
 		RENDER_TYPE_AVATAR						= LLDrawPool::POOL_AVATAR,
+		RENDER_TYPE_CONTROL_AV					= LLDrawPool::POOL_CONTROL_AV, // Animesh
 		RENDER_TYPE_TREE						= LLDrawPool::POOL_TREE,
 		RENDER_TYPE_INVISIBLE					= LLDrawPool::POOL_INVISIBLE,
 		RENDER_TYPE_VOIDWATER					= LLDrawPool::POOL_VOIDWATER,
diff --git a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
index b818a7d4800f34d679028da3fc79cfb4ac4207d9..81b093b8c25ed1ef80a43e4dd3c1762a92c474bd 100644
--- a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Mehrere Texturen
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Inventar" name="inventory" value="0"/>
-		<radio_item label="Lokal" name="local" value="1"/>
-		<radio_item label="Backen" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Größe: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Inventar" name="inventory" value="0"/>
+		<combo_box.item label="Lokal" name="local" value="1"/>
+	</combo_box>
 	<button label="Standard" label_selected="Standard" name="Default"/>
 	<button label="Leer" label_selected="Leer" name="Blank"/>
 	<button label="Keine" label_selected="Keine" name="None"/>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
index e0aa9fe4a97ab2fe765ba8405772a537fa44ae35..16fdb69509896fd30b6b121b34d8154669eabc9f 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
 	</text>
 	<check_box initial_value="true" label="Freunde immer darstellen" name="AlwaysRenderFriends"/>
 	<button label="Ausnahmen..." name="RenderExceptionsButton"/>
-	<button label="Einstellungen als Voreinstellung speichern..." name="PrefSaveButton"/>
-	<button label="Voreinstellung laden..." name="PrefLoadButton"/>
+	<button label="Einstellungen als Voreinstellung speichern" name="PrefSaveButton" width="235" left="5"/>
+	<button label="Voreinstellung laden" name="PrefLoadButton" width="120"/>
 	min_val=&quot;0.125&quot;
-	<button label="Voreinstellung löschen..." name="PrefDeleteButton"/>
-	<button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/>
+	<button label="Voreinstellung löschen" name="PrefDeleteButton" width="130"/>
+	<button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults" width="248"/>
 	<button label="Erweiterte Einstellungen..." name="AdvancedSettings"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
index 1435b7f87d34aea0a3ef44ca26a3de6d86d2aed2..a8509cabac42364618f804b94db38dc34d1a5720 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
@@ -35,5 +35,5 @@
 	<text name="Proxy Settings:">
 		Proxy-Einstellungen:
 	</text>
-	<button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy"/>
+	<button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy" width="160"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index a1dd179765208b873bf54df78be62776b9871fc6..b2d9e530398c4bcdc8cd13f4898b81f3163ab140 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -123,8 +123,8 @@
                 No parcel selected.
             </panel.string>
             <panel.string name="time_stamp_template">
-				[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
-			</panel.string>
+              [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
+            </panel.string>
             <text
              type="string"
              length="1"
diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml
index 3daff1a132fdecbadcb9f52519b218187ac3bc79..773d9aafc9cba2cd75c91f53ea64b67ff2280c6b 100644
--- a/indra/newview/skins/default/xui/en/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml
@@ -120,8 +120,8 @@
 Try saving image as 24 bit Targa (.tga).
     </text>
     <check_box
-     control_name="LosslessJ2CUpload"
      enabled="false"
+     initial_value="false"
      follows="bottom|left"
      height="16"
      label="Use lossless compression"
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
index 63334e2b241aa385862d527a8957c68db10f16ff..802a6649c8ab65c0e2de397bb11fc0915fe1017c 100644
--- a/indra/newview/skins/default/xui/en/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
@@ -13,7 +13,7 @@
  width="400">
     <floater.string
      name="timeStamp">
-        [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+        [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
     </floater.string>
     <scroll_list
      bottom="268"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index a52d0a95d600024f32c50d44b19ba028d908379e..3a669113894d437f79500a18031ffa0e0dfff497 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -48,42 +48,28 @@
     </text>
 	
 	<!-- mode selector -->
-	   <radio_group
+    <combo_box
      control_name="mode_selection"
      height="20"
      layout="topleft"
-     left="0"
-     top_pad="80"
+     left="6"
+     top_pad="77"
      name="mode_selection"
-     follows="left|top">
-        <radio_item
+     follows="left|top"
+     width="120">
+      <combo_box.item
          label="Inventory"
          name="inventory"
-         top_delta="20" 
-         layout="topleft"
-         height="16" 
-         left="0" 
-         value="0"
-         width="70" />
-        <radio_item
+         value="0" />
+      <combo_box.item
          label="Local"
-         left_pad="0"
-         layout="topleft"
-         top_delta="0" 
-         height="16" 
          name="local"
-         value="1"
-         width="50" />
-       <radio_item
+         value="1" />
+      <combo_box.item
          label="Bake"
-         left_pad="0"
-         layout="topleft"
-         top_delta="0"
-         height="16"
          name="bake"
-         value="2"
-         width="50" />
-    </radio_group>
+         value="2" />
+    </combo_box>
 	<!-- -->
 	
     <text
@@ -92,20 +78,8 @@
      follows="left|top"
      height="14"
      layout="topleft"
-     left_delta="12"
+     left="8"
      name="size_lbl"
-     top_pad="4">
-        Size:
-    </text>
-
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="14"
-     layout="topleft"
-     left_delta="0"
-     name="unknown"
      top_pad="4">
         [DIMENSIONS]
     </text>
@@ -149,8 +123,8 @@
      image_selected="eye_button_active.tga"
      image_unselected="eye_button_inactive.tga"
      layout="topleft"
-     left_delta="-80"
-     top_delta="-10"
+     left="18"
+     top_delta="-23"
      name="Pipette"
      width="28" />
    <text
@@ -329,7 +303,7 @@ layout="topleft"
      label="OK"
      label_selected="OK"
      layout="topleft"
-     left="95"
+     left="176"
      top="-30"
      name="Select"
      width="100" />
@@ -352,5 +326,5 @@ layout="topleft"
      left="6"
      name="apply_immediate_check"
      top_delta="0"
-     width="120" />
+     width="150" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 76df0abdfd68a565d081e9ed39aec9621a2fa3ef..d88c267a95e63bccedf1e939fe602e9ff304a858 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -12,6 +12,7 @@
       <file>msyh.ttc</file>
       <file load_collection="true">Cambria.ttc</file>
       <file>malgun.ttf</file>
+      <file>micross.ttf</file>
     </os>
     <os name="Mac">
       <file>ヒラギノ角ゴシック W3.ttc</file>  
@@ -25,6 +26,7 @@
       <file>华文细黑.ttf</file>
       <file>PingFang.ttc</file>
       <file>STIXGeneral.otf</file>
+      <file>Thonburi.ttc</file>
     </os>
   </font>
 
diff --git a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
index db29d9cebcb544b32299f96dcc0565c756b5c59e..49e52ebb8d6a28eb17b987a19c52c175c2fdfc17 100644
--- a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
@@ -16,4 +16,12 @@
          function="ScriptChiclet.Action"
          parameter="end" />
     </menu_item_call>
+    <menu_item_call
+     label="Close All Dialogs"
+     layout="topleft"
+     name="Close All">
+        <menu_item_call.on_click
+         function="ScriptChiclet.Action"
+         parameter="close all" />
+    </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 873b95926b7845fa650e7caec9ac5f1961b9c571..5fa1847d1b840941e54557745c34542d3056f5fb 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1732,6 +1732,16 @@ function="World.EnvPreset"
                  function="Advanced.ToggleRenderType"
                  parameter="character" />
             </menu_item_check>
+            <menu_item_check
+             label="Animeshes"
+             name="Rendering Type Control Avatar">
+                <menu_item_check.on_check
+                 function="Advanced.CheckRenderType"
+                 parameter="controlAV" />
+                <menu_item_check.on_click
+                 function="Advanced.ToggleRenderType"
+                 parameter="controlAV" />
+            </menu_item_check>
             <menu_item_check
              label="Surface Patch"
              name="Rendering Type Surface Patch"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c53b4ca800b86b441441049f042179c36c237fa5..b19c9a6e7cc2b68e26776424d641441087f6d646 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3679,6 +3679,17 @@ Could not teleport to [SLURL] as it's on a different grid ([GRID]) than the curr
      yestext="OK"/>
   </notification>
 
+  <notification icon="alertmodal.tga"
+		name="GeneralCertificateErrorShort"
+		type="alertmodal">
+Could not connect to the server.
+[REASON]
+    <tag>fail</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification icon="alertmodal.tga"
 		name="GeneralCertificateError"
 		type="alertmodal">
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 13986c40308f5a505000e54d74296e77569f3a15..87035e5cd38e83c57919772559d56fdcc30bd6c8 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -41,7 +41,7 @@
     </string>
     <string
      name="acquired_date">
-        [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+        [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
     </string>
     <!-- Texture names for rating icons -->
     <string
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index eeb930485e1250b27c1f36d2f2a9e02db7416101..6c8cc9d39a63be96b4427c822814dbadda9c03ef 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -30,7 +30,6 @@
      tab_height="30"
      tab_position="top"
      halign="center"
-     hide_scroll_arrows="true"
      top="8"
      width="315">
          <panel
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index ece6c95080e22da18c5c46f97fb2d33648341f61..c023cb036ee65655ba80801c69d1a01dfbae330e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -52,7 +52,7 @@
     </check_box>
 
     <check_box
-        control_name="VoiceCallsFriendsOnly"
+        enabled="false"
         height="16"
         label="Only friends and groups can call or IM me"
         layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index c2defdd772f33b2f7c1f12e498440dc1fa373504..65b9a6411182d38133ae47f55c27167a5d40b2e5 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -514,12 +514,12 @@
    follows="left|top"
    height="23"
    is_toggle="true"
-   label="Input/Output devices"
+   label="Voice Input/Output devices"
    layout="topleft"
    left="20"
    top_pad="6"
    name="device_settings_btn"
-   width="190">
+   width="230">
   </button>
     <panel
     layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
index bec793bbeeeff4bd0deef6da4806408b16da47d4..6f82a0efa1a42fa21ca3162c91b9864c15d03fe6 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -203,10 +203,10 @@
                         Ice Level:
                     </text>
                     <slider
-                            decimal_digits="1"
+                            decimal_digits="3"
                             follows="left|top"
                             height="14"
-                            increment="0.1"
+                            increment="0.001"
                             initial_value="0"
                             left_delta="5"
                             top_delta="20"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 2a1eb425edc959737150881eb878bb0db0d4b5d8..1777a0db0523cf55f38c0d1d5d137987fdb21691 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -32,7 +32,7 @@ width="333">
    top="5"
    follows="left|top|right"
    layout="topleft"
-   width="303"
+   width="307"
    height="33"
    name="panel_currentlook"
    >
@@ -118,14 +118,14 @@ width="333">
    name="Filter"
    search_button_visible="true"
    top_pad="10"
-   width="303" />
+   width="307" />
    <panel
    class="panel_outfits_inventory"
    filename="panel_outfits_inventory.xml"
    name="panel_outfits_inventory"
    height="493"
    min_height="410"
-   width="320"
+   width="325"
    visible="false"
    left="0"
    tab_group="1"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index acb6f5b42ae260c34da92cb7781668f12b024283..9a68479d05c143907a5ef0d73ed09f28016ad986 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -33,7 +33,7 @@
   </panel.string>
   <panel.string
     name="acquiredDate">
-    [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+    [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
   </panel.string>
   <panel.string
     name="origin_inventory">
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9e45e2e3bfc6279355ca19d05a3b191c8cd8d3db..7398e457f0803077452b506ff157d9ba25c8b3f8 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -28,7 +28,7 @@
     <string name="BuildConfig">Build Configuration [BUILD_CONFIG]</string>
 
 	<string name="AboutPosition">
-You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt;
 SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
 (global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
 [SERVER_VERSION]
@@ -107,7 +107,9 @@ Voice Server Version: [VOICE_VERSION]
 	<string name="CertExpired">The certificate returned by the Grid appears to be expired.  Please check your system clock, or contact your Grid administrator.</string>
 	<string name="CertKeyUsage">The certificate returned by the server could not be used for SSL.  Please contact your Grid administrator.</string>
 	<string name="CertBasicConstraints">Too many certificates were in the servers Certificate chain.  Please contact your Grid administrator.</string>
+	<string name="CertInvalid">Could not load certificate. Please contact your Grid administrator.</string>
 	<string name="CertInvalidSignature">The certificate signature returned by the Grid server could not be verified.  Please contact your Grid administrator.</string>
+	<string name="CertAllocationFailure">Failed to allocate openssl memory for certificate.</string>
 
 	<string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string>
 	<string name="LoginFailed">Login failed.</string>
diff --git a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
index 2e409ef69c9bb4fa98c26de8613b9c28d504bb38..a77dd99af0e6a2df8484757258587db6cc0ff87c 100644
--- a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Texturas múltiples
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Inventario" name="inventory" value="0"/>
-		<radio_item label="Local" name="local" value="1"/>
-		<radio_item label="Hornear" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Tamaño: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Inventario" name="inventory" value="0"/>
+		<combo_box.item label="Local" name="local" value="1"/>
+	</combo_box>
 	<button label="Por defecto" label_selected="Por defecto" name="Default" width="84"/>
 	<button label="Blanca" label_selected="Blanca" name="Blank"/>
 	<button label="Ninguna" label_selected="Ninguna" left="90" name="None"/>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
index 007101b8fed8dcf464a775d25efd7caae5b9b04a..0ba676898f8722effc67736d98a48ab89f39060e 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
@@ -28,5 +28,5 @@
 	<check_box label="Mostrar la selección de cuadrícula al iniciar sesión" name="show_grid_selection_check"/>
 	<check_box label="Mostrar el menú Avanzado" name="show_advanced_menu_check"/>
 	<check_box label="Mostrar el menú Desarrollar" name="show_develop_menu_check"/>
-	<button label="Permisos de creación predeterminados" name="default_creation_permissions"/>
+	<button label="Permisos de creación predeterminados" name="default_creation_permissions" width="235"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
index 816c6985480a3221563cebe2098d0ada670fafa7..47815d02967ec5258b6681129c6980cf1f97f246 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
 	</text>
 	<check_box initial_value="true" label="Renderizar siempre los amigos" name="AlwaysRenderFriends"/>
 	<button label="Excepciones..." name="RenderExceptionsButton"/>
-	<button label="Guardar configuración como valor predefinido..." name="PrefSaveButton"/>
-	<button label="Cargar predefinido..." name="PrefLoadButton"/>
+	<button label="Guardar configuración como valor predefinido" name="PrefSaveButton" width="260" left="5"/>
+	<button label="Cargar predefinido" name="PrefLoadButton" left_pad="7"/>
 	min_val=&quot;0.125&quot;
-	<button label="Eliminar predefinido..." name="PrefDeleteButton"/>
-	<button label="Restablecer la configuración recomendada" name="Defaults"/>
+	<button label="Eliminar predefinido" name="PrefDeleteButton"  width="117" left_pad="7"/>
+	<button label="Restablecer la configuración recomendada" name="Defaults" width="248"/>
 	<button label="Configuración avanzada..." name="AdvancedSettings"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
index 2925727b48980670f7867cb047d89c74be7b132c..a4de7954c5460960ffc03fe75e8c920dc7b66376 100644
--- a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Textures multiples
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Inventaire" name="inventory" value="0"/>
-		<radio_item label="Local" name="local" value="1"/>
-		<radio_item label="Figer" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Taille : [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Inventaire" name="inventory" value="0"/>
+		<combo_box.item label="Local" name="local" value="1"/>
+	</combo_box>
 	<button label="Défaut" label_selected="Défaut" name="Default" width="60"/>
 	<button label="Vierge" label_selected="Vierge" name="Blank" width="60"/>
 	<button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index 7117ace7e1b54dda6381ef9d0425c588e361a50a..46d63052909faad838f7c7c20e27ab1cd4bdbc04 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
 	</text>
 	<check_box initial_value="true" label="Toujours effectuer le rendu des amis" name="AlwaysRenderFriends"/>
 	<button label="Exceptions..." name="RenderExceptionsButton"/>
-	<button label="Enregistrer les paramètres comme préréglage..." name="PrefSaveButton"/>
-	<button label="Charger un préréglage..." name="PrefLoadButton"/>
+	<button label="Enregistrer les paramètres comme préréglage" name="PrefSaveButton" width="260" />
+	<button label="Charger un préréglage" name="PrefLoadButton" width="132"/>
 	min_val=&quot;0,125&quot;
-	<button label="Supprimer un préréglage..." name="PrefDeleteButton"/>
-	<button label="Réinitialiser les paramètres recommandés" name="Defaults"/>
+	<button label="Supprimer un préréglage" name="PrefDeleteButton" width="148" top_delta="30" left_pad="-220"/>
+	<button label="Réinitialiser les paramètres recommandés" name="Defaults" width="255" top_delta="35"/>
 	<button label="Paramètres avancés" name="AdvancedSettings"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
index 2e4644cef3efd25d0730d303005434385eb08e0a..f857bfe49faee209805ca273f5aa2822ac021012 100644
--- a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Texture multiple
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Inventario" name="inventory" value="0"/>
-		<radio_item label="Locale" name="local" value="1"/>
-		<radio_item label="Effettua il bake" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Dimensioni: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Inventario" name="inventory" value="0"/>
+		<combo_box.item label="Locale" name="local" value="1"/>
+	</combo_box>
 	<button label="Default" label_selected="Default" name="Default"/>
 	<button label="Vuoto" label_selected="Vuoto" name="Blank"/>
 	<button label="Niente" label_selected="Niente" name="None"/>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
index f3ca9fafb3b6d50c1404c749f751dcdf3aaa9a4f..c7739b847200423e7d8fdc5b3320be18272cf12c 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
 	</text>
 	<check_box initial_value="true" label="Esegui sempre il rendering degli amici" name="AlwaysRenderFriends"/>
 	<button label="Eccezioni..." name="RenderExceptionsButton"/>
-	<button label="Salva impostazioni come valori predefiniti..." name="PrefSaveButton"/>
-	<button label="Carica valore predefinito..." name="PrefLoadButton"/>
+	<button label="Salva impostazioni come valori predefiniti" name="PrefSaveButton" width="240" left="4"/>
+	<button label="Carica valore predefinito" name="PrefLoadButton" width="145" left_pad="7"/>
 	min_val=&quot;0.125&quot;
-	<button label="Elimina valore predefinito..." name="PrefDeleteButton"/>
+	<button label="Elimina valore predefinito" name="PrefDeleteButton" width="148" left_pad="7"/>
 	<button label="Ripristina impostazioni consigliate" name="Defaults"/>
 	<button label="Impostazioni avanzate..." name="AdvancedSettings"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
index aa3ff53f4aea97473fded82735133fc78c30d74d..c9d90539e1d3193da59d5bf72c9e15a111d7cd23 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
@@ -35,5 +35,5 @@
 	<text name="Proxy Settings:">
 		Impostazioni proxy:
 	</text>
-	<button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy"/>
+	<button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy" width="160"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
index 05e7bfefd2ee7cb07f25cc616433c071efd19184..1221702e9b762a70140e410f2786036ef9ad82dc 100644
--- a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		複数のテクスチャ
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="インベントリ" name="inventory" value="0"/>
-		<radio_item label="ローカル" name="local" value="1"/>
-		<radio_item label="構築(ベーク)" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		サイズ: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="インベントリ" name="inventory" value="0"/>
+		<combo_box.item label="ローカル" name="local" value="1"/>
+	</combo_box>
 	<button label="デフォルト" label_selected="デフォルト" name="Default"/>
 	<button label="ブランク" label_selected="ブランク" name="Blank"/>
 	<button label="なし" label_selected="なし" name="None"/>
diff --git a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
index 8ac158b4623608d494a731de0fc9d1166a6d0947..24252131606cbc233843031075efb0ae23a14e1b 100644
--- a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
@@ -9,13 +9,10 @@
 	<text name="Multiple">
 		Wiele tekstur
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Szafa" name="inventory" />
-		<radio_item label="Lokalna" name="local" />
-	</radio_group>
-	<text name="unknown">
-		Rozm.: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Szafa" name="inventory" />
+		<combo_box.item label="Lokalna" name="local" />
+	</combo_box>
 	<button label="Domyślna" label_selected="Domyślna" name="Default" />
 	<button label="Pusta" label_selected="Pusta" name="Blank" />
 	<button label="Przezrocz." label_selected="Przezrocz." name="None" />
diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
index d06c16d8c8a6b724657ccd571c06d3bc9dafe29b..d3eec114e258df9fd9a83076bce633d2c3c3664f 100644
--- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Multiplas texturas
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Inventário" name="inventory" value="0"/>
-		<radio_item label="Local" name="local" value="1"/>
-		<radio_item label="Assar" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Tamanho: [DIMENSÕES]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Inventário" name="inventory" value="0"/>
+		<combo_box.item label="Local" name="local" value="1"/>
+	</combo_box>
 	<button label="Padrão" label_selected="Padrão" name="Default"/>
 	<button label="Branco" label_selected="Branco" name="Blank"/>
 	<button label="Nenhum" label_selected="Nenhum" name="None"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
index a0f4ea4ed5d9d4023ccf55e48a8e89bfdb89fb81..d387c4c869333e78ca546ecfdd63c68f6eec3470 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
@@ -33,10 +33,10 @@ rápido
 	</text>
 	<check_box initial_value="true" label="Sempre renderizar amigos" name="AlwaysRenderFriends"/>
 	<button label="Exceções..." name="RenderExceptionsButton"/>
-	<button label="Salvar configurações como predefinição..." name="PrefSaveButton"/>
-	<button label="Carregar predefinição..." name="PrefLoadButton"/>
+	<button label="Salvar configurações como predefinição" name="PrefSaveButton" width="235" left="5"/>
+	<button label="Carregar predefinição" name="PrefLoadButton" width="130" left_pad="8"/>
 	min_val=&quot;0.125&quot;
-	<button label="Excluir predefinição..." name="PrefDeleteButton"/>
-	<button label="Redefinir para configurações recomendadas" left="110" name="Defaults"/>
+	<button label="Excluir predefinição" name="PrefDeleteButton" width="122" left_pad="8"/>
+	<button label="Redefinir para configurações recomendadas" name="Defaults" width="255"/>
 	<button label="Configurações avançadas..." name="AdvancedSettings"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
index 03536f28c378b4da3093577ab4099cd1285c5350..56fc225bc0856ba1099d14c0f6b310daaa5cb9d0 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
@@ -35,5 +35,5 @@
 	<text name="Proxy Settings:">
 		Configurações de proxy:
 	</text>
-	<button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy"/>
+	<button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy" width="180"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
index c56657b86bc109c0130b9e55151f1ea8fee0e091..d4323e5c344b52fe9e4e84e67b7ac278e1697132 100644
--- a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Несколько текстур
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Инвентарь" name="inventory" value="0"/>
-		<radio_item label="Локально" name="local" value="1"/>
-		<radio_item label="Зафиксировать" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Размер: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Инвентарь" name="inventory" value="0"/>
+		<combo_box.item label="Локально" name="local" value="1"/>
+	</combo_box>
 	<button label="По умолчанию" label_selected="По умолчанию" name="Default"/>
 	<button label="Очистить" label_selected="Очистить" name="Blank"/>
 	<button label="Нет" label_selected="Нет" name="None"/>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index 517c4db278206e561ba122ff3cebdaacb10476f8..f3d52aacb9461b74a3d4838ae3ba3ea96aab9341 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -1612,22 +1612,22 @@
 [DOWNLOAD_PATH].
 	</notification>
 	<notification name="RequiredUpdate">
-		Для входа необходима версия \[VERSION]. 
+		Для входа необходима версия [VERSION]. 
 Скачайте обновление с веб-сайта https://secondlife.com/support/downloads/
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="PauseForUpdate">
-		Для входа необходима версия \[VERSION]. 
+		Для входа необходима версия [VERSION]. 
 Нажмите OK для загрузки и установки.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="OptionalUpdateReady">
-		Версия \[VERSION] загружена и готова к установке. 
+		Версия [VERSION] загружена и готова к установке. 
 Нажмите OK для установки.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="PromptOptionalUpdate">
-		Версия \[VERSION] загружена и готова к установке. 
+		Версия [VERSION] загружена и готова к установке. 
 Продолжить?
 		<usetemplate canceltext="Не сейчас" name="yesnocancelbuttons" notext="Пропустить" yestext="Установить"/>
 	</notification>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
index dd0cf8e17256b4d3780438d0acf11e9bffb2a11c..79d5cb796028e1183099d674235c5a417b2c4ee0 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
@@ -28,5 +28,5 @@
 	<check_box label="Выбор сетки при входе" name="show_grid_selection_check"/>
 	<check_box label="Показывать расширенное меню" name="show_advanced_menu_check"/>
 	<check_box label="Показать меню разработчика" name="show_develop_menu_check"/>
-	<button label="Стандартные разрешения на создание" name="default_creation_permissions"/>
+	<button label="Стандартные разрешения на создание" name="default_creation_permissions" width="235"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
index 4524fb4d434060cf9b3274d2e2dd7dc2f431c6f0..f392a1f0b7a6e86b64c198e1645835b0d953350b 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
@@ -32,7 +32,7 @@
 	</text>
 	<check_box initial_value="true" label="Всегда рисовать друзей" name="AlwaysRenderFriends"/>
 	<button label="Исключения..." name="RenderExceptionsButton"/>
-	<button label="Сохранить настройки как пресет..." name="PrefSaveButton"/>
+	<button label="Сохранить настройки как пресет..." name="PrefSaveButton" width="210"/>
 	<button label="Загрузить пресет..." name="PrefLoadButton"/>
 	min_val=&quot;0,125&quot;
 	<button label="Удалить пресет..." name="PrefDeleteButton"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
index 1a1670912728bc4a04be98721a8c9a00a65c0dfe..0389cdcbe5caee522a81d6d95190483d76f24cfc 100644
--- a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		Birden çok doku
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="Envanter" name="inventory" value="0"/>
-		<radio_item label="Yerel" name="local" value="1"/>
-		<radio_item label="Kurut" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		Büyüklük: [DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="Envanter" name="inventory" value="0"/>
+		<combo_box.item label="Yerel" name="local" value="1"/>
+	</combo_box>
 	<button label="Varsayılan" label_selected="Varsayılan" name="Default"/>
 	<button label="BoÅŸ" label_selected="BoÅŸ" name="Blank"/>
 	<button label="Hiçbiri" label_selected="Hiçbiri" name="None"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
index 881ca4033837961519b6648da6e00905f7be0b4e..6fc3e1129b832771ef61aa578a05fcdb5e074443 100644
--- a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
@@ -9,14 +9,10 @@
 	<text name="Multiple">
 		多重材質
 	</text>
-	<radio_group name="mode_selection">
-		<radio_item label="收納區" name="inventory" value="0"/>
-		<radio_item label="本地" name="local" value="1"/>
-		<radio_item label="確定產出" name="bake" value="2"/>
-	</radio_group>
-	<text name="unknown">
-		尺寸:[DIMENSIONS]
-	</text>
+	<combo_box name="mode_selection">
+		<combo_box.item label="收納區" name="inventory" value="0"/>
+		<combo_box.item label="本地" name="local" value="1"/>
+	</combo_box>
 	<button label="預設" label_selected="預設" name="Default"/>
 	<button label="空白" label_selected="空白" name="Blank"/>
 	<button label="ç„¡" label_selected="ç„¡" name="None"/>
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 63967fae37843a1e37f6a422db527dff98ca233f..e5d226a2a4966cea58d25fca2939073d71e424f6 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -124,6 +124,14 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
 S32 LLMachineID::init() { return 1; }
 	
 
+LLCertException::LLCertException(const LLSD& cert_data, const std::string& msg)
+    : LLException(msg),
+    mCertData(cert_data)
+{
+    LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;
+}
+
+
 // -------------------------------------------------------------------------------------------
 // TUT
 // -------------------------------------------------------------------------------------------
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index f5edde1923b7b235027948efb677406f6a288b95..90a2af98f7fc0adfcf043d447560ad3ab2e5e639 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -523,6 +523,11 @@ def construct(self):
                 else:
                     self.path("fmod.dll")
 
+            if self.args['openal'] == 'ON':
+                # Get openal dll
+                self.path("OpenAL32.dll")
+                self.path("alut.dll")
+
             # For textures
             self.path("openjpeg.dll")
 
@@ -1515,7 +1520,6 @@ def construct(self):
                     print "Skipping libfmod.so - not found"
                     pass
 
-
         # Vivox runtimes
         with self.prefix(src=relpkgdir, dst="bin"):
             self.path("SLVoice")
@@ -1545,10 +1549,12 @@ def construct(self):
     print('%s \\\n%s' %
           (sys.executable,
            ' '.join((("'%s'" % arg) if ' ' in arg else arg) for arg in sys.argv)))
+    # fmodstudio and openal can be used simultaneously and controled by environment
     extra_arguments = [
         dict(name='bugsplat', description="""BugSplat database to which to post crashes,
              if BugSplat crash reporting is desired""", default=''),
         dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'),
+        dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'),
         ]
     try:
         main(extra=extra_arguments)