diff --git a/.hgtags b/.hgtags
index fcf043b1ea496cbd568de109050512c468eac013..b0da8b0d987f003ea3e50ff9d9fb28482d18013f 100755
--- a/.hgtags
+++ b/.hgtags
@@ -545,3 +545,4 @@ ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
 821edfcd14919c0e95c590866171c61fb57e8623 6.0.0-release
 21b7604680ef6b6ea67f8bebaaa588d6e263bdc1 6.0.1-release
 a3143db58a0f6b005232bf9018e7fef17ff9ec90 6.1.0-release
+50f0ece62ddb5a244ecb6d00ef5a89d80ad50efa 6.1.1-release
diff --git a/autobuild.xml b/autobuild.xml
index 62542be8d8e44bd99c918260aca779174b68d6ea..5f072512c1822073e92618f18d5b459c41cbf060 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -44,7 +44,7 @@
         </map>
         <key>version</key>
         <string>1.2.15</string>
-      </map>      
+      </map>
       <key>apr_suite</key>
       <map>
         <key>copyright</key>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 05c548ad0956d2f35ef7a41431ea7c4a60e3c971..4fa5860f7e5f90dd5ac8e8560613a4e94965b66c 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -220,6 +220,8 @@ Ansariel Hiller
 	STORM-2151
 	MAINT-6917
 	MAINT-8085
+	MAINT-8723
+	SL-10385
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 605032e0a826647a0ccb13a14df65074975f572c..e32625796cd4c642ed3de31048075c16cc9b9b7b 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2191,9 +2191,10 @@ BOOL LLVolume::generate()
 			LLVector4a* end_profile = profile+sizeT;
 			LLVector4a offset = mPathp->mPath[s].mPos;
 
+            // hack to work around MAINT-5660 for debug until we can suss out
+            // what is wrong with the path generated that inserts NaNs...
             if (!offset.isFinite3())
-            { // MAINT-5660; don't know why this happens, does not affect Release builds
-                LL_WARNS() << "LLVolume using path with non-finite points. Resetting them to 0,0,0" << LL_ENDL;
+            {
                 offset.clear();
             }
 
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index 57ceb3e11be7fea6735b02bf3288248a271d6902..a219ac14501a9fee140e004bbbfb132ba6aca9d5 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -65,23 +65,23 @@ const F32 MATERIALS_MULTIPLIER                   = 10000.f;
 
 template<typename T> T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
 {
-	if ( (data.has(field)) && (field_type == data[field].type()) )
-	{
-		return (T)data[field];
-	}
-	LL_ERRS() << "Missing or mistyped field '" << field << "' in material definition" << LL_ENDL;
-	return (T)LLSD();
+    if ( (data.has(field)) && (field_type == data[field].type()) )
+    {
+        return (T)data[field];
+    }
+    LL_ERRS() << "Missing or mistyped field '" << field << "' in material definition" << LL_ENDL;
+    return (T)LLSD();
 }
 
 // GCC didn't like the generic form above for some reason
 template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
 {
-	if ( (data.has(field)) && (field_type == data[field].type()) )
-	{
-		return data[field].asUUID();
-	}
-	LL_ERRS() << "Missing or mistyped field '" << field << "' in material definition" << LL_ENDL;
-	return LLUUID::null;
+    if ( (data.has(field)) && (field_type == data[field].type()) )
+    {
+        return data[field].asUUID();
+    }
+    LL_ERRS() << "Missing or mistyped field '" << field << "' in material definition" << LL_ENDL;
+    return LLUUID::null;
 }
 
 /**
@@ -91,137 +91,377 @@ template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, c
 const LLMaterial LLMaterial::null;
 
 LLMaterial::LLMaterial()
-	: mNormalOffsetX(0.0f)
-	, mNormalOffsetY(0.0f)
-	, mNormalRepeatX(1.0f)
-	, mNormalRepeatY(1.0f)
-	, mNormalRotation(0.0f)
-	, mSpecularOffsetX(0.0f)
-	, mSpecularOffsetY(0.0f)
-	, mSpecularRepeatX(1.0f)
-	, mSpecularRepeatY(1.0f)
-	, mSpecularRotation(0.0f)
-	, mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR)
-	, mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
-	, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
-	, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
-	, mAlphaMaskCutoff(0)
+    : mNormalOffsetX(0.0f)
+    , mNormalOffsetY(0.0f)
+    , mNormalRepeatX(1.0f)
+    , mNormalRepeatY(1.0f)
+    , mNormalRotation(0.0f)
+    , mSpecularOffsetX(0.0f)
+    , mSpecularOffsetY(0.0f)
+    , mSpecularRepeatX(1.0f)
+    , mSpecularRepeatY(1.0f)
+    , mSpecularRotation(0.0f)
+    , mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR)
+    , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
+    , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
+    , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+    , mAlphaMaskCutoff(0)
 {
 }
 
 LLMaterial::LLMaterial(const LLSD& material_data)
 {
-	fromLLSD(material_data);
+    fromLLSD(material_data);
 }
 
-LLSD LLMaterial::asLLSD() const
+const LLUUID& LLMaterial::getNormalID() const
+{
+    return mNormalID;
+}
+
+void LLMaterial::setNormalID(const LLUUID& normal_id)
 {
-	LLSD material_data;
+    mNormalID = normal_id;
+}
+
+void LLMaterial::getNormalOffset(F32& offset_x, F32& offset_y) const
+{
+    offset_x = mNormalOffsetX;
+    offset_y = mNormalOffsetY;
+}
 
-	material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID;
-	material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = ll_round(mNormalOffsetX * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = ll_round(mNormalOffsetY * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = ll_round(mNormalRepeatX * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = ll_round(mNormalRepeatY * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = ll_round(mNormalRotation * MATERIALS_MULTIPLIER);
+F32 LLMaterial::getNormalOffsetX() const
+{
+    return mNormalOffsetX;
+}
 
-	material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID;
-	material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = ll_round(mSpecularOffsetX * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = ll_round(mSpecularOffsetY * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = ll_round(mSpecularRepeatX * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = ll_round(mSpecularRepeatY * MATERIALS_MULTIPLIER);
-	material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = ll_round(mSpecularRotation * MATERIALS_MULTIPLIER);
+F32 LLMaterial::getNormalOffsetY() const
+{
+    return mNormalOffsetY;
+}
 
-	material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD]     = mSpecularLightColor.getValue();
-	material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD]       = mSpecularLightExponent;
-	material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD]      = mEnvironmentIntensity;
-	material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
-	material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD]  = mAlphaMaskCutoff;
+void LLMaterial::setNormalOffset(F32 offset_x, F32 offset_y)
+{
+    mNormalOffsetX = offset_x;
+    mNormalOffsetY = offset_y;
+}
 
-	return material_data;
+void LLMaterial::setNormalOffsetX(F32 offset_x)
+{
+    mNormalOffsetX = offset_x;
 }
 
-void LLMaterial::fromLLSD(const LLSD& material_data)
+void LLMaterial::setNormalOffsetY(F32 offset_y)
+{
+    mNormalOffsetY = offset_y;
+}
+
+void LLMaterial::getNormalRepeat(F32& repeat_x, F32& repeat_y) const
+{
+    repeat_x = mNormalRepeatX;
+    repeat_y = mNormalRepeatY;
+}
+
+F32 LLMaterial::getNormalRepeatX() const
+{
+    return mNormalRepeatX;
+}
+
+F32 LLMaterial::getNormalRepeatY() const
+{
+    return mNormalRepeatY;
+}
+
+void LLMaterial::setNormalRepeat(F32 repeat_x, F32 repeat_y)
+{
+    mNormalRepeatX = repeat_x;
+    mNormalRepeatY = repeat_y;
+}
+
+void LLMaterial::setNormalRepeatX(F32 repeat_x)
+{
+    mNormalRepeatX = repeat_x;
+}
+
+void LLMaterial::setNormalRepeatY(F32 repeat_y)
+{
+    mNormalRepeatY = repeat_y;
+}
+
+F32 LLMaterial::getNormalRotation() const
+{
+    return mNormalRotation;
+}
+
+void LLMaterial::setNormalRotation(F32 rot)
+{
+    mNormalRotation = rot;
+}
+
+const LLUUID& LLMaterial::getSpecularID() const
+{
+    return mSpecularID;
+}
+
+void LLMaterial::setSpecularID(const LLUUID& specular_id)
+{
+    mSpecularID = specular_id;
+}
+
+void LLMaterial::getSpecularOffset(F32& offset_x, F32& offset_y) const
+{
+    offset_x = mSpecularOffsetX;
+    offset_y = mSpecularOffsetY;
+}
+
+F32 LLMaterial::getSpecularOffsetX() const
+{
+    return mSpecularOffsetX;
+}
+
+F32 LLMaterial::getSpecularOffsetY() const
+{
+    return mSpecularOffsetY;
+}
+
+void LLMaterial::setSpecularOffset(F32 offset_x, F32 offset_y)
+{
+    mSpecularOffsetX = offset_x;
+    mSpecularOffsetY = offset_y;
+}
+
+void LLMaterial::setSpecularOffsetX(F32 offset_x)
+{
+    mSpecularOffsetX = offset_x;
+}
+
+void LLMaterial::setSpecularOffsetY(F32 offset_y)
+{
+    mSpecularOffsetY = offset_y;
+}
+
+void LLMaterial::getSpecularRepeat(F32& repeat_x, F32& repeat_y) const
+{
+    repeat_x = mSpecularRepeatX;
+    repeat_y = mSpecularRepeatY;
+}
+
+F32 LLMaterial::getSpecularRepeatX() const
+{
+    return mSpecularRepeatX;
+}
+
+F32 LLMaterial::getSpecularRepeatY() const
+{
+    return mSpecularRepeatY;
+}
+
+void LLMaterial::setSpecularRepeat(F32 repeat_x, F32 repeat_y)
+{
+    mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y;
+}
+
+void LLMaterial::setSpecularRepeatX(F32 repeat_x)
+{
+    mSpecularRepeatX = repeat_x;
+}
+
+void LLMaterial::setSpecularRepeatY(F32 repeat_y)
+{
+    mSpecularRepeatY = repeat_y;
+}
+
+F32 LLMaterial::getSpecularRotation() const
+{
+    return mSpecularRotation;
+}
+
+void LLMaterial::setSpecularRotation(F32 rot)
+{
+    mSpecularRotation = rot;
+}
+
+const LLColor4U LLMaterial::getSpecularLightColor() const
+{
+    return mSpecularLightColor;
+}
+
+void LLMaterial::setSpecularLightColor(const LLColor4U& color)
+{
+    mSpecularLightColor = color;
+}
+
+U8 LLMaterial::getSpecularLightExponent() const
+{
+    return mSpecularLightExponent;
+}
+
+void LLMaterial::setSpecularLightExponent(U8 exponent)
+{
+    mSpecularLightExponent = exponent;
+}
+
+U8 LLMaterial::getEnvironmentIntensity() const
+{
+    return mEnvironmentIntensity;
+}
+
+void LLMaterial::setEnvironmentIntensity(U8 intensity)
 {
-	mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
-	mNormalOffsetX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mNormalOffsetY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mNormalRepeatX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mNormalRepeatY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mNormalRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+    mEnvironmentIntensity = intensity;
+}
 
-	mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
-	mSpecularOffsetX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mSpecularOffsetY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mSpecularRepeatX  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mSpecularRepeatY  = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
-	mSpecularRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+U8 LLMaterial::getDiffuseAlphaMode() const
+{
+    return mDiffuseAlphaMode;
+}
 
-	mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
-	mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD,       LLSD::TypeInteger);
-	mEnvironmentIntensity  = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD,      LLSD::TypeInteger);
-	mDiffuseAlphaMode      = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
-	mAlphaMaskCutoff       = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD,  LLSD::TypeInteger);
+void LLMaterial::setDiffuseAlphaMode(U8 alpha_mode)
+{
+    mDiffuseAlphaMode = alpha_mode;
+}
+
+U8 LLMaterial::getAlphaMaskCutoff() const
+{
+    return mAlphaMaskCutoff;
+}
+
+void LLMaterial::setAlphaMaskCutoff(U8 cutoff)
+{
+    mAlphaMaskCutoff = cutoff;
+}
+
+LLSD LLMaterial::asLLSD() const
+{
+    LLSD material_data;
+
+    S32 normalOffsetXInt = ll_round(mNormalOffsetX  * MATERIALS_MULTIPLIER);
+    S32 normalOffsetYInt = ll_round(mNormalOffsetY  * MATERIALS_MULTIPLIER);
+    S32 normalRotInt     = ll_round(mNormalRotation * MATERIALS_MULTIPLIER);
+
+    material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID;
+    material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = normalOffsetXInt;
+    material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = normalOffsetYInt;
+    material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = ll_round(mNormalRepeatX * MATERIALS_MULTIPLIER);
+    material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = ll_round(mNormalRepeatY * MATERIALS_MULTIPLIER);
+    material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = normalRotInt;
+
+    material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID;
+
+    S32 specularOffsetXInt = ll_round(mSpecularOffsetX  * MATERIALS_MULTIPLIER);
+    S32 specularOffsetYInt = ll_round(mSpecularOffsetY  * MATERIALS_MULTIPLIER);
+    S32 specularRotInt     = ll_round(mSpecularRotation * MATERIALS_MULTIPLIER);
+
+    material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = specularOffsetXInt;
+    material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = specularOffsetYInt;
+    material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = ll_round(mSpecularRepeatX * MATERIALS_MULTIPLIER);
+    material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = ll_round(mSpecularRepeatY * MATERIALS_MULTIPLIER);
+    material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = specularRotInt;
+
+    material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD]     = mSpecularLightColor.getValue();
+    material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD]       = mSpecularLightExponent;
+    material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD]      = mEnvironmentIntensity;
+    material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
+    material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD]  = mAlphaMaskCutoff;
+
+    return material_data;
+}
+
+void LLMaterial::fromLLSD(const LLSD& material_data)
+{
+    mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
+
+    S32 normalOffsetXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger);
+    S32 normalOffsetYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger);
+    S32 normalRotInt     = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger);
+    S32 normalRepeatXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger);
+    S32 normalRepeatYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger);
+
+    mNormalOffsetX  = F32(normalOffsetXInt) / MATERIALS_MULTIPLIER;
+    mNormalOffsetY  = F32(normalOffsetYInt) / MATERIALS_MULTIPLIER;
+    mNormalRotation = F32(normalRotInt)     / MATERIALS_MULTIPLIER;
+    mNormalRepeatX  = F32(normalRepeatXInt) / MATERIALS_MULTIPLIER;
+    mNormalRepeatY  = F32(normalRepeatYInt) / MATERIALS_MULTIPLIER;
+
+    mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
+
+    S32 specularOffsetXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger);
+    S32 specularOffsetYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger);
+    S32 specularRotInt     = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger);
+    S32 specularRepeatXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger);
+    S32 specularRepeatYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger);
+
+    mSpecularOffsetX   = F32(specularOffsetXInt) / MATERIALS_MULTIPLIER;
+    mSpecularOffsetY   = F32(specularOffsetYInt) / MATERIALS_MULTIPLIER;
+    mSpecularRotation  = F32(specularRotInt)     / MATERIALS_MULTIPLIER;
+    mSpecularRepeatX  = F32(specularRepeatXInt) / MATERIALS_MULTIPLIER;
+    mSpecularRepeatY  = F32(specularRepeatYInt) / MATERIALS_MULTIPLIER;
+
+    mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
+    mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD,       LLSD::TypeInteger);
+    mEnvironmentIntensity  = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD,      LLSD::TypeInteger);
+    mDiffuseAlphaMode      = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
+    mAlphaMaskCutoff       = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD,  LLSD::TypeInteger);
 }
 
 bool LLMaterial::isNull() const
 {
-	return (*this == null);
+    return (*this == null);
 }
 
 bool LLMaterial::operator == (const LLMaterial& rhs) const
 {
-	return 
-		(mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) &&
-		(mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) &&
-		(mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) &&
-		(mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) &&
-		(mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) &&
-		(mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff);
+    return 
+        (mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) &&
+        (mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) &&
+        (mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) &&
+        (mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) &&
+        (mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) &&
+        (mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff);
 }
 
 bool LLMaterial::operator != (const LLMaterial& rhs) const
 {
-	return !(*this == rhs);
+    return !(*this == rhs);
 }
 
 
 U32 LLMaterial::getShaderMask(U32 alpha_mode)
 { //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation
-	U32 ret = 0;
-
-	//two least significant bits are "diffuse alpha mode"
-	if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
-	{
-		ret = alpha_mode;
-	}
-	else
-	{
-		ret = getDiffuseAlphaMode();
-	}
-
-	llassert(ret < SHADER_COUNT);
-
-	//next bit is whether or not specular map is present
-	const U32 SPEC_BIT = 0x4;
-
-	if (getSpecularID().notNull())
-	{
-		ret |= SPEC_BIT;
-	}
-
-	llassert(ret < SHADER_COUNT);
-	
-	//next bit is whether or not normal map is present
-	const U32 NORM_BIT = 0x8;
-	if (getNormalID().notNull())
-	{
-		ret |= NORM_BIT;
-	}
-
-	llassert(ret < SHADER_COUNT);
-
-	return ret;
+    U32 ret = 0;
+
+    //two least significant bits are "diffuse alpha mode"
+    if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
+    {
+        ret = alpha_mode;
+    }
+    else
+    {
+        ret = getDiffuseAlphaMode();
+    }
+
+    llassert(ret < SHADER_COUNT);
+
+    //next bit is whether or not specular map is present
+    const U32 SPEC_BIT = 0x4;
+
+    if (getSpecularID().notNull())
+    {
+        ret |= SPEC_BIT;
+    }
+
+    llassert(ret < SHADER_COUNT);
+    
+    //next bit is whether or not normal map is present
+    const U32 NORM_BIT = 0x8;
+    if (getNormalID().notNull())
+    {
+        ret |= NORM_BIT;
+    }
+
+    llassert(ret < SHADER_COUNT);
+
+    return ret;
 }
 
 
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index 9f52a3f6c1b1c2c32c759a770a2fc2b0ae6b6534..d58b7ee8127ae7d86488827702723bdbd2f6ab3b 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -39,114 +39,115 @@ class LLMaterial : public LLRefCount
 {
 public:
 
-	typedef enum
-	{
-		DIFFUSE_ALPHA_MODE_NONE = 0,
-		DIFFUSE_ALPHA_MODE_BLEND = 1,
-		DIFFUSE_ALPHA_MODE_MASK = 2,
-		DIFFUSE_ALPHA_MODE_EMISSIVE = 3,
-		DIFFUSE_ALPHA_MODE_DEFAULT = 4,
-	} eDiffuseAlphaMode;
-
-	typedef enum
-	{
-		SHADER_COUNT = 16,
-		ALPHA_SHADER_COUNT = 4
-	} eShaderCount;
-
-	
-	
-	static const U8			DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255));
-	static const LLColor4U	DEFAULT_SPECULAR_LIGHT_COLOR;
-	static const U8			DEFAULT_ENV_INTENSITY = 0;
-
-	LLMaterial();
-	LLMaterial(const LLSD& material_data);
-
-	LLSD asLLSD() const;
-	void fromLLSD(const LLSD& material_data);
-
-	const LLUUID& getNormalID() const { return mNormalID; }
-	void		setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; }
-	void		getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; }
-	F32		getNormalOffsetX() const { return mNormalOffsetX; }
-	F32		getNormalOffsetY() const { return mNormalOffsetY; }
-
-	void		setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; }
-	void		setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; }
-	void		setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; }
-
-	void		getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; }
-	F32		getNormalRepeatX() const { return mNormalRepeatX; }
-	F32		getNormalRepeatY() const { return mNormalRepeatY; }
-
-	void		setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; }
-	void		setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; }
-	void		setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; }
-
-	F32		getNormalRotation() const { return mNormalRotation; }
-	void		setNormalRotation(F32 rot) { mNormalRotation = rot; }
-
-	const LLUUID& getSpecularID() const { return mSpecularID; }
-	void		setSpecularID(const LLUUID& specular_id)  { mSpecularID = specular_id; }
-	void		getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; }
-	F32		getSpecularOffsetX() const { return mSpecularOffsetX; }
-	F32		getSpecularOffsetY() const { return mSpecularOffsetY; }
-
-	void		setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; }
-	void		setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; }
-	void		setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; }
-
-	void		getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; }
-	F32		getSpecularRepeatX() const { return mSpecularRepeatX; }
-	F32		getSpecularRepeatY() const { return mSpecularRepeatY; }
-
-	void		setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; }
-	void		setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; }
-	void		setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; }
-
-	F32		getSpecularRotation() const { return mSpecularRotation; }
-	void		setSpecularRotation(F32 rot) { mSpecularRotation = rot; }
-
-	const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; }
-	void		setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; }
-	U8			getSpecularLightExponent() const { return mSpecularLightExponent; }
-	void		setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; }
-	U8			getEnvironmentIntensity() const { return mEnvironmentIntensity; }
-	void		setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; }
-	U8			getDiffuseAlphaMode() const { return mDiffuseAlphaMode; }
-	void		setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; }
-	U8			getAlphaMaskCutoff() const { return mAlphaMaskCutoff; }
-	void		setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
-
-	bool		isNull() const;
-	static const LLMaterial null;
-
-	bool		operator == (const LLMaterial& rhs) const;
-	bool		operator != (const LLMaterial& rhs) const;
-
-	U32			getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
+    typedef enum
+    {
+        DIFFUSE_ALPHA_MODE_NONE = 0,
+        DIFFUSE_ALPHA_MODE_BLEND = 1,
+        DIFFUSE_ALPHA_MODE_MASK = 2,
+        DIFFUSE_ALPHA_MODE_EMISSIVE = 3,
+        DIFFUSE_ALPHA_MODE_DEFAULT = 4,
+    } eDiffuseAlphaMode;
+
+    typedef enum
+    {
+        SHADER_COUNT = 16,
+        ALPHA_SHADER_COUNT = 4
+    } eShaderCount;
+
+    
+    
+    static const U8         DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255));
+    static const LLColor4U  DEFAULT_SPECULAR_LIGHT_COLOR;
+    static const U8         DEFAULT_ENV_INTENSITY = 0;
+
+    LLMaterial();
+    LLMaterial(const LLSD& material_data);
+
+    LLSD asLLSD() const;
+    void fromLLSD(const LLSD& material_data);
+
+    const LLUUID&   getNormalID() const;
+    void            setNormalID(const LLUUID& normal_id);
+
+    void        getNormalOffset(F32& offset_x, F32& offset_y) const;
+    F32         getNormalOffsetX() const;
+    F32         getNormalOffsetY() const;
+
+    void        setNormalOffset(F32 offset_x, F32 offset_y);
+    void        setNormalOffsetX(F32 offset_x);
+    void        setNormalOffsetY(F32 offset_y);
+
+    void        getNormalRepeat(F32& repeat_x, F32& repeat_y) const;
+    F32         getNormalRepeatX() const;
+    F32         getNormalRepeatY() const;
+
+    void        setNormalRepeat(F32 repeat_x, F32 repeat_y);
+    void        setNormalRepeatX(F32 repeat_x);
+    void        setNormalRepeatY(F32 repeat_y);
+
+    F32         getNormalRotation() const;
+    void        setNormalRotation(F32 rot);
+
+    const LLUUID& getSpecularID() const;
+    void        setSpecularID(const LLUUID& specular_id);
+    void        getSpecularOffset(F32& offset_x, F32& offset_y) const;
+    F32         getSpecularOffsetX() const;
+    F32         getSpecularOffsetY() const;
+
+    void        setSpecularOffset(F32 offset_x, F32 offset_y);
+    void        setSpecularOffsetX(F32 offset_x);
+    void        setSpecularOffsetY(F32 offset_y);
+
+    void        getSpecularRepeat(F32& repeat_x, F32& repeat_y) const;
+    F32         getSpecularRepeatX() const;
+    F32         getSpecularRepeatY() const;
+
+    void        setSpecularRepeat(F32 repeat_x, F32 repeat_y);
+    void        setSpecularRepeatX(F32 repeat_x);
+    void        setSpecularRepeatY(F32 repeat_y);
+
+    F32         getSpecularRotation() const;
+    void        setSpecularRotation(F32 rot);
+
+    const LLColor4U getSpecularLightColor() const;
+    void        setSpecularLightColor(const LLColor4U& color);
+    U8          getSpecularLightExponent() const;
+    void        setSpecularLightExponent(U8 exponent);
+    U8          getEnvironmentIntensity() const;
+    void        setEnvironmentIntensity(U8 intensity);
+    U8          getDiffuseAlphaMode() const;
+    void        setDiffuseAlphaMode(U8 alpha_mode);
+    U8          getAlphaMaskCutoff() const;
+    void        setAlphaMaskCutoff(U8 cutoff);
+
+    bool        isNull() const;
+    static const LLMaterial null;
+
+    bool        operator == (const LLMaterial& rhs) const;
+    bool        operator != (const LLMaterial& rhs) const;
+
+    U32         getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
 
 protected:
-	LLUUID		mNormalID;
-	F32			mNormalOffsetX;
-	F32			mNormalOffsetY;
-	F32			mNormalRepeatX;
-	F32			mNormalRepeatY;
-	F32			mNormalRotation;
-
-	LLUUID		mSpecularID;
-	F32			mSpecularOffsetX;
-	F32			mSpecularOffsetY;
-	F32			mSpecularRepeatX;
-	F32			mSpecularRepeatY;
-	F32			mSpecularRotation;
-
-	LLColor4U	mSpecularLightColor;
-	U8			mSpecularLightExponent;
-	U8			mEnvironmentIntensity;
-	U8			mDiffuseAlphaMode;
-	U8			mAlphaMaskCutoff;
+    LLUUID      mNormalID;
+    F32         mNormalOffsetX;
+    F32         mNormalOffsetY;
+    F32         mNormalRepeatX;
+    F32         mNormalRepeatY;
+    F32         mNormalRotation;
+
+    LLUUID      mSpecularID;
+    F32         mSpecularOffsetX;
+    F32         mSpecularOffsetY;
+    F32         mSpecularRepeatX;
+    F32         mSpecularRepeatY;
+    F32         mSpecularRotation;
+
+    LLColor4U   mSpecularLightColor;
+    U8          mSpecularLightExponent;
+    U8          mEnvironmentIntensity;
+    U8          mDiffuseAlphaMode;
+    U8          mAlphaMaskCutoff;
 };
 
 typedef LLPointer<LLMaterial> LLMaterialPtr;
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index a40c3988f23c72ea218458dc2a143845853ab639..dc2e2010440b8028c024b06451f1472c4df4d8df 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -136,6 +136,8 @@ class LLTextureEntry
 	
 	virtual const LLUUID &getID() const { return mID; }
 	const LLColor4 &getColor() const { return mColor; }
+    const F32 getAlpha() const { return mColor.mV[VALPHA]; }
+
 	void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; }
 	F32  getScaleS() const { return mScaleS; }
 	F32  getScaleT() const { return mScaleT; }
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index d18512f6133e437256ffb735ec11d1ca3d0e3868..df36738604b93e2dc191dcebb8521624be65a7f9 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1897,7 +1897,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
 		GL_TEXTURE_COORD_ARRAY
 	};
 
-	 U32 mask[] = 
+	static const U32 mask[] = 
 	{ //copied from llvertexbuffer.h
 		0x0001, //MAP_VERTEX,
 		0x0002, //MAP_NORMAL,
@@ -2628,3 +2628,11 @@ LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_w
 { 
     gGL.setSceneBlendType(LLRender::BT_ALPHA);
 }
+
+#if LL_WINDOWS
+// Expose desired use of high-performance graphics processor to Optimus driver
+extern "C" 
+{ 
+    _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; 
+}
+#endif
\ No newline at end of file
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index ec8f05e4caf8be9343781b1f5ea25f76892b8ee8..4303c3ed11f9d229d4984be889db9a9a23c4410e 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -606,8 +606,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		}
 	}
 	
-	//LL_SHADER_LOADING_WARNS() << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
-
 	if (filename.empty()) 
 	{
 		return 0;
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 7f2224870d76eed58cd1931044af54fa91545468..698b128d45d079c8d7633bd38977c480000835a2 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -489,10 +489,6 @@ void LLToolTipMgr::show(const LLToolTip::Params& params)
 		return;
 	}
 	
-	S32 mouse_x;
-	S32 mouse_y;
-	LLUI::getMousePositionLocal(gToolTipView, &mouse_x, &mouse_y);
-
 	// are we ready to show the tooltip?
 	if (!mToolTipsBlocked									// we haven't hit a key, moved the mouse, etc.
 		&& LLUI::getMouseIdleTime() > params_with_defaults.delay_time)	// the mouse has been still long enough
@@ -574,12 +570,12 @@ void LLToolTipMgr::updateToolTipVisibility()
 	}
 
 	// hide existing tooltips if they have timed out
-	S32 mouse_x, mouse_y;
-	LLUI::getMousePositionLocal(gToolTipView, &mouse_x, &mouse_y);
-
 	F32 tooltip_timeout = 0.f;
 	if (toolTipVisible())
 	{
+		S32 mouse_x, mouse_y;
+		LLUI::getMousePositionLocal(gToolTipView, &mouse_x, &mouse_y);
+		
 		// mouse far away from tooltip
 		tooltip_timeout = mLastToolTipParams.visible_time_far;
 		// mouse near rect will only include the tooltip if the 
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 770f13c1c398d710266752010afaad60132eb150..e9f8ba020e674c5bfcca6ec74f3b8f5ad64d868e 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -237,9 +237,13 @@ void LLUI::dirtyRect(LLRect rect)
 void LLUI::setMousePositionScreen(S32 x, S32 y)
 {
 	S32 screen_x, screen_y;
+#if defined(LL_DARWIN)
+    screen_x = ll_round((F32)x);
+    screen_y = ll_round((F32)y);
+#else
 	screen_x = ll_round((F32)x * getScaleFactor().mV[VX]);
 	screen_y = ll_round((F32)y * getScaleFactor().mV[VY]);
-	
+#endif
 	LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
 }
 
@@ -250,7 +254,7 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)
 	getWindow()->getCursorPosition(&cursor_pos_window);
 	LLCoordGL cursor_pos_gl(cursor_pos_window.convert());
 	*x = ll_round((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]);
-	*y = ll_round((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]);
+	*y = ll_round((F32)cursor_pos_gl.mY / getScaleFactor().mV[VY]);
 }
 
 //static 
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index c8c086d705c8be6b7845323f49e51b941e1e16c7..54a4793b2df6bd2512262d3ff979941da0ac7db5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -28,6 +28,8 @@
 #import "llwindowmacosx-objc.h"
 #import "llappdelegate-objc.h"
 
+extern BOOL gHiDPISupport;
+
 #pragma mark local functions
 
 NativeKeyEventData extractKeyDataFromKeyEvent(NSEvent* theEvent)
@@ -154,8 +156,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
 {
 	[[NSNotificationCenter defaultCenter] addObserver:self
 											 selector:@selector(windowResized:) name:NSWindowDidResizeNotification
-											   object:[self window]];    
- 
+											   object:[self window]];
+    
     [[NSNotificationCenter defaultCenter] addObserver:self
 											 selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification
 											   object:[self window]];
@@ -167,6 +169,17 @@ attributedStringInfo getSegments(NSAttributedString *str)
     [[NSNotificationCenter defaultCenter] addObserver:self
 											 selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification
 											   object:[self window]];
+	[[NSNotificationCenter defaultCenter] addObserver:self
+											 selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification
+											   object:[self window]];
+
+
+    NSRect wnd_rect = [[self window] frame];
+    NSRect dev_rect = [self convertRectToBacking:wnd_rect];
+    if (!NSEqualSizes(wnd_rect.size,dev_rect.size))
+    {
+        callResize(dev_rect.size.width, dev_rect.size.height);
+    }
 }
 
 - (void)setOldResize:(bool)oldresize
@@ -178,8 +191,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
 {
     if (!mOldResize)  //Maint-3288
     {
-        NSSize size = [self frame].size;
-        callResize(size.width, size.height);
+        NSSize dev_sz = gHiDPISupport ? [self convertSizeToBacking:[self frame].size] : [self frame].size;
+        callResize(dev_sz.width, dev_sz.height);
     }
 }
 
@@ -198,6 +211,11 @@ attributedStringInfo getSegments(NSAttributedString *str)
     mModifiers = [NSEvent modifierFlags];
 }
 
+-(void)windowDidChangeScreen:(NSNotification *)notification;
+{
+	callWindowDidChangeScreen();
+}
+
 - (void)dealloc
 {
 	[[NSNotificationCenter defaultCenter] removeObserver:self];
@@ -258,7 +276,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	}
 	
 	[self setPixelFormat:pixelFormat];
-	
+
+	//for retina support
+	[self setWantsBestResolutionOpenGLSurface:gHiDPISupport];
+
 	[self setOpenGLContext:glContext];
 	
 	[glContext setView:self];
@@ -350,7 +371,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
         callRightMouseUp(mMousePos, [theEvent modifierFlags]);
         mSimulatedRightClick = false;
     } else {
-        NSPoint mPoint = [theEvent locationInWindow];
+        NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow];
         mMousePos[0] = mPoint.x;
         mMousePos[1] = mPoint.y;
         callLeftMouseUp(mMousePos, [theEvent modifierFlags]);
@@ -369,14 +390,16 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)mouseMoved:(NSEvent *)theEvent
 {
-	float mouseDeltas[2] = {
-		float([theEvent deltaX]),
-		float([theEvent deltaY])
+    NSPoint dev_delta = gHiDPISupport ? [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])] : NSMakePoint([theEvent deltaX], [theEvent deltaY]);
+
+	float mouseDeltas[] = {
+		float(dev_delta.x),
+		float(dev_delta.y)
 	};
 	
 	callDeltaUpdate(mouseDeltas, 0);
 	
-	NSPoint mPoint = [theEvent locationInWindow];
+    NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow];
 	mMousePos[0] = mPoint.x;
 	mMousePos[1] = mPoint.y;
 	callMouseMoved(mMousePos, 0);
@@ -390,14 +413,17 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	// Trust the deltas supplied by NSEvent.
 	// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
 	// NSEvent isn't obsolete, and provides us with the correct deltas.
-	float mouseDeltas[2] = {
-		float([theEvent deltaX]),
-		float([theEvent deltaY])
+
+    NSPoint dev_delta = gHiDPISupport ? [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])] : NSMakePoint([theEvent deltaX], [theEvent deltaY]);
+
+	float mouseDeltas[] = {
+		float(dev_delta.x),
+		float(dev_delta.y)
 	};
 	
 	callDeltaUpdate(mouseDeltas, 0);
 	
-	NSPoint mPoint = [theEvent locationInWindow];
+	NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow];
 	mMousePos[0] = mPoint.x;
 	mMousePos[1] = mPoint.y;
 	callMouseDragged(mMousePos, 0);
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index 7e90ade423c402df0bbc50f893df4b115cb28cdd..94c725fc7ebb74fc67d1c9b8d6cbbddb14f3b50d 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -180,6 +180,11 @@ BOOL LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor,
 	return FALSE;
 }
 
+BOOL LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow *window)
+{
+	return FALSE;
+}
+
 void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg)
 {
 
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 47d5a18858b45724747663bc77ac9b474a9cf748..4d753024fec52ff3ab07e48b2317f8bfdfa23f7c 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -66,6 +66,7 @@ class LLWindowCallbacks
 	virtual BOOL handleTimerEvent(LLWindow *window);
 	virtual BOOL handleDeviceChange(LLWindow *window);
 	virtual BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
+	virtual BOOL handleWindowDidChangeScreen(LLWindow *window);
 
 	enum DragNDropAction {
 		DNDA_START_TRACKING = 0,// Start tracking an incoming drag
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index b06cd2c184ec61488d54e024c931cac20ace1fca..34da99de194c59cbc0de4a0b818884609096b468 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -31,6 +31,9 @@
 #include <map>
 #include <vector>
 
+//fir CGSize
+#include <CoreGraphics/CGGeometry.h>
+
 typedef std::vector<std::pair<int, bool> > segment_t;
 
 typedef std::vector<int> segment_lengths;
@@ -101,11 +104,15 @@ void setResizeMode(bool oldresize, void* glview);
 NSWindowRef createNSWindow(int x, int y, int width, int height);
 
 #include <OpenGL/OpenGL.h>
+
 GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
 void glSwapBuffers(void* context);
 CGLContextObj getCGLContextObj(GLViewRef view);
 unsigned long getVramSize(GLViewRef view);
-void getContentViewBounds(NSWindowRef window, float* bounds);
+float getDeviceUnitSize(GLViewRef view);
+const CGPoint & getContentViewBoundsPosition(NSWindowRef window);
+const CGSize & getContentViewBoundsSize(NSWindowRef window);
+const CGSize & getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
 void getWindowSize(NSWindowRef window, float* size);
 void setWindowSize(NSWindowRef window, int width, int height);
 void getCursorPos(NSWindowRef window, float* pos);
@@ -141,6 +148,7 @@ void callWindowFocus();
 void callWindowUnfocus();
 void callWindowHide();
 void callWindowUnhide();
+void callWindowDidChangeScreen();
 void callDeltaUpdate(float *delta, unsigned int mask);
 void callMiddleMouseDown(float *pos, unsigned int mask);
 void callMiddleMouseUp(float *pos, unsigned int mask);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 43ce9a225524def43281c673f1ff077411b3c5a4..c3eb9b8c8a79004d65094ba2457bb146fadea319 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -253,12 +253,24 @@ unsigned long getVramSize(GLViewRef view)
 	return [(LLOpenGLView *)view getVramSize];
 }
 
-void getContentViewBounds(NSWindowRef window, float* bounds)
+float getDeviceUnitSize(GLViewRef view)
 {
-	bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
-	bounds[1] = [[(LLNSWindow*)window contentView] bounds].origin.y;
-	bounds[2] = [[(LLNSWindow*)window contentView] bounds].size.width;
-	bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
+	return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
+}
+
+const CGPoint & getContentViewBoundsPosition(NSWindowRef window)
+{
+	return [[(LLNSWindow*)window contentView] bounds].origin;
+}
+
+const CGSize & getContentViewBoundsSize(NSWindowRef window)
+{
+	return [[(LLNSWindow*)window contentView] bounds].size;
+}
+
+const CGSize & getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
+{
+    return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size;
 }
 
 void getWindowSize(NSWindowRef window, float* size)
@@ -368,8 +380,8 @@ void closeWindow(NSWindowRef window)
 
 void removeGLView(GLViewRef view)
 {
+	[(LLOpenGLView*)view clearGLContext];
 	[(LLOpenGLView*)view removeFromSuperview];
-	[(LLOpenGLView*)view release];
 }
 
 void setupInputWindow(NSWindowRef window, GLViewRef glview)
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index d4afbb15df4f7a8fd1ebd58fdbd9d8f13cc31a86..fedea3de08d274286d7e6b3343b11392218e6ced 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -43,6 +43,7 @@
 #include <CoreServices/CoreServices.h>
 
 extern BOOL gDebugWindowProc;
+BOOL gHiDPISupport = TRUE;
 
 const S32	BITS_PER_PIXEL = 32;
 const S32	MAX_NUM_RESOLUTIONS = 32;
@@ -400,6 +401,14 @@ void callWindowUnhide()
 	}
 }
 
+void callWindowDidChangeScreen()
+{
+	if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+	{
+		gWindowImplementation->getCallbacks()->handleWindowDidChangeScreen(gWindowImplementation);
+	}
+}
+
 void callDeltaUpdate(float *delta, MASK mask)
 {
 	gWindowImplementation->updateMouseDeltas(delta);
@@ -819,7 +828,6 @@ void LLWindowMacOSX::gatherInput()
 
 BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 {
-	float rect[4];
 	S32 err = -1;
 
 	if(mFullscreen)
@@ -830,10 +838,12 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 	}
 	else if(mWindow)
 	{
-		getContentViewBounds(mWindow, rect);
+		const CGPoint & pos = getContentViewBoundsPosition(mWindow);
 
-		position->mX = rect[0];
-		position->mY = rect[1];
+		position->mX = pos.x;
+		position->mY = pos.y;
+
+		err = noErr;
 	}
 	else
 	{
@@ -845,7 +855,6 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 
 BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 {
-	float rect[4];
 	S32 err = -1;
 
 	if(mFullscreen)
@@ -856,10 +865,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 	}
 	else if(mWindow)
 	{
-		getContentViewBounds(mWindow, rect);
+		const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow);
 
-		size->mX = rect[2];
-		size->mY = rect[3];
+		size->mX = sz.width;
+		size->mY = sz.height;
 	}
 	else
 	{
@@ -871,7 +880,6 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 
 BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 {
-	float rect[4];
 	S32 err = -1;
 	
 	if(mFullscreen)
@@ -882,10 +890,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 	}
 	else if(mWindow)
 	{
-		getContentViewBounds(mWindow, rect);
+		const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow);
 		
-		size->mX = rect[2];
-		size->mY = rect[3];
+		size->mX = sz.width;
+		size->mY = sz.height;
 	}
 	else
 	{
@@ -1094,6 +1102,9 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
 	// trigger mouse move callback
 	LLCoordGL gl_pos;
 	convertCoords(position, &gl_pos);
+	float scale = getSystemUISize();
+	gl_pos.mX *= scale;
+	gl_pos.mY *= scale;
 	mCallbacks->handleMouseMove(this, gl_pos, (MASK)0);
 
 	return result;
@@ -1124,8 +1135,9 @@ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
 		cursor_point[1] += mCursorLastEventDeltaY;
 	}
 
-	position->mX = cursor_point[0];
-	position->mY = cursor_point[1];
+	float scale = getSystemUISize();
+	position->mX = cursor_point[0] * scale;
+	position->mY = cursor_point[1] * scale;
 
 	return TRUE;
 }
@@ -1334,6 +1346,7 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
 
 		mouse_point[0] = from.mX;
 		mouse_point[1] = from.mY;
+		
 		convertWindowToScreen(mWindow, mouse_point);
 
 		to->mX = mouse_point[0];
@@ -1889,6 +1902,11 @@ MASK LLWindowMacOSX::modifiersToMask(S16 modifiers)
 	return mask;
 }
 
+F32 LLWindowMacOSX::getSystemUISize()
+{
+	return gHiDPISupport ? ::getDeviceUnitSize(mGLView) : LLWindow::getSystemUISize();
+}
+
 #if LL_OS_DRAGDROP_ENABLED
 /*
 S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 9e9bd8ae394c2012254a12b104984a15e15a4e41..24651027e8385f29ff13fe908173d9588fb29694 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -112,6 +112,7 @@ class LLWindowMacOSX : public LLWindow
 	/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
 	/*virtual*/ void interruptLanguageTextInput();
 	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
+	/*virtual*/ F32 getSystemUISize();
 
 	static std::vector<std::string> getDynamicFallbackFontList();
 
@@ -135,7 +136,7 @@ class LLWindowMacOSX : public LLWindow
 		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
 		BOOL ignore_pixel_depth,
 		U32 fsaa_samples);
-	~LLWindowMacOSX();
+		~LLWindowMacOSX();
 
 	void	initCursors();
 	BOOL	isValid();
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 6abaeb2f90723ba328101fc117a1f19e93407e47..5e3254243a3b271c531c00916b750411d9dad34e 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.2.0
+6.1.2
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0a3324ce6178299e1365cd8d6ba57c49a793a8d6..394df72068958adecd8f0bd14faecebd2ae06f40 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8781,6 +8781,17 @@
     <string>Boolean</string>
     <key>Value</key>
     <integer>0</integer>
+  </map>
+   <key>RenderHiDPI</key>
+  <map>
+    <key>Comment</key>
+    <string>Enable support for HiDPI displays, like Retina (MacOS X ONLY, requires restart)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
   </map>
     <key>RenderPerformanceTest</key>
     <map>
@@ -9039,17 +9050,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-  <key>RenderDebugSH</key>
-    <map>
-      <key>Comment</key>
-      <string>Enable SH indirect lighting visualization.</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
   <key>RenderMaxTextureIndex</key>
   <map>
     <key>Comment</key>
@@ -13217,7 +13217,7 @@
     <key>LastSystemUIScaleFactor</key>
     <map>
       <key>Comment</key>
-      <string>Size of system UI during last run. On Windows 100% (96 DPI) system setting is 1.0 UI size</string>
+      <string>OBSOLETE: System UI scale factor is now automatically and independently from UIScaleFactor applied</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..c64b6ba24066ceb57544c9dcc585d860cd354a7d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
@@ -0,0 +1,64 @@
+/** 
+ * @file attachmentAlphaMaskShadowF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform float minimum_alpha;
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 post_pos;
+VARYING vec2 vary_texcoord0;
+VARYING float pos_w;
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+
+void main() 
+{
+	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+
+	if (alpha < 0.05) // treat as totally transparent
+	{
+		discard;
+	}
+
+	if (alpha < minimum_alpha) // treat as semi-transparent
+	{
+	  //if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+	  {
+	    discard;
+	  }
+	}
+
+	frag_color = vec4(1,1,1,1);
+
+#if !DEPTH_CLAMP	
+	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..b54c580ce95ea58f93ad0c6369311bb89e710541
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
@@ -0,0 +1,68 @@
+/** 
+ * @file attachmentAlphaShadowF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform float minimum_alpha;
+uniform sampler2D diffuseMap;
+
+VARYING float pos_w;
+VARYING float target_pos_x;
+
+#if !DEPTH_CLAMP
+VARYING vec4 post_pos;
+#endif
+
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
+
+void main() 
+{
+	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
+
+	if (alpha < 0.05) // treat as totally transparent
+	{
+		discard;
+	}
+
+	if (alpha < minimum_alpha)
+	{
+	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+	  {
+	    discard;
+	  }
+	}
+
+	frag_color = vec4(1,1,1,1);
+
+#if !DEPTH_CLAMP	
+	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..31b93dc36acc16e6fbde76a51c5f2d18d2cf19ca
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
@@ -0,0 +1,74 @@
+/** 
+ * @file attachmentShadowV.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$
+ */
+
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+uniform mat4 texture_matrix0;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+mat4 getObjectSkinnedTransform();
+void passTextureIndex();
+
+#if !DEPTH_CLAMP
+VARYING vec4 post_pos;
+#endif
+VARYING vec2 vary_texcoord0;
+VARYING float pos_w;
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+
+void main()
+{
+	//transform vertex
+	mat4 mat = getObjectSkinnedTransform();
+	
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+
+	vec4 p = projection_matrix * vec4(pos, 1.0);
+
+	pos_w = p.w;
+
+	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+	vertex_color = diffuse_color;
+
+#if !DEPTH_CLAMP
+	p.z = max(p.z, -p.w+0.01);
+    post_pos = p;
+	gl_Position = p;
+#else
+	gl_Position = p;
+#endif
+
+	passTextureIndex();
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..b8ce54bcb121ebb7940ee3272f9fb6af17399cf7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
@@ -0,0 +1,65 @@
+/** 
+ * @file treeShadowF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform float minimum_alpha;
+uniform sampler2D diffuseMap;
+
+#if !DEPTH_CLAMP
+VARYING vec4 post_pos;
+#endif
+
+VARYING float target_pos_x;
+VARYING float pos_w;
+VARYING vec2 vary_texcoord0;
+
+void main() 
+{
+	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+
+	if (alpha < 0.05) // treat as totally transparent
+	{
+		discard;
+	}
+
+	if (alpha < minimum_alpha)
+	{
+	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+	  {
+	    discard;
+	  }
+	}
+
+	frag_color = vec4(1,1,1,1);
+	
+#if !DEPTH_CLAMP
+	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..ef49b6f4e826bafdd0daf3a14bf8655ec62ec19d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -0,0 +1,68 @@
+/** 
+ * @file avatarAlphaShadowF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform float minimum_alpha;
+
+uniform sampler2D diffuseMap;
+
+#if !DEPTH_CLAMP
+VARYING vec4 post_pos;
+#endif
+
+VARYING float pos_w;
+VARYING float target_pos_x;
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
+
+void main() 
+{
+	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
+
+	if (alpha < 0.05) // treat as totally transparent
+	{
+		discard;
+	}
+
+	if (alpha < minimum_alpha) // treat as semi-transparent
+	{
+	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+	  {
+	    discard;
+	  }
+	}
+
+	frag_color = vec4(1,1,1,1);
+	
+#if !DEPTH_CLAMP
+	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..d1d7ece6febb89a622fabc6845eae0c067bbe862
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -0,0 +1,82 @@
+/** 
+ * @file avatarShadowV.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$
+ */
+ 
+uniform mat4 texture_matrix0;
+uniform mat4 projection_matrix;
+uniform float shadow_target_width;
+
+mat4 getSkinnedTransform();
+void passTextureIndex();
+
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+#if !DEPTH_CLAMP
+VARYING vec4 post_pos;
+#endif
+VARYING float pos_w;
+VARYING float target_pos_x;
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
+
+void main()
+{
+	vec4 pos;
+	vec3 norm;
+	
+	vec4 pos_in = vec4(position.xyz, 1.0);
+	mat4 trans = getSkinnedTransform();
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
+	pos.w = 1.0;
+	
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
+	norm = normalize(norm);
+	
+	pos = projection_matrix * pos;
+
+	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+	pos_w = pos.w;
+
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+	vertex_color = diffuse_color;
+#if !DEPTH_CLAMP
+	post_pos = pos;
+
+	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+	gl_Position = pos;
+#endif
+
+	passTextureIndex();
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..90566393d281b4b97ffa0d194c3f8d18c643b397
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
@@ -0,0 +1,42 @@
+/** 
+ * @file highlightF.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$
+ */
+ 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform vec4 color;
+uniform sampler2D diffuseMap;
+
+VARYING vec2 vary_texcoord0;
+
+void main() 
+{
+	frag_data[0] = color*texture2D(diffuseMap, vary_texcoord0.xy);
+	frag_data[1] = vec4(0.0);
+	frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 22b3ce51287f2d93836afce6d1a25fcc31391ec8..211057f972d6b4084b3823ac3156125f4ce5a31e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -275,6 +275,10 @@ extern BOOL gRandomizeFramerate;
 extern BOOL gPeriodicSlowFrame;
 extern BOOL gDebugGL;
 
+#if LL_DARWIN
+extern BOOL gHiDPISupport;
+#endif
+
 ////////////////////////////////////////////////////////////
 // All from the last globals push...
 
@@ -588,6 +592,10 @@ static void settings_to_globals()
 	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
 	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
 	LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
+	
+#if LL_DARWIN
+	gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
+#endif
 }
 
 static void settings_modify()
@@ -1137,38 +1145,38 @@ bool LLAppViewer::init()
 
     if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
     {
-        LLProcess::Params updater;
-        updater.desc = "updater process";
-        // Because it's the updater, it MUST persist beyond the lifespan of the
-        // viewer itself.
-        updater.autokill = false;
+		LLProcess::Params updater;
+		updater.desc = "updater process";
+		// Because it's the updater, it MUST persist beyond the lifespan of the
+		// viewer itself.
+		updater.autokill = false;
 #if LL_WINDOWS
-        updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
+		updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
 #elif LL_DARWIN
-        // explicitly run the system Python interpreter on SLVersionChecker.py
-        updater.executable = "python";
-        updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
+		// explicitly run the system Python interpreter on SLVersionChecker.py
+		updater.executable = "python";
+		updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
 #else
-        updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
+		updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
 #endif
-        // add LEAP mode command-line argument to whichever of these we selected
-        updater.args.add("leap");
-        // UpdaterServiceSettings
-        updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
-        // channel
-        updater.args.add(LLVersionInfo::getChannel());
-        // testok
-        updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
-        // ForceAddressSize
-        updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
-
-        // Run the updater. An exception from launching the updater should bother us.
-        LLLeap::create(updater, true);
-    }
-    else
-    {
-        LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
-    }
+		// add LEAP mode command-line argument to whichever of these we selected
+		updater.args.add("leap");
+		// UpdaterServiceSettings
+		updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+		// channel
+		updater.args.add(LLVersionInfo::getChannel());
+		// testok
+		updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
+		// ForceAddressSize
+		updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
+
+		// Run the updater. An exception from launching the updater should bother us.
+		LLLeap::create(updater, true);
+	}
+	else
+	{
+		LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
+	}
 
 	// Iterate over --leap command-line options. But this is a bit tricky: if
 	// there's only one, it won't be an array at all.
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index f0a0851b2e7272c0a257ca60780fa50fc7af8d03..4b6ddf153d54a71f3034f6f5fc49f672a1f03f4c 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -60,6 +60,7 @@ static U32 sShaderLevel = 0;
 LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
 BOOL	LLDrawPoolAvatar::sSkipOpaque = FALSE;
 BOOL	LLDrawPoolAvatar::sSkipTransparent = FALSE;
+S32     LLDrawPoolAvatar::sShadowPass = -1;
 S32 LLDrawPoolAvatar::sDiffuseChannel = 0;
 F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f;
 
@@ -429,19 +430,33 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
 
 S32 LLDrawPoolAvatar::getNumShadowPasses()
 {
-	return 2;
+    // avatars opaque, avatar alpha, avatar alpha mask, alpha attachments, alpha mask attachments, opaque attachments...
+	return NUM_SHADOW_PASSES;
 }
 
 void LLDrawPoolAvatar::beginShadowPass(S32 pass)
 {
 	LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
 
-	if (pass == 0)
+	if (pass == SHADOW_PASS_AVATAR_OPAQUE)
 	{
 		sVertexProgram = &gDeferredAvatarShadowProgram;
 		
-		//gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);		
+		if ((sShaderLevel > 0))  // for hardware blending
+		{
+			sRenderingSkinned = TRUE;
+			sVertexProgram->bind();
+		}
 
+		gGL.diffuseColor4f(1,1,1,1);
+	}
+    else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
+	{
+		sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
+
+        // bind diffuse tex so we can reference the alpha channel...
+        sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+		
 		if ((sShaderLevel > 0))  // for hardware blending
 		{
 			sRenderingSkinned = TRUE;
@@ -450,7 +465,52 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
 
 		gGL.diffuseColor4f(1,1,1,1);
 	}
-	else
+    else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
+	{
+		sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
+
+        // bind diffuse tex so we can reference the alpha channel...
+        sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+		
+		if ((sShaderLevel > 0))  // for hardware blending
+		{
+			sRenderingSkinned = TRUE;
+			sVertexProgram->bind();
+		}
+
+		gGL.diffuseColor4f(1,1,1,1);
+	}
+    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND)
+	{
+		sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
+
+        // bind diffuse tex so we can reference the alpha channel...
+        sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+		
+		if ((sShaderLevel > 0))  // for hardware blending
+		{
+			sRenderingSkinned = TRUE;
+			sVertexProgram->bind();
+		}
+
+		gGL.diffuseColor4f(1,1,1,1);
+	}
+    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK)
+	{
+		sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
+
+        // bind diffuse tex so we can reference the alpha channel...
+		sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
+		if ((sShaderLevel > 0))  // for hardware blending
+		{
+			sRenderingSkinned = TRUE;
+			sVertexProgram->bind();
+		}
+
+		gGL.diffuseColor4f(1,1,1,1);
+	}
+	else // SHADOW_PASS_ATTACHMENT_OPAQUE
 	{
 		sVertexProgram = &gDeferredAttachmentShadowProgram;
 		sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -461,20 +521,19 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
 void LLDrawPoolAvatar::endShadowPass(S32 pass)
 {
 	LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
-	if (pass == 0)
-	{
-		if (sShaderLevel > 0)
-		{
-			sRenderingSkinned = FALSE;
-			sVertexProgram->unbind();
-		}
-	}
-	else
+
+	if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE)
 	{
 		LLVertexBuffer::unbind();
+	}
+
+    if (sShaderLevel > 0)
+	{			
 		sVertexProgram->unbind();
-		sVertexProgram = NULL;
 	}
+    sVertexProgram = NULL;
+    sRenderingSkinned = FALSE;
+    LLDrawPoolAvatar::sShadowPass = -1;
 }
 
 void LLDrawPoolAvatar::renderShadow(S32 pass)
@@ -506,16 +565,67 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
 		return;
 	}
 	
-	if (pass == 0)
+    LLDrawPoolAvatar::sShadowPass = pass;
+
+	if (pass == SHADOW_PASS_AVATAR_OPAQUE)
 	{
+        LLDrawPoolAvatar::sSkipTransparent = true;
 		avatarp->renderSkinned();
+        LLDrawPoolAvatar::sSkipTransparent = false;
 	}
-	else
+    else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
 	{
-		for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
-		{
-			renderRigged(avatarp, i);
-		}
+        LLDrawPoolAvatar::sSkipOpaque = true;
+		avatarp->renderSkinned();
+        LLDrawPoolAvatar::sSkipOpaque = false;
+	}
+    else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
+	{
+        LLDrawPoolAvatar::sSkipOpaque = true;
+		avatarp->renderSkinned();
+        LLDrawPoolAvatar::sSkipOpaque = false;
+	}
+    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha
+	{
+        LLDrawPoolAvatar::sSkipOpaque = true;
+        renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
+        renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
+        renderRigged(avatarp, RIGGED_ALPHA);
+        renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
+        renderRigged(avatarp, RIGGED_GLOW);
+        renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
+        renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
+        renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
+        LLDrawPoolAvatar::sSkipOpaque = false;
+	}
+    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask
+	{
+        LLDrawPoolAvatar::sSkipOpaque = true;
+        renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
+        renderRigged(avatarp, RIGGED_NORMMAP_MASK);
+        renderRigged(avatarp, RIGGED_SPECMAP_MASK);
+		renderRigged(avatarp, RIGGED_NORMSPEC_MASK);    
+        renderRigged(avatarp, RIGGED_GLOW);
+        LLDrawPoolAvatar::sSkipOpaque = false;
+	}
+	else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE
+	{
+        LLDrawPoolAvatar::sSkipTransparent = true;
+		renderRigged(avatarp, RIGGED_MATERIAL);
+        renderRigged(avatarp, RIGGED_SPECMAP);
+		renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
+		renderRigged(avatarp, RIGGED_NORMMAP);		
+		renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
+		renderRigged(avatarp, RIGGED_NORMSPEC);
+		renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
+		renderRigged(avatarp, RIGGED_SIMPLE);
+		renderRigged(avatarp, RIGGED_FULLBRIGHT);
+		renderRigged(avatarp, RIGGED_SHINY);
+		renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
+		renderRigged(avatarp, RIGGED_GLOW);
+		renderRigged(avatarp, RIGGED_DEFERRED_BUMP);
+		renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE);
+        LLDrawPoolAvatar::sSkipTransparent = false;
 	}
 }
 
@@ -1830,6 +1940,13 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
 	{
 		LLFace* face = mRiggedFace[type][i];
+
+        S32 offset = face->getIndicesStart();
+		U32 count = face->getIndicesCount();
+
+        U16 start = face->getGeomStart();
+		U16 end = start + face->getGeomCount()-1;			
+
 		LLDrawable* drawable = face->getDrawable();
 		if (!drawable)
 		{
@@ -1868,8 +1985,89 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 		LLVertexBuffer* buff = face->getVertexBuffer();
 
+        const LLTextureEntry* tex_entry = face->getTextureEntry();
+		LLMaterial* mat = tex_entry ? tex_entry->getMaterialParams().get() : nullptr;
+
+        if (LLDrawPoolAvatar::sShadowPass >= 0)
+        {
+            bool is_alpha_blend = false;
+            bool is_alpha_mask  = false;
+
+            LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
+            if (tex)
+            {
+                if (tex->getIsAlphaMask())
+                {
+                    is_alpha_mask = true;
+                }
+            }
+
+            if (tex)
+            {
+                LLGLenum image_format = tex->getPrimaryFormat();
+                if (!is_alpha_mask && (image_format == GL_RGBA || image_format == GL_ALPHA))
+                {
+                    is_alpha_blend = true;
+                }
+            }
+
+            if (tex_entry)
+            {
+                if (tex_entry->getAlpha() <= 0.99f)
+                {
+                    is_alpha_blend = true;
+                }
+            }
+
+            if (mat)
+            {                
+                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode()))
+                {
+                    case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
+                    {
+                        is_alpha_mask  = true;
+                        is_alpha_blend = false;
+                    }
+                    break;
+
+                    case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
+                    {
+                        is_alpha_blend = true;
+                        is_alpha_mask  = false;
+                    }
+                    break;
+
+                    case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
+                    case LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT:
+                    case LLMaterial::DIFFUSE_ALPHA_MODE_NONE:
+                    default:
+                        is_alpha_blend = false;
+                        is_alpha_mask  = false;
+                        break;
+                }
+            }
+
+            // if this is alpha mask content and we're doing opaques or a non-alpha-mask shadow pass...
+            if (is_alpha_mask && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_MASK))
+            {
+                return;
+            }
+
+            // if this is alpha blend content and we're doing opaques or a non-alpha-blend shadow pass...
+            if (is_alpha_blend && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_BLEND))
+            {
+                return;
+            }
+
+            // if this is opaque content and we're skipping opaques...
+            if (!is_alpha_mask && !is_alpha_blend && LLDrawPoolAvatar::sSkipOpaque)
+            {
+                return;
+            }
+        }
+
 		if (buff)
-		{
+		{        
 			if (sShaderLevel > 0)
 			{
                 // upload matrix palette to shader
@@ -1915,19 +2113,11 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
 			}
 
-			U16 start = face->getGeomStart();
-			U16 end = start + face->getGeomCount()-1;
-			S32 offset = face->getIndicesStart();
-			U32 count = face->getIndicesCount();
-
 			/*if (glow)
 			{
 				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
 			}*/
 
-			const LLTextureEntry* te = face->getTextureEntry();
-			LLMaterial* mat = te->getMaterialParams().get();
-
 			if (mat)
 			{
 				//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change 
@@ -1958,12 +2148,12 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 				if (mat->getSpecularID().isNull())
 				{
-					env = te->getShiny()*0.25f;
+					env = tex_entry->getShiny()*0.25f;
 					col.set(env,env,env,0);
 					spec = env;
 				}
 		
-				BOOL fullbright = te->getFullbright();
+				BOOL fullbright = tex_entry->getFullbright();
 
 				sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
 				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
@@ -1971,7 +2161,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 				{
-					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
+                    F32 cutoff = mat->getAlphaMaskCutoff()/255.f;
+					sVertexProgram->setMinimumAlpha(cutoff);
 				}
 				else
 				{
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 8292279042027da803784d83d50a4eef6336ce6a..3392381e117d072f46d39d603a7baad775c8cb4e 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -55,107 +55,12 @@ class LLDrawPoolAvatar : public LLFacePool
 							LLVertexBuffer::MAP_CLOTHWEIGHT
 	};
 
-	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
-
-	virtual S32 getShaderLevel() const;
-
-	LLDrawPoolAvatar();
     ~LLDrawPoolAvatar();
     /*virtual*/ BOOL isDead();
 
-	static LLMatrix4& getModelView();
-
-	/*virtual*/ LLDrawPool *instancePool();
-
-	/*virtual*/ S32  getNumPasses();
-	/*virtual*/ void beginRenderPass(S32 pass);
-	/*virtual*/ void endRenderPass(S32 pass);
-	/*virtual*/ void prerender();
-	/*virtual*/ void render(S32 pass = 0);
-
-	/*virtual*/ S32 getNumDeferredPasses();
-	/*virtual*/ void beginDeferredPass(S32 pass);
-	/*virtual*/ void endDeferredPass(S32 pass);
-	/*virtual*/ void renderDeferred(S32 pass);
-	
-	/*virtual*/ S32 getNumPostDeferredPasses();
-	/*virtual*/ void beginPostDeferredPass(S32 pass);
-	/*virtual*/ void endPostDeferredPass(S32 pass);
-	/*virtual*/ void renderPostDeferred(S32 pass);
-
-	/*virtual*/ S32 getNumShadowPasses();
-	/*virtual*/ void beginShadowPass(S32 pass);
-	/*virtual*/ void endShadowPass(S32 pass);
-	/*virtual*/ void renderShadow(S32 pass);
-
-	void beginRigid();
-	void beginImpostor();
-	void beginSkinned();
-	
-	void endRigid();
-	void endImpostor();
-	void endSkinned();
+    virtual S32 getShaderLevel() const;
 
-	void beginDeferredImpostor();
-	void beginDeferredRigid();
-	void beginDeferredSkinned();
-	
-	void endDeferredImpostor();
-	void endDeferredRigid();
-	void endDeferredSkinned();
-	
-	void beginPostDeferredAlpha();
-	void endPostDeferredAlpha();
-
-	void beginRiggedSimple();
-	void beginRiggedFullbright();
-	void beginRiggedFullbrightShiny();
-	void beginRiggedShinySimple();
-	void beginRiggedAlpha();
-	void beginRiggedFullbrightAlpha();
-	void beginRiggedGlow();
-	void beginDeferredRiggedAlpha();
-	void beginDeferredRiggedMaterial(S32 pass);
-	void beginDeferredRiggedMaterialAlpha(S32 pass);
-
-	void endRiggedSimple();
-	void endRiggedFullbright();
-	void endRiggedFullbrightShiny();
-	void endRiggedShinySimple();
-	void endRiggedAlpha();
-	void endRiggedFullbrightAlpha();
-	void endRiggedGlow();
-	void endDeferredRiggedAlpha();
-	void endDeferredRiggedMaterial(S32 pass);
-	void endDeferredRiggedMaterialAlpha(S32 pass);
-
-	void beginDeferredRiggedSimple();
-	void beginDeferredRiggedBump();
-	
-	void endDeferredRiggedSimple();
-	void endDeferredRiggedBump();
-		
-	void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
-	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
-									  LLFace* facep, 
-									  const LLMeshSkinInfo* skin, 
-									  LLVolume* volume,
-									  const LLVolumeFace& vol_face);
-	void updateRiggedVertexBuffers(LLVOAvatar* avatar);
-
-	void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
-	void renderRiggedSimple(LLVOAvatar* avatar);
-	void renderRiggedAlpha(LLVOAvatar* avatar);
-	void renderRiggedFullbrightAlpha(LLVOAvatar* avatar);
-	void renderRiggedFullbright(LLVOAvatar* avatar);
-	void renderRiggedShinySimple(LLVOAvatar* avatar);
-	void renderRiggedFullbrightShiny(LLVOAvatar* avatar);
-	void renderRiggedGlow(LLVOAvatar* avatar);
-	void renderDeferredRiggedSimple(LLVOAvatar* avatar);
-	void renderDeferredRiggedBump(LLVOAvatar* avatar);
-	void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
-	
-	typedef enum
+    typedef enum
 	{
 		RIGGED_MATERIAL=0,
 		RIGGED_MATERIAL_ALPHA,
@@ -260,6 +165,117 @@ class LLDrawPoolAvatar : public LLFacePool
 							 LLVertexBuffer::MAP_WEIGHT4,
 	} eRiggedDataMask;
 
+typedef enum
+	{
+		SHADOW_PASS_AVATAR_OPAQUE,
+        SHADOW_PASS_AVATAR_ALPHA_BLEND,
+        SHADOW_PASS_AVATAR_ALPHA_MASK,
+        SHADOW_PASS_ATTACHMENT_ALPHA_BLEND,
+        SHADOW_PASS_ATTACHMENT_ALPHA_MASK,
+        SHADOW_PASS_ATTACHMENT_OPAQUE,
+        NUM_SHADOW_PASSES
+	} eShadowPass;
+
+	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+	virtual S32 getVertexShaderLevel() const;
+
+	LLDrawPoolAvatar();
+
+	static LLMatrix4& getModelView();
+
+	/*virtual*/ LLDrawPool *instancePool();
+
+	/*virtual*/ S32  getNumPasses();
+	/*virtual*/ void beginRenderPass(S32 pass);
+	/*virtual*/ void endRenderPass(S32 pass);
+	/*virtual*/ void prerender();
+	/*virtual*/ void render(S32 pass = 0);
+
+	/*virtual*/ S32 getNumDeferredPasses();
+	/*virtual*/ void beginDeferredPass(S32 pass);
+	/*virtual*/ void endDeferredPass(S32 pass);
+	/*virtual*/ void renderDeferred(S32 pass);
+	
+	/*virtual*/ S32 getNumPostDeferredPasses();
+	/*virtual*/ void beginPostDeferredPass(S32 pass);
+	/*virtual*/ void endPostDeferredPass(S32 pass);
+	/*virtual*/ void renderPostDeferred(S32 pass);
+
+	/*virtual*/ S32 getNumShadowPasses();
+	/*virtual*/ void beginShadowPass(S32 pass);
+	/*virtual*/ void endShadowPass(S32 pass);
+	/*virtual*/ void renderShadow(S32 pass);
+
+	void beginRigid();
+	void beginImpostor();
+	void beginSkinned();
+	
+	void endRigid();
+	void endImpostor();
+	void endSkinned();
+
+	void beginDeferredImpostor();
+	void beginDeferredRigid();
+	void beginDeferredSkinned();
+	
+	void endDeferredImpostor();
+	void endDeferredRigid();
+	void endDeferredSkinned();
+	
+	void beginPostDeferredAlpha();
+	void endPostDeferredAlpha();
+
+	void beginRiggedSimple();
+	void beginRiggedFullbright();
+	void beginRiggedFullbrightShiny();
+	void beginRiggedShinySimple();
+	void beginRiggedAlpha();
+	void beginRiggedFullbrightAlpha();
+	void beginRiggedGlow();
+	void beginDeferredRiggedAlpha();
+	void beginDeferredRiggedMaterial(S32 pass);
+	void beginDeferredRiggedMaterialAlpha(S32 pass);
+
+	void endRiggedSimple();
+	void endRiggedFullbright();
+	void endRiggedFullbrightShiny();
+	void endRiggedShinySimple();
+	void endRiggedAlpha();
+	void endRiggedFullbrightAlpha();
+	void endRiggedGlow();
+	void endDeferredRiggedAlpha();
+	void endDeferredRiggedMaterial(S32 pass);
+	void endDeferredRiggedMaterialAlpha(S32 pass);
+
+	void beginDeferredRiggedSimple();
+	void beginDeferredRiggedBump();
+	
+	void endDeferredRiggedSimple();
+	void endDeferredRiggedBump();
+		
+	void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
+	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
+									  LLFace* facep, 
+									  const LLMeshSkinInfo* skin, 
+									  LLVolume* volume,
+									  const LLVolumeFace& vol_face);
+	void updateRiggedVertexBuffers(LLVOAvatar* avatar);
+
+	void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
+	void renderRiggedSimple(LLVOAvatar* avatar);
+	void renderRiggedAlpha(LLVOAvatar* avatar);
+	void renderRiggedFullbrightAlpha(LLVOAvatar* avatar);
+	void renderRiggedFullbright(LLVOAvatar* avatar);
+	void renderRiggedShinySimple(LLVOAvatar* avatar);
+	void renderRiggedFullbrightShiny(LLVOAvatar* avatar);
+	void renderRiggedGlow(LLVOAvatar* avatar);
+	void renderDeferredRiggedSimple(LLVOAvatar* avatar);
+	void renderDeferredRiggedBump(LLVOAvatar* avatar);
+	void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
+	
+	
+
 	void addRiggedFace(LLFace* facep, U32 type);
 	void removeRiggedFace(LLFace* facep); 
 
@@ -273,6 +289,7 @@ class LLDrawPoolAvatar : public LLFacePool
 
 	static BOOL sSkipOpaque;
 	static BOOL sSkipTransparent;
+    static S32  sShadowPass;
 	static S32 sDiffuseChannel;
 	static F32 sMinimumAlpha;
 
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index e676b8d9f906171c21e6eb81ffe0ab071def31a1..b5b2fd5e00d22a155492fcae0841a4c5a89935ab 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -213,7 +213,7 @@ void LLDrawPoolTerrain::render(S32 pass)
 	// Special-case for land ownership feedback
 	if (gSavedSettings.getBOOL("ShowParcelOwners"))
 	{
-		hilightParcelOwners();
+		hilightParcelOwners(false);
 	}
 }
 
@@ -443,13 +443,13 @@ void LLDrawPoolTerrain::renderFullShader()
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
-void LLDrawPoolTerrain::hilightParcelOwners()
+void LLDrawPoolTerrain::hilightParcelOwners(bool deferred)
 {
 	if (mShaderLevel > 1)
 	{ //use fullbright shader for highlighting
 		LLGLSLShader* old_shader = sShader;
 		sShader->unbind();
-		sShader = &gHighlightProgram;
+		sShader = deferred ? &gDeferredHighlightProgram : &gHighlightProgram;
 		sShader->bind();
 		gGL.diffuseColor4f(1, 1, 1, 1);
 		LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index b4ef7881a8adee1b820dc4fe1468dae8ba88e6bf..04e27d9370ed4dd05309450a0e8a5eceebb441f0 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -89,7 +89,7 @@ class LLDrawPoolTerrain : public LLFacePool
 	void drawLoop();
 
 private:
-	void hilightParcelOwners();
+	void hilightParcelOwners(bool deferred);
 };
 
 #endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 6d0e99984554a1ced0e619384dfc9b11e0d03f6c..ad1df2b0e3c2c145ff7badf3676844b2cad108b2 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -36,6 +36,8 @@
 #include "llmatrix4a.h"
 #include "v3color.h"
 
+#include "lldefs.h"
+
 #include "lldrawpoolavatar.h"
 #include "lldrawpoolbump.h"
 #include "llgl.h"
@@ -610,6 +612,129 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 }
 
 
+void renderFace(LLDrawable* drawable, LLFace *face)
+{
+    LLVOVolume* vobj = drawable->getVOVolume();
+    if (vobj)
+    {
+        LLVertexBuffer::unbind();
+        gGL.pushMatrix();
+        gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix);
+
+        LLVolume* volume = NULL;
+
+        if (drawable->isState(LLDrawable::RIGGED))
+        {
+            vobj->updateRiggedVolume();
+            volume = vobj->getRiggedVolume();
+        }
+        else
+        {
+            volume = vobj->getVolume();
+        }
+
+        if (volume)
+        {
+            const LLVolumeFace& vol_face = volume->getVolumeFace(face->getTEOffset());
+            LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mPositions, NULL, vol_face.mNumIndices, vol_face.mIndices);
+        }
+
+        gGL.popMatrix();
+    }
+}
+
+void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections)
+{
+    //Need to because crash on ATI 3800 (and similar cards) MAINT-5018 
+    LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+    LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+    if (shader)
+    {
+        gDebugProgram.bind();
+    }
+
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.pushMatrix();
+
+    BOOL is_hud_object = mVObjp->isHUDAttachment();
+
+    if (mDrawablep->isActive())
+    {
+        gGL.loadMatrix(gGLModelView);
+        gGL.multMatrix((F32*)mVObjp->getRenderMatrix().mMatrix);
+    }
+    else if (!is_hud_object)
+    {
+        gGL.loadIdentity();
+        gGL.multMatrix(gGLModelView);
+        LLVector3 trans = mVObjp->getRegion()->getOriginAgent();
+        gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+    }
+
+    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+
+    if (bRenderHiddenSelections)
+    {
+        gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
+        LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
+        if (shader)
+        {
+            gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+            renderFace(mDrawablep, this);
+        }
+        else
+        {
+            LLGLEnable fog(GL_FOG);
+            glFogi(GL_FOG_MODE, GL_LINEAR);
+            float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
+            LLColor4 fogCol = color * fogCfx;
+            glFogf(GL_FOG_START, d);
+            glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+            glFogfv(GL_FOG_COLOR, fogCol.mV);
+
+            gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+            {
+                gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+                renderFace(mDrawablep, this);
+            }
+        }
+    }
+
+    gGL.flush();
+    gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+    gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, color.mV[VALPHA]);
+
+    {
+        LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
+        LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+
+        if (!wireframe_selection)
+        { //modify wireframe into outline selection mode
+            glStencilFunc(GL_NOTEQUAL, 2, 0xffff);
+            glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+        }
+
+        LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+        glPolygonOffset(3.f, 3.f);
+        glLineWidth(5.f);
+        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+        renderFace(mDrawablep, this);
+    }
+
+    glLineWidth(1.f);
+    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    gGL.popMatrix();
+
+    if (shader)
+    {
+        shader->bind();
+    }
+}
+
 /* removed in lieu of raycast uv detection
 void LLFace::renderSelectedUV()
 {
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 8531df856105960b1df02e0d7dfebee313b3f86f..5a217411da5e791f079b073011d483e11ee47ec2 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -199,6 +199,7 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16>
 	void		renderSelectedUV();
 
 	void		renderSelected(LLViewerTexture *image, const LLColor4 &color);
+	void		renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections);
 
 	F32			getKey()					const	{ return mDistance; }
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 55796b1e7fcafe4e7edb2333f417aa8a22b10ef4..13f9b9a0b5554d95a26f4bdf3860ea36bb4d1c1b 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2781,6 +2781,9 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
         combo->remove("8x");
         combo->remove("16x");
     }
+	
+	LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
+	use_HiDPI->setVisible(FALSE);
 #endif
 
     return TRUE;
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 73120a02425f17dda97580b892b7d5331e582773..f46152dcec96844d9bc88f66f15f07db2e1261dd 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -495,6 +495,8 @@ void LLHUDEffectLookAt::render()
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
+		LLGLDisable gls_stencil(GL_STENCIL_TEST);
+
 		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index 44c8db19c0308f90f52ac3fac4c9abe9ebd9e302..cc772c8f5c0aa2f1e11afc0a576bf2215e02ddbb 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -322,6 +322,7 @@ void LLHUDEffectPointAt::render()
 	update();
 	if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
 	{
+		LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 825c2b31bef19382ed6ba6053e76c04ccf37814f..85a878c4a2f1586ef160c9111aa795f3841cf77d 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -80,6 +80,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
 {
 	LLGLSUIDefault texture_state;
 	LLGLDepthTest gls_depth(GL_TRUE);
+	LLGLDisable gls_stencil(GL_STENCIL_TEST);
 	if (for_select)
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index c7d108b6deea7e22684257956e7173af31d41485..81d862a82765ea3a669db7e739bdcd0872188de5 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -224,6 +224,7 @@ void LLHUDNameTag::render()
 	if (sDisplayText)
 	{
 		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+		LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		renderText(FALSE);
 	}
 }
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 486e077b9bd3e280a300c7651c6bcc0eaee8006f..82824861a9f901e52d870149ff1c9af6882bfd5b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -102,6 +102,7 @@ void LLHUDText::render()
 	if (!mOnHUDAttachment && sDisplayText)
 	{
 		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+		LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		renderText();
 	}
 }
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 126c6be388b5777f88f542490d2474ef2c4f367a..df040d8f13afe7d687624d4bd2579fe5ab2b4cd1 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -113,6 +113,11 @@ void LLLoginInstance::connect(LLPointer<LLCredential> credentials)
 {
 	std::vector<std::string> uris;
 	LLGridManager::getInstance()->getLoginURIs(uris);
+    if (uris.size() < 1)
+    {
+        LL_WARNS() << "Failed to get login URIs during connect. No connect for you!" << LL_ENDL;
+        return;
+    }
 	connect(uris.front(), credentials);
 }
 
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 8d7865c8ba641c217f2b1a2da9424ba4bb15b6cc..5e6a44c09da11b603ac3a2c890391d17475337b3 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -444,14 +444,17 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
 		LLSpinCtrl*	ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
 		LLSpinCtrl*	ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
 		LLSpinCtrl*	ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
-		LLComboBox*		comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
+		LLComboBox*	comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
+		LLCheckBoxCtrl*	cb_planar_align = mPanel->getChild<LLCheckBoxCtrl>("checkbox planar align");
+		bool align_planar = (cb_planar_align && cb_planar_align->get());
+
 		llassert(comboTexGen);
 		llassert(object);
 
 		if (ctrlTexScaleS)
 		{
 			valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
-			if (valid)
+			if (valid || align_planar)
 			{
 				value = ctrlTexScaleS->get();
 				if (comboTexGen &&
@@ -460,13 +463,19 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
 					value *= 0.5f;
 				}
 				object->setTEScaleS( te, value );
+
+				if (align_planar) 
+				{
+					LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te);
+					LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te);
+				}
 			}
 		}
 
 		if (ctrlTexScaleT)
 		{
 			valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
-			if (valid)
+			if (valid || align_planar)
 			{
 				value = ctrlTexScaleT->get();
 				//if( checkFlipScaleT->get() )
@@ -479,36 +488,60 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
 					value *= 0.5f;
 				}
 				object->setTEScaleT( te, value );
+
+				if (align_planar) 
+				{
+					LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te);
+					LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te);
+				}
 			}
 		}
 
 		if (ctrlTexOffsetS)
 		{
 			valid = !ctrlTexOffsetS->getTentative();
-			if (valid)
+			if (valid || align_planar)
 			{
 				value = ctrlTexOffsetS->get();
 				object->setTEOffsetS( te, value );
+
+				if (align_planar) 
+				{
+					LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te);
+					LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te);
+				}
 			}
 		}
 
 		if (ctrlTexOffsetT)
 		{
 			valid = !ctrlTexOffsetT->getTentative();
-			if (valid)
+			if (valid || align_planar)
 			{
 				value = ctrlTexOffsetT->get();
 				object->setTEOffsetT( te, value );
+
+				if (align_planar) 
+				{
+					LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te);
+					LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te);
+				}
 			}
 		}
 
 		if (ctrlTexRotation)
 		{
 			valid = !ctrlTexRotation->getTentative();
-			if (valid)
+			if (valid || align_planar)
 			{
 				value = ctrlTexRotation->get() * DEG_TO_RAD;
 				object->setTERotation( te, value );
+
+				if (align_planar) 
+				{
+					LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te);
+					LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te);
+				}
 			}
 		}
 		return true;
@@ -552,6 +585,19 @@ struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor
 				object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
 				object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
 				object->setTERotation(te, uv_rot);
+
+				LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID());
+
+				LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
+
+				LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
+				LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
 			}
 		}
 		if (!set_aligned)
@@ -599,12 +645,19 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
 			tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
 			tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
 			F32 st_rot = tep->getRotation();
+
+            bool eq_offset_x = is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12);
+            bool eq_offset_y = is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12);
+            bool eq_scale_x  = is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12);
+            bool eq_scale_y  = is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12);
+            bool eq_rot      = is_approx_equal_fraction(st_rot, aligned_st_rot, 6);
+
 			// needs a fuzzy comparison, because of fp errors
-			if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12) && 
-				is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12) && 
-				is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12) &&
-				is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12) &&
-				is_approx_equal_fraction(st_rot, aligned_st_rot, 14))
+			if (eq_offset_x && 
+				eq_offset_y && 
+				eq_scale_x &&
+				eq_scale_y &&
+				eq_rot)
 			{
 				return true;
 			}
@@ -968,9 +1021,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 			F32 spec_scale_s = 1.f;
 			F32 norm_scale_s = 1.f;
 
-			LLSelectedTE::getScaleS(						diff_scale_s, identical_diff_scale_s);			
-			LLSelectedTEMaterial::getSpecularRepeatX( spec_scale_s, identical_spec_scale_s);
-			LLSelectedTEMaterial::getNormalRepeatX(	norm_scale_s, identical_norm_scale_s);
+			LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s);			
+			LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s);
+			LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s);
 
 			diff_scale_s = editable ? diff_scale_s : 1.0f;
 			diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
@@ -2056,10 +2109,10 @@ void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata)
 }
 
 //static
-void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot)
+void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot, int te)
 {
-	LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD);
-	LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD);
+	LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD, te);
+	LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD, te);
 	self->sendTextureInfo();
 }
 
@@ -2437,7 +2490,7 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical
 			return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
 		}
 	} get_te_face_func;
-	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return);
+	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr);
 }
 
 void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face)
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 7c084cb0abea07d1632c583a70bb4bb5298d981e..0b40d7d41a124d27ce8ce96f2598e9f064c4be14 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -179,7 +179,7 @@ class LLPanelFace : public LLPanel
 	static void		syncRepeatY(LLPanelFace* self, F32 scaleV);
 	static void		syncOffsetX(LLPanelFace* self, F32 offsetU);
 	static void		syncOffsetY(LLPanelFace* self, F32 offsetV);
-	static void 	syncMaterialRot(LLPanelFace* self, F32 rot);
+	static void 	syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1);
 
 	static void		onCommitMaterialShinyScaleX(	LLUICtrl* ctrl, void* userdata);
 	static void		onCommitMaterialShinyScaleY(	LLUICtrl* ctrl, void* userdata);
@@ -252,16 +252,16 @@ class LLPanelFace : public LLPanel
 		typename DataType,
 		typename SetValueType,
 		void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
-	static void edit(LLPanelFace* p, DataType data)
+	static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID())
 	{
 		LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data);
 		struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor
 		{
-			LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {}
+			LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {}
 			virtual ~LLSelectedTEEditMaterial() {};
 			virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material)
 			{
-				if (_edit)
+				if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID()))
 				{
 					LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material);
 					llassert_always(new_material);
@@ -325,16 +325,17 @@ class LLPanelFace : public LLPanel
 				return NULL;
 			}
 			LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >*	_edit;
-			LLPanelFace*																			_panel;
-		} editor(p, &edit);
-		LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor);
+			LLPanelFace *_panel;
+			const LLUUID & _only_for_object_id;
+		} editor(p, &edit, only_for_object_id);
+		LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te);
 	}
 
 	template<
 		typename DataType,
 		typename ReturnType,
 		ReturnType (LLMaterial::* const MaterialGetFunc)() const  >
-	static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value)
+	static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())
 	{
 		DataType data_value;
 		struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType>
@@ -359,7 +360,7 @@ class LLPanelFace : public LLPanel
 			}
 			DataType _default;
 		} GetFunc(default_value);
-		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value);
+		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance);
 		data_to_return = data_value;
 	}
 
@@ -367,7 +368,7 @@ class LLPanelFace : public LLPanel
 		typename DataType,
 		typename ReturnType, // some kids just have to different...
 		ReturnType (LLTextureEntry::* const TEGetFunc)() const >
-	static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value)
+	static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())
 	{
 		DataType data_value;
 		struct GetTEVal : public LLSelectedTEGetFunctor<DataType>
@@ -381,7 +382,7 @@ class LLPanelFace : public LLPanel
 			}
 			DataType _default;
 		} GetTEValFunc(default_value);
-		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value );
+		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance );
 		data_to_return = data_value;
 	}
 
@@ -414,6 +415,7 @@ class LLPanelFace : public LLPanel
 	bool mUpdateInFlight;
 	bool mUpdatePending;
 
+public:
 	#if defined(DEF_GET_MAT_STATE)
 		#undef DEF_GET_MAT_STATE
 	#endif
@@ -426,29 +428,29 @@ class LLPanelFace : public LLPanel
 		DEF_EDIT_MAT_STATE
 	#endif
 
-	// Accessors for selected TE material state
-	//
-	#define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue)												\
-		static void MaterialMemberFunc(DataType& data, bool& identical)																\
-		{																																					\
-			getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue);	\
-		}
-
-	// Mutators for selected TE material
-	//
-	#define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc)																\
-		static void MaterialMemberFunc(LLPanelFace* p,DataType data)																	\
-		{																																					\
-			edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data);													\
-		}
-
-	// Accessors for selected TE state proper (legacy settings etc)
-	//
-	#define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue)													\
-		static void TexEntryMemberFunc(DataType& data, bool& identical)																\
-		{																																					\
-			getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue);		\
-		}
+    // Accessors for selected TE material state
+    //
+    #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue,HasTolerance,Tolerance)                                           \
+        static void MaterialMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance)          \
+        {                                                                                                                                           \
+            getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance);   \
+        }
+
+    // Mutators for selected TE material
+    //
+    #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc)                                                              \
+        static void MaterialMemberFunc(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID())     \
+        {                                                                                                                           \
+            edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p, data, te, only_for_object_id);                         \
+        }
+
+    // Accessors for selected TE state proper (legacy settings etc)
+    //
+    #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue,HasTolerance,Tolerance)                                        \
+        static void TexEntryMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance)      \
+        {                                                                                                                                       \
+            getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance);   \
+        }
 
 	class LLSelectedTEMaterial
 	{
@@ -458,19 +460,19 @@ class LLPanelFace : public LLPanel
 		static void getMaxNormalRepeats(F32& repeats, bool& identical);
 		static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha);
 
-		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null)
-		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null)
-		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f)
-		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f)
-		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f)
-		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f)
-		DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f)
+		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null)
+		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null)
+		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f)
 
-		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f)
-		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f)
-		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f)
-		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f)
-		DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f)
+		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f)
+		DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f)
 
 		DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode);
 		DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff);
@@ -506,17 +508,17 @@ class LLPanelFace : public LLPanel
 		static void getObjectScaleT(F32& scale_t, bool& identical);
 		static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
 
-		DEF_GET_TE_STATE(U8,U8,getBumpmap,0)
-		DEF_GET_TE_STATE(U8,U8,getShiny,0)
-		DEF_GET_TE_STATE(U8,U8,getFullbright,0)
-		DEF_GET_TE_STATE(F32,F32,getRotation,0.0f)
-		DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f)
-		DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f)
-		DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f)
-		DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f)
-		DEF_GET_TE_STATE(F32,F32,getGlow,0.0f)
-		DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT)
-		DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white)		
+		DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0)
+		DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0)
+		DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0)
+		DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f)
+		DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f)
+		DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f)
+		DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f)
+		DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f)
+		DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f)
+		DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT)
+		DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black);
 	};
 };
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 4a2d545b332cd534b1618ef1a008363a64937d87..b36df244f875f9ca6614da66622188e1c0a38146 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -2089,29 +2089,33 @@ void LLSelectMgr::selectionSetGlow(F32 glow)
 	mSelectedObjects->applyToObjects( &func2 );
 }
 
-void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func)
+void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int te)
 {
 	struct f1 : public LLSelectedTEFunctor
 	{
 		LLMaterialPtr mMaterial;
-		f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {}
+		f1(LLSelectedTEMaterialFunctor* material_func, int te) : _material_func(material_func), _specific_te(te) {}
 
-		bool apply(LLViewerObject* object, S32 face)
+		bool apply(LLViewerObject* object, S32 te)
 		{
-			if (object && object->permModify() && _material_func)
-			{
-				LLTextureEntry* tep = object->getTE(face);
-				if (tep)
-				{
-					LLMaterialPtr current_material = tep->getMaterialParams();
-					_material_func->apply(object, face, tep, current_material);
-				}
-			}
+            if (_specific_te == -1 || (te == _specific_te))
+            {
+			    if (object && object->permModify() && _material_func)
+			    {
+				    LLTextureEntry* tep = object->getTE(te);
+				    if (tep)
+				    {
+					    LLMaterialPtr current_material = tep->getMaterialParams();
+					    _material_func->apply(object, te, tep, current_material);
+				    }
+			    }
+            }
 			return true;
 		}
 
 		LLSelectedTEMaterialFunctor* _material_func;
-	} func1(material_func);
+        int _specific_te;
+	} func1(material_func, te);
 	mSelectedObjects->applyToTEs( &func1 );
 
 	struct f2 : public LLSelectedObjectFunctor
@@ -5833,6 +5837,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 		gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
 		gGL.scalef(cur_zoom, cur_zoom, cur_zoom);
 	}
+
 	if (mSelectedObjects->getNumNodes())
 	{
 		LLUUID inspect_item_id= LLUUID::null;
@@ -5850,6 +5855,9 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 			}
 		}
 
+		bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections;
+		F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
+
 		LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID();
 		for (S32 pass = 0; pass < 2; pass++)
 		{
@@ -5860,35 +5868,63 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 				LLViewerObject* objectp = node->getObject();
 				if (!objectp)
 					continue;
-				if (objectp->isHUDAttachment() != for_hud)
-				{
-					continue;
-				}
-				if (objectp->getID() == focus_item_id)
-				{
-					node->renderOneSilhouette(gFocusMgr.getFocusColor());
-				}
-				else if(objectp->getID() == inspect_item_id)
-				{
-					node->renderOneSilhouette(sHighlightInspectColor);
-				}
-				else if (node->isTransient())
-				{
-					BOOL oldHidden = LLSelectMgr::sRenderHiddenSelections;
-					LLSelectMgr::sRenderHiddenSelections = FALSE;
-					node->renderOneSilhouette(sContextSilhouetteColor);
-					LLSelectMgr::sRenderHiddenSelections = oldHidden;
-				}
-				else if (objectp->isRootEdit())
-				{
-					node->renderOneSilhouette(sSilhouetteParentColor);
-				}
-				else
-				{
-					node->renderOneSilhouette(sSilhouetteChildColor);
-				}
-			}
-		}
+
+                if(getTEMode() && !node->hasSelectedTE()) 
+                    continue;
+
+                if (objectp->mDrawable 
+                    && objectp->mDrawable->getVOVolume() 
+                    && objectp->mDrawable->getVOVolume()->isMesh())
+                {
+                    S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
+                    for (S32 te = 0; te < num_tes; ++te)
+                    {
+                        if (!getTEMode())
+                        {
+                            objectp->mDrawable->getFace(te)->renderOneWireframe(
+                                LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha * 2)
+                                , fogCfx, wireframe_selection, node->isTransient() ? FALSE : LLSelectMgr::sRenderHiddenSelections);
+                        }
+                        else if(node->isTESelected(te))
+                        {
+                            objectp->mDrawable->getFace(te)->renderOneWireframe(
+                                LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha * 2)
+                                , fogCfx, wireframe_selection, node->isTransient() ? FALSE : LLSelectMgr::sRenderHiddenSelections);
+                        }
+                    }
+                }
+                else
+                {
+                    if (objectp->isHUDAttachment() != for_hud)
+                    {
+                        continue;
+                    }
+                    if (objectp->getID() == focus_item_id)
+                    {
+                        node->renderOneSilhouette(gFocusMgr.getFocusColor());
+                    }
+                    else if (objectp->getID() == inspect_item_id)
+                    {
+                        node->renderOneSilhouette(sHighlightInspectColor);
+                    }
+                    else if (node->isTransient())
+                    {
+                        BOOL oldHidden = LLSelectMgr::sRenderHiddenSelections;
+                        LLSelectMgr::sRenderHiddenSelections = FALSE;
+                        node->renderOneSilhouette(sContextSilhouetteColor);
+                        LLSelectMgr::sRenderHiddenSelections = oldHidden;
+                    }
+                    else if (objectp->isRootEdit())
+                    {
+                        node->renderOneSilhouette(sSilhouetteParentColor);
+                    }
+                    else
+                    {
+                        node->renderOneSilhouette(sSilhouetteChildColor);
+                    }
+                }
+			} //for all selected node's
+		} //for pass
 	}
 
 	if (mHighlightedObjects->getNumNodes())
@@ -6052,7 +6088,7 @@ void LLSelectNode::selectTE(S32 te_index, BOOL selected)
 	mLastTESelected = te_index;
 }
 
-BOOL LLSelectNode::isTESelected(S32 te_index)
+BOOL LLSelectNode::isTESelected(S32 te_index) const
 {
 	if (te_index < 0 || te_index >= mObject->getNumTEs())
 	{
@@ -6061,7 +6097,7 @@ BOOL LLSelectNode::isTESelected(S32 te_index)
 	return (mTESelectMask & (0x1 << te_index)) != 0;
 }
 
-S32 LLSelectNode::getLastSelectedTE()
+S32 LLSelectNode::getLastSelectedTE() const
 {
 	if (!isTESelected(mLastTESelected))
 	{
@@ -6070,11 +6106,6 @@ S32 LLSelectNode::getLastSelectedTE()
 	return mLastTESelected;
 }
 
-S32 LLSelectNode::getLastOperatedTE()
-{
-	return mLastTESelected;
-}
-
 LLViewerObject* LLSelectNode::getObject()
 {
 	if (!mObject)
@@ -6274,148 +6305,6 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)
 	return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));
 }
 
-
-//helper function for pushing relevant vertices from drawable to GL
-void pushWireframe(LLDrawable* drawable)
-{
-	LLVOVolume* vobj = drawable->getVOVolume();
-	if (vobj)
-	{
-		LLVertexBuffer::unbind();
-		gGL.pushMatrix();
-		gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
-
-		LLVolume* volume = NULL;
-
-		if (drawable->isState(LLDrawable::RIGGED))
-		{
-				vobj->updateRiggedVolume();
-				volume = vobj->getRiggedVolume();
-		}
-		else
-		{
-			volume = vobj->getVolume();
-		}
-
-		if (volume)
-		{
-			for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
-			{
-				const LLVolumeFace& face = volume->getVolumeFace(i);
-				LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
-			}
-		}
-
-		gGL.popMatrix();
-	}
-	
-}
-
-void LLSelectNode::renderOneWireframe(const LLColor4& color)
-{
-    //Need to because crash on ATI 3800 (and similar cards) MAINT-5018 
-    LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
-    LLViewerObject* objectp = getObject();
-    if (!objectp)
-    {
-        return;
-    }
-
-    LLDrawable* drawable = objectp->mDrawable;
-    if (!drawable)
-    {
-        return;
-    }
-
-    LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
-    if (shader)
-    {
-        gDebugProgram.bind();
-    }
-
-    gGL.matrixMode(LLRender::MM_MODELVIEW);
-    gGL.pushMatrix();
-
-    BOOL is_hud_object = objectp->isHUDAttachment();
-
-    if (drawable->isActive())
-    {
-        gGL.loadMatrix(gGLModelView);
-        gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix);
-    }
-    else if (!is_hud_object)
-    {
-        gGL.loadIdentity();
-        gGL.multMatrix(gGLModelView);
-        LLVector3 trans = objectp->getRegion()->getOriginAgent();
-        gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
-    }
-
-    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
-    if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
-    {
-        gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
-        LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
-        if (shader)
-        {
-            gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
-            pushWireframe(drawable);
-        }
-        else
-        {
-            LLGLEnable fog(GL_FOG);
-            glFogi(GL_FOG_MODE, GL_LINEAR);
-            float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
-            LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
-            glFogf(GL_FOG_START, d);
-            glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
-            glFogfv(GL_FOG_COLOR, fogCol.mV);
-
-            gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-            {
-                gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
-                pushWireframe(drawable);
-            }
-        }
-    }
-
-    gGL.flush();
-    gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
-    gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, LLSelectMgr::sHighlightAlpha * 2);
-
-    {
-        bool wireframe_selection = gFloaterTools && gFloaterTools->getVisible();
-
-        LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
-        LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
-
-        if (!wireframe_selection)
-        { //modify wireframe into outline selection mode
-            glStencilFunc(GL_NOTEQUAL, 2, 0xffff);
-            glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-        }
-
-        LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
-        glPolygonOffset(3.f, 3.f);
-        glLineWidth(5.f);
-        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-        pushWireframe(drawable);
-    }
-
-    glLineWidth(1.f);
-    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    gGL.popMatrix();
-
-    if (shader)
-    {
-        shader->bind();
-    }
-}
-
 //-----------------------------------------------------------------------------
 // renderOneSilhouette()
 //-----------------------------------------------------------------------------
@@ -6436,7 +6325,8 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 	LLVOVolume* vobj = drawable->getVOVolume();
 	if (vobj && vobj->isMesh())
 	{
-		renderOneWireframe(color);
+		//This check (if(...)) with assert here just for ensure that this situation will not happens, and can be removed later. For example on the next release.
+		llassert(!"renderOneWireframe() was removed SL-10194");
 		return;
 	}
 
@@ -8050,3 +7940,40 @@ void LLSelectMgr::sendSelectionMove()
 
 	//saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
 }
+
+template<>
+bool LLCheckIdenticalFunctor<F32>::same(const F32& a, const F32& b, const F32& tolerance)
+{
+    F32 delta = (a - b);
+    F32 abs_delta = fabs(delta);
+    return abs_delta <= tolerance;
+}
+
+#define DEF_DUMMY_CHECK_FUNCTOR(T)                                                  \
+template<>                                                                          \
+bool LLCheckIdenticalFunctor<T>::same(const T& a, const T& b, const T& tolerance)   \
+{                                                                                   \
+    (void)tolerance;                                                                \
+    return a == b;                                                                  \
+}
+
+DEF_DUMMY_CHECK_FUNCTOR(LLUUID)
+DEF_DUMMY_CHECK_FUNCTOR(LLGLenum)
+DEF_DUMMY_CHECK_FUNCTOR(LLTextureEntry)
+DEF_DUMMY_CHECK_FUNCTOR(LLTextureEntry::e_texgen)
+DEF_DUMMY_CHECK_FUNCTOR(bool)
+DEF_DUMMY_CHECK_FUNCTOR(U8)
+DEF_DUMMY_CHECK_FUNCTOR(int)
+DEF_DUMMY_CHECK_FUNCTOR(LLColor4)
+DEF_DUMMY_CHECK_FUNCTOR(LLMediaEntry)
+DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLMaterial>)
+DEF_DUMMY_CHECK_FUNCTOR(std::string)
+DEF_DUMMY_CHECK_FUNCTOR(std::vector<std::string>)
+
+template<>
+bool LLCheckIdenticalFunctor<class LLFace *>::same(class LLFace* const & a, class LLFace* const & b, class LLFace* const & tolerance)   \
+{                                                                                   \
+    (void)tolerance;                                                                \
+    return a == b;                                                                  \
+}
+
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index caf104178f2cb89c43daea60bb172dfb5b631bf7..ce0fee88036d80b5d45bec08e02b1c9b21353851 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -124,6 +124,11 @@ template <typename T> struct LLSelectedTEGetFunctor
 	virtual T get(LLViewerObject* object, S32 te) = 0;
 };
 
+template <typename T> struct LLCheckIdenticalFunctor
+{
+	static bool same(const T& a, const T& b, const T& tolerance);
+};
+
 typedef enum e_send_type
 {
 	SEND_ONLY_ROOTS,
@@ -168,14 +173,14 @@ class LLSelectNode
 
 	void selectAllTEs(BOOL b);
 	void selectTE(S32 te_index, BOOL selected);
-	BOOL isTESelected(S32 te_index);
-	S32 getLastSelectedTE();
-	S32 getLastOperatedTE();
+	BOOL isTESelected(S32 te_index) const;
+	bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; }
+	S32 getLastSelectedTE() const;
+	S32 getLastOperatedTE() const { return mLastTESelected; }
 	S32 getTESelectMask() { return mTESelectMask; }
-	void renderOneWireframe(const LLColor4& color);
 	void renderOneSilhouette(const LLColor4 &color);
 	void setTransient(BOOL transient) { mTransient = transient; }
-	BOOL isTransient() { return mTransient; }
+	BOOL isTransient() const { return mTransient; }
 	LLViewerObject* getObject();
 	void setObject(LLViewerObject* object);
 	// *NOTE: invalidate stored textures and colors when # faces change
@@ -313,7 +318,7 @@ class LLObjectSelection : public LLRefCount
 	LLViewerObject* getPrimaryObject() { return mPrimaryObject; }
 
 	// iterate through texture entries
-	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res);
+	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance = false, T tolerance = T());
 	template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value);
 	
 	S32 getNumNodes();
@@ -535,10 +540,10 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	EGridMode		getGridMode() { return mGridMode; }
 	void			getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false);
 
-	BOOL getTEMode()		{ return mTEMode; }
-	void setTEMode(BOOL b)	{ mTEMode = b; }
+	BOOL getTEMode() const { return mTEMode; }
+	void setTEMode(BOOL b) { mTEMode = b; }
 
-	BOOL shouldShowSelection()	{ return mShowSelection; }
+	BOOL shouldShowSelection() const { return mShowSelection; }
 
 	LLBBox getBBoxOfSelection() const;
 	LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; }
@@ -594,7 +599,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	void selectionSetClickAction(U8 action);
 	void selectionSetIncludeInSearch(bool include_in_search);
 	void selectionSetGlow(const F32 glow);
-	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func);
+	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1);
 	void selectionRemoveMaterial();
 
 	void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);
@@ -866,7 +871,7 @@ void dialog_refresh_all();
 //-----------------------------------------------------------------------------
 // getSelectedTEValue
 //-----------------------------------------------------------------------------
-template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res)
+template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance, T tolerance)
 {
 	bool have_first = false;
 	bool have_selected = false;
@@ -902,7 +907,14 @@ template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGet
 			{
 				if ( value != selected_value )
 				{
-					identical = false;
+                    if (!has_tolerance)
+                    {
+					    identical = false;
+                    }
+                    else if (!LLCheckIdenticalFunctor<T>::same(value, selected_value, tolerance))
+                    {
+                        identical = false;
+                    }
 				}
 				if (te == selected_te)
 				{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c5da7dc1b0dbfd090d701286c32f41883e5a63d1..7e275defeda1c21915ebb6674cf9c3fa604ddac7 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -791,10 +791,6 @@ bool idle_startup()
 				}
 			}
 			display_startup();
-			if (gViewerWindow->getSystemUIScaleFactorChanged())
-			{
-				LLViewerWindow::showSystemUIScaleFactorChanged();
-			}
 			LLStartUp::setStartupState( STATE_LOGIN_WAIT );		// Wait for user input
 		}
 		else
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 1f69939c4644fa41232a1be7db6a59e23607fc1b..f8849bf9978633aed86db64afaa061340bcf7b2b 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -60,13 +60,16 @@
 #include "bufferarray.h"
 #include "bufferstream.h"
 #include "llcorehttputil.h"
-
 #include "llhttpretrypolicy.h"
 
 bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
-LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits");
-LLTrace::EventStatHandle<F64Milliseconds > LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");
 
+LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");
+LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");
+
+LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");
+LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexDecodeLatency("texture_decode_latency");
+LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexFetchLatency("texture_fetch_latency");
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -564,15 +567,21 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	F32 mImagePriority;
 	U32 mWorkPriority;
 	F32 mRequestedPriority;
-	S32                         mDesiredDiscard,
-								mSimRequestedDiscard,
-								mRequestedDiscard,
-								mLoadedDiscard,
-								mDecodedDiscard;
-	LLFrameTimer                mRequestedTimer,
-								mFetchTimer;
-	LLTimer			mCacheReadTimer;
-	F32				mCacheReadTime;
+	S32 mDesiredDiscard;
+	S32 mSimRequestedDiscard;
+	S32 mRequestedDiscard;
+    S32 mLoadedDiscard;
+    S32 mDecodedDiscard;
+	S32 mFullWidth;
+	S32 mFullHeight;
+	LLFrameTimer mRequestedDeltaTimer;
+	LLFrameTimer mFetchDeltaTimer;
+	LLTimer mCacheReadTimer;
+    LLTimer mDecodeTimer;
+    LLTimer mFetchTimer;
+	F32 mCacheReadTime; // time for cache read only
+    F32 mDecodeTime;    // time for decode only
+    F32 mFetchTime;     // total time from req to finished fetch
 	LLTextureCache::handle_t    mCacheReadHandle,
 								mCacheWriteHandle;
 	S32                         mRequestedSize,
@@ -906,6 +915,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mLoadedDiscard(-1),
 	  mDecodedDiscard(-1),
 	  mCacheReadTime(0.f),
+	  mDecodeTime(0.f),
+      mFetchTime(0.f),
 	  mCacheReadHandle(LLTextureCache::nullHandle()),
 	  mCacheWriteHandle(LLTextureCache::nullHandle()),
 	  mRequestedSize(0),
@@ -1167,7 +1178,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState != DONE)
 	{
-		mFetchTimer.reset();
+		mFetchDeltaTimer.reset();
 	}
 
 	if (mState == INIT)
@@ -1218,7 +1229,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			mFileSize = 0;
 			mLoaded = FALSE;			
-			
+
+            add(LLTextureFetch::sCacheAttempt, 1.0);
+
 			if (mUrl.compare(0, 7, "file://") == 0)
 			{
 				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
@@ -1229,7 +1242,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
 				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
 																		  offset, size, responder);
-				mCacheReadTimer.reset();
+                mCacheReadTimer.reset();                
 			}
 			else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache())
 			{
@@ -1260,6 +1273,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			{
 				mCacheReadHandle = LLTextureCache::nullHandle();
 				setState(CACHE_POST);
+                add(LLTextureFetch::sCacheHit, 1.0);
 				// fall through
 			}
 			else
@@ -1297,7 +1311,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
 							   << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
 							   << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
-			record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
 		}
 		else
 		{
@@ -1315,7 +1328,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			
 			// fall through
-			record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
 		}
 	}
 
@@ -1571,7 +1583,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			return true; // failed
 		}
 		
-		mRequestedTimer.reset();
+		mRequestedDeltaTimer.reset();
 		mLoaded = FALSE;
 		mGetStatus = LLCore::HttpStatus();
 		mGetReason.clear();
@@ -1898,6 +1910,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mFetcher->getFetchDebugger()->addHistoryEntry(this);
 			}
 
+            mDecodeTime = mDecodeTimer.getElapsedTimeF32();
+
 			if (mDecodedDiscard < 0)
 			{
 				if (mCachedSize > 0 && !mInLocalCache && mRetryAttempt == 0)
@@ -2002,6 +2016,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		else
 		{
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+            mFetchTime = mFetchTimer.getElapsedTimeF32();
 			return true;
 		}
 	}
@@ -2945,11 +2960,12 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
 			discard_level = worker->mDecodedDiscard;
 			raw = worker->mRawImage;
 			aux = worker->mAuxImage;
-			F32Seconds cache_read_time(worker->mCacheReadTime);
-			if (cache_read_time != (F32Seconds)0.f)
-			{
-				record(sCacheReadLatency, cache_read_time);
-			}
+			sample(sTexDecodeLatency, worker->mDecodeTime);
+            sample(sTexFetchLatency, worker->mFetchTime);
+            sample(sCacheReadLatency, worker->mCacheReadTime);
+            worker->mCacheReadTimer.reset();
+            worker->mDecodeTimer.reset();
+            worker->mFetchTimer.reset();
 			res = true;
 			LL_DEBUGS(LOG_TXT) << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;
 			worker->unlockWorkMutex();									// -Mw
@@ -3253,7 +3269,7 @@ void LLTextureFetch::sendRequestListToSimulators()
 // 			req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
 				continue;
 			}
-			F32 elapsed = req->mRequestedTimer.getElapsedTimeF32();
+			F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
 			{
 				F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
 				if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
@@ -3322,7 +3338,7 @@ void LLTextureFetch::sendRequestListToSimulators()
 				req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
 				req->mSimRequestedDiscard = req->mDesiredDiscard;
 				req->mRequestedPriority = req->mImagePriority;
-				req->mRequestedTimer.reset();
+				req->mRequestedDeltaTimer.reset();
 				req->unlockWorkMutex();									// -Mw
 				sim_request_count++;
 				if (sim_request_count >= IMAGES_PER_REQUEST)
@@ -3397,7 +3413,7 @@ void LLTextureFetch::sendRequestListToSimulators()
 // Locks:  Mw
 bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
 {
-	mRequestedTimer.reset();
+	mRequestedDeltaTimer.reset();
 	if (index >= mTotalPackets)
 	{
 // 		LL_WARNS(LOG_TXT) << "Received Image Packet " << index << " > max: " << mTotalPackets << " for image: " << mID << LL_ENDL;
@@ -3606,8 +3622,8 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
 	{
 		worker->lockWorkMutex();										// +Mw
 		state = worker->mState;
-		fetch_dtime = worker->mFetchTimer.getElapsedTimeF32();
-		request_dtime = worker->mRequestedTimer.getElapsedTimeF32();
+		fetch_dtime = worker->mFetchDeltaTimer.getElapsedTimeF32();
+		request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();
 		if (worker->mFileSize > 0)
 		{
 			if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR)
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index cfa312ccd95b2dabd94a3cb2b960aabce98cc155..a2155bde1fbe9b8c970e1902cbc9f2e0d3bef8e8 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -308,13 +308,16 @@ class LLTextureFetch : public LLWorkerThread
 	S32 mPacketCount;
 	S32 mBadPacketCount;
 	
+    static LLTrace::CountStatHandle<F64>        sCacheHit;
+    static LLTrace::CountStatHandle<F64>        sCacheAttempt;
+    static LLTrace::SampleStatHandle<F32Seconds> sCacheReadLatency;
+    static LLTrace::SampleStatHandle<F32Seconds> sTexDecodeLatency;
+    static LLTrace::SampleStatHandle<F32Seconds> sTexFetchLatency;
+
 private:
 	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only
 	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
 
-	static LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > sCacheHitRate;
-	static LLTrace::EventStatHandle<F64Milliseconds > sCacheReadLatency;
-
 	LLTextureCache* mTextureCache;
 	LLImageDecodeThread* mImageDecodeThread;
 	
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index d7b95db94f9ecf51ef5e910206b535bc45215908..0d2edc0268e2be3382e1869830523b2f7574b5c4 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -240,9 +240,9 @@ void LLTextureBar::draw()
 		{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ
 		{ "HTP", LLColor4::green },	// WAIT_HTTP_REQ
 		{ "DEC", LLColor4::yellow },// DECODE_IMAGE
-		{ "DEC", LLColor4::green }, // DECODE_IMAGE_UPDATE
+		{ "DEU", LLColor4::green }, // DECODE_IMAGE_UPDATE
 		{ "WRT", LLColor4::purple },// WRITE_TO_CACHE
-		{ "WRT", LLColor4::orange },// WAIT_ON_WRITE
+		{ "WWT", LLColor4::orange },// WAIT_ON_WRITE
 		{ "END", LLColor4::red },   // DONE
 #define LAST_STATE 14
 		{ "CRE", LLColor4::magenta }, // LAST_STATE+1
@@ -530,6 +530,25 @@ void LLGLTexMemBar::draw()
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 
+    LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
+
+    F64 cacheHits     = recording.getSampleCount(LLTextureFetch::sCacheHit);
+    F64 cacheAttempts = recording.getSampleCount(LLTextureFetch::sCacheAttempt);
+
+	F32 cacheHitRate = (cacheAttempts > 0.0) ? F32((cacheHits / cacheAttempts) * 100.0f) : 0.0f;
+
+    U32 cacheReadLatMin = U32(recording.getMin(LLTextureFetch::sCacheReadLatency).value() * 1000.0f);
+    U32 cacheReadLatMed = U32(recording.getMean(LLTextureFetch::sCacheReadLatency).value() * 1000.0f);
+    U32 cacheReadLatMax = U32(recording.getMax(LLTextureFetch::sCacheReadLatency).value() * 1000.0f);
+
+    U32 texDecodeLatMin = U32(recording.getMin(LLTextureFetch::sTexDecodeLatency).value() * 1000.0f);
+    U32 texDecodeLatMed = U32(recording.getMean(LLTextureFetch::sTexDecodeLatency).value() * 1000.0f);
+    U32 texDecodeLatMax = U32(recording.getMax(LLTextureFetch::sTexDecodeLatency).value() * 1000.0f);
+
+    U32 texFetchLatMin = U32(recording.getMin(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
+    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",
 					total_mem.value(),
 					max_total_mem.value(),
@@ -542,7 +561,7 @@ void LLGLTexMemBar::draw()
 					cache_max_usage);
 	//, cache_entries, cache_max_entries
 
-	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5,
+	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 
 	U32 cache_read(0U), cache_write(0U), res_wait(0U);
@@ -558,6 +577,21 @@ void LLGLTexMemBar::draw()
 					cache_write,
 					res_wait);
 
+	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5,
+											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
+
+    text = llformat("CacheHitRate: %3.2f Read: %d/%d/%d Decode: %d/%d/%d Fetch: %d/%d/%d",
+                    cacheHitRate,
+                    cacheReadLatMin,
+                    cacheReadLatMed,
+                    cacheReadLatMax,
+                    texDecodeLatMin,
+                    texDecodeLatMed,
+                    texDecodeLatMax,
+                    texFetchLatMin,
+                    texFetchLatMed,
+                    texFetchLatMax);
+
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 
@@ -640,7 +674,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)
 LLRect LLGLTexMemBar::getRequiredRect()
 {
 	LLRect rect;
-	rect.mTop = 68; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
+	rect.mTop = 78; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
 	return rect;
 }
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 2e5807cab93cb87f83fa5b1b59540e54dc02985a..0862113999119b08427f06a461c1ce79375951ac 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -688,7 +688,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 		static LLCullResult result;
 		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
+		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
 		gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
 		stop_glerror();
 
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 374322ac10a2e6f0e5f10ad40b053040bb26c7ec..a593905060bec4c166f7637c005dc8e39b04848f 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -34,6 +34,7 @@
 #include "lltrans.h"
 #include "llweb.h"
 
+
 /// key used to store the grid, and the name attribute in the grid data
 const std::string  GRID_VALUE = "keyname";
 /// the value displayed in the grid selector menu, and other human-oriented text
@@ -87,13 +88,6 @@ LLGridManager::LLGridManager()
 	// an attacker.  Don't want someone snagging a password.
 	std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
 														   "grids.xml");
-
-    // fall back to app_settings/grids.xml if it's provided
-    if (!LLFile::isfile(grid_file))
-    {
-        grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
-														   "grids.xml");
-    }
 	LL_DEBUGS("GridManager")<<LL_ENDL;
 
 	initialize(grid_file);
@@ -139,13 +133,6 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "https://my.aditi.lindenlab.com/",
 				  "Aditi");
 
-    // dump example grid file...
-    //llofstream out_llsd_xml;
-    //std::string default_grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml");
-    //out_llsd_xml.open(default_grid_file.c_str());
-    //LLSDSerialize::toPrettyXML(mGridList, out_llsd_xml);
-    //out_llsd_xml.close();
-
 	LLSD other_grids;
 	llifstream llsd_xml;
 	if (!grid_file.empty())
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 5f35f71742aebc6f19e297f974eee311721a5485..5cf9a74f8a4bfcf435227c8525c7196648782fae 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -159,6 +159,10 @@ LLGLSLShader		gHighlightProgram;
 LLGLSLShader		gHighlightNormalProgram;
 LLGLSLShader		gHighlightSpecularProgram;
 
+LLGLSLShader		gDeferredHighlightProgram;
+LLGLSLShader		gDeferredHighlightNormalProgram;
+LLGLSLShader		gDeferredHighlightSpecularProgram;
+
 LLGLSLShader		gPathfindingProgram;
 LLGLSLShader		gPathfindingNoNormalsProgram;
 
@@ -212,7 +216,11 @@ LLGLSLShader			gDeferredShadowProgram;
 LLGLSLShader			gDeferredShadowCubeProgram;
 LLGLSLShader			gDeferredShadowAlphaMaskProgram;
 LLGLSLShader			gDeferredAvatarShadowProgram;
+LLGLSLShader			gDeferredAvatarAlphaShadowProgram;
+LLGLSLShader			gDeferredAvatarAlphaMaskShadowProgram;
 LLGLSLShader			gDeferredAttachmentShadowProgram;
+LLGLSLShader			gDeferredAttachmentAlphaShadowProgram;
+LLGLSLShader			gDeferredAttachmentAlphaMaskShadowProgram;
 LLGLSLShader			gDeferredAlphaProgram;
 LLGLSLShader			gDeferredAlphaImpostorProgram;
 LLGLSLShader			gDeferredAlphaWaterProgram;
@@ -1271,6 +1279,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredSkinnedFullbrightShinyProgram.unload();
 		gDeferredSkinnedFullbrightProgram.unload();
 
+        gDeferredHighlightProgram.unload();
+        gDeferredHighlightNormalProgram.unload();
+        gDeferredHighlightSpecularProgram.unload();
+
 		gNormalMapGenProgram.unload();
 		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
 		{
@@ -1282,6 +1294,36 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
 	BOOL success = TRUE;
 
+    if (success)
+	{
+		gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
+		gDeferredHighlightProgram.mShaderFiles.clear();
+		gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredHighlightProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		
+		success = gDeferredHighlightProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gDeferredHighlightNormalProgram.mName = "Deferred Highlight Normals Shader";
+		gDeferredHighlightNormalProgram.mShaderFiles.clear();
+		gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredHighlightNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		
+		success = gHighlightNormalProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gDeferredHighlightSpecularProgram.mName = "Deferred Highlight Spec Shader";
+		gDeferredHighlightSpecularProgram.mShaderFiles.clear();
+		gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredHighlightSpecularProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		
+		success = gDeferredHighlightSpecularProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
@@ -2024,7 +2066,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredWaterProgram.mFeatures.hasGamma = true;
 		gDeferredWaterProgram.mFeatures.hasTransport = true;
 		gDeferredWaterProgram.mFeatures.encodesNormal = true;
-		//gDeferredWaterProgram.mFeatures.hasShadows = true;
 
 		gDeferredWaterProgram.mShaderFiles.clear();
 		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 66cb80657f0791880af2c055bbc298cbcfc3d378..18be3c22aa372f5f769fa8e5fc30f3370bd96e0b 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -247,6 +247,10 @@ extern LLGLSLShader			gHighlightProgram;
 extern LLGLSLShader			gHighlightNormalProgram;
 extern LLGLSLShader			gHighlightSpecularProgram;
 
+extern LLGLSLShader			gDeferredHighlightProgram;
+extern LLGLSLShader			gDeferredHighlightNormalProgram;
+extern LLGLSLShader			gDeferredHighlightSpecularProgram;
+
 extern LLGLSLShader			gPathfindingProgram;
 extern LLGLSLShader			gPathfindingNoNormalsProgram;
 
@@ -305,6 +309,10 @@ extern LLGLSLShader			gDeferredPostNoDoFProgram;
 extern LLGLSLShader			gDeferredPostGammaCorrectProgram;
 extern LLGLSLShader			gDeferredAvatarShadowProgram;
 extern LLGLSLShader			gDeferredAttachmentShadowProgram;
+extern LLGLSLShader			gDeferredAttachmentAlphaShadowProgram;
+extern LLGLSLShader			gDeferredAttachmentAlphaMaskShadowProgram;
+extern LLGLSLShader			gDeferredAvatarAlphaShadowProgram;
+extern LLGLSLShader			gDeferredAvatarAlphaMaskShadowProgram;
 extern LLGLSLShader			gDeferredAlphaProgram;
 extern LLGLSLShader			gDeferredAlphaImpostorProgram;
 extern LLGLSLShader			gDeferredFullbrightProgram;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 1ba7a7b2b9656c0e84c2913a0e80663f2b3a4d9b..618acf4452f5efca2d3b12a2f3c74fb41a3647c6 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1195,9 +1195,17 @@ void LLViewerFetchedTexture::loadFromFastCache()
 	}
 	mInFastCacheList = FALSE;
 
+    add(LLTextureFetch::sCacheAttempt, 1.0);
+
+    LLTimer fastCacheTimer;
 	mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel);
 	if(mRawImage.notNull())
 	{
+        F32 cachReadTime = fastCacheTimer.getElapsedTimeF32();
+
+        add(LLTextureFetch::sCacheHit, 1.0);
+        sample(LLTextureFetch::sCacheReadLatency, cachReadTime);
+
 		mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
 		mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
 		setTexelsPerImage();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 3421b99ba46e7cbcf37cbe61c3838f36e890bb1f..996d14080584e31d9d4a22311cb5fa55e6dacba0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1622,8 +1622,6 @@ BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32
 {
     if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE)
     {
-        gSavedSettings.setF32("LastSystemUIScaleFactor", ui_scale_factor);
-        gSavedSettings.setF32("UIScaleFactor", ui_scale_factor);
         LLViewerWindow::reshape(window_width, window_height);
         mResDirty = true;
         return TRUE;
@@ -1635,6 +1633,14 @@ BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32
     }
 }
 
+BOOL LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window)
+{
+	LLCoordScreen window_rect;
+	mWindow->getSize(&window_rect);
+	reshape(window_rect.mX, window_rect.mY);
+	return TRUE;
+}
+
 void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
 {
 	LLAppViewer::instance()->pingMainloopTimeout(msg);
@@ -1697,8 +1703,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mResDirty(false),
 	mStatesDirty(false),
 	mCurrResolutionIndex(0),
-	mProgressView(NULL),
-	mSystemUIScaleFactorChanged(false)
+	mProgressView(NULL)
 {
 	// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
 	// pass its value right now. Instead, pass it a nullary function that
@@ -1730,7 +1735,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	U32 fsaa_samples)
 	*/
 	// create window
-    mWindow = LLWindowManager::createWindow(this,
+	mWindow = LLWindowManager::createWindow(this,
 		p.title, p.name, p.x, p.y, p.width, p.height, 0,
 		p.fullscreen, 
 		gHeadlessClient,
@@ -1774,31 +1779,9 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	LLCoordScreen scr;
     mWindow->getSize(&scr);
 
-    if(p.fullscreen && ( scr.mX!=p.width || scr.mY!=p.height))
-    {
-		LL_WARNS() << "Fullscreen has forced us in to a different resolution now using "<<scr.mX<<" x "<<scr.mY<<LL_ENDL;
-		gSavedSettings.setS32("FullScreenWidth",scr.mX);
-		gSavedSettings.setS32("FullScreenHeight",scr.mY);
-    }
-
-
-	F32 system_scale_factor = mWindow->getSystemUISize();
-	if (system_scale_factor < MIN_UI_SCALE || system_scale_factor > MAX_UI_SCALE)
-	{
-		// reset to default;
-		system_scale_factor = 1.f;
-	}
-	if (p.first_run || gSavedSettings.getF32("LastSystemUIScaleFactor") != system_scale_factor)
-	{
-		mSystemUIScaleFactorChanged = !p.first_run;
-		gSavedSettings.setF32("LastSystemUIScaleFactor", system_scale_factor);
-		gSavedSettings.setF32("UIScaleFactor", system_scale_factor);
-	}
-
-
 	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
 	// the size of a window or fullscreen context may have been adjusted slightly...)
-	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE);
+	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getSystemUISize();
 	
 	mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
 	mDisplayScale *= ui_scale_factor;
@@ -1839,6 +1822,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 		LLFeatureManager::getInstance()->applyRecommendedSettings();
 		gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
 	}
+
+	if (!gGLManager.mHasDepthClamp)
+	{
+		LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
+	}
 	
 	// If we crashed while initializng GL stuff last time, disable certain features
 	if (gSavedSettings.getBOOL("RenderInitError"))
@@ -1886,33 +1874,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
 }
 
-//static
-void LLViewerWindow::showSystemUIScaleFactorChanged()
-{
-	LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged);
-}
-
 std::string LLViewerWindow::getLastSnapshotDir()
 {
     return sSnapshotDir;
 }
 
-//static
-bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if(option == 0)
-	{
-		LLFloaterReg::toggleInstanceOrBringToFront("preferences");
-		LLFloater* pref_floater = LLFloaterReg::getInstance("preferences");
-		LLTabContainer* tab_container = pref_floater->getChild<LLTabContainer>("pref core");
-		tab_container->selectTabByName("advanced1");
-
-	}
-	return false; 
-}
-
-
 void LLViewerWindow::initGLDefaults()
 {
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -3039,12 +3005,12 @@ void LLViewerWindow::moveCursorToCenter()
 		S32 x = getWorldViewWidthScaled() / 2;
 		S32 y = getWorldViewHeightScaled() / 2;
 	
+		LLUI::setMousePositionScreen(x, y);
+		
 		//on a forced move, all deltas get zeroed out to prevent jumping
 		mCurrentMousePoint.set(x,y);
 		mLastMousePoint.set(x,y);
 		mCurrentMouseDelta.set(0,0);	
-
-		LLUI::setMousePositionScreen(x, y);	
 	}
 }
 
@@ -5388,7 +5354,7 @@ F32	LLViewerWindow::getWorldViewAspectRatio() const
 
 void LLViewerWindow::calcDisplayScale()
 {
-	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE);
+	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getSystemUISize();
 	LLVector2 display_scale;
 	display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
 	display_scale *= ui_scale_factor;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index d8d420e6becd0179e1b59859a7becbe4d81fa507..d41a606f113172462608accc10e31d25316fc974 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -212,6 +212,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	/*virtual*/ BOOL handleTimerEvent(LLWindow *window);
 	/*virtual*/ BOOL handleDeviceChange(LLWindow *window);
 	/*virtual*/ BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
+	/*virtual*/ BOOL handleWindowDidChangeScreen(LLWindow *window);
 
 	/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
 	/*virtual*/ void handlePauseWatchdog(LLWindow *window);
@@ -423,8 +424,6 @@ class LLViewerWindow : public LLWindowCallbacks
 	void			calcDisplayScale();
 	static LLRect 	calcScaledRect(const LLRect & rect, const LLVector2& display_scale);
 
-	bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; }
-	static void showSystemUIScaleFactorChanged();
 	static std::string getLastSnapshotDir();
 
 private:
@@ -440,7 +439,6 @@ class LLViewerWindow : public LLWindowCallbacks
 	S32				getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter
 	LLRect			getChatConsoleRect(); // Get optimal cosole rect.
 
-	static bool onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response);
 private:
 	LLWindow*		mWindow;						// graphical window object
 	bool			mActive;
@@ -514,7 +512,6 @@ class LLViewerWindow : public LLWindowCallbacks
 	LLPointer<LLViewerObject>	mDragHoveredObject;
 
 	static LLTrace::SampleStatHandle<>	sMouseVelocityStat;
-	bool mSystemUIScaleFactorChanged; // system UI scale factor changed from last run
 };
 
 //
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index cb83cf8fdf3e4b25c678c8562d772f663420be08..6e08a2ff12f78d877c3a0a7b2dabc1f52065d638 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -356,6 +356,7 @@ void LLVoiceVisualizer::render()
 		//---------------------------------------------------------------
 		LLGLSPipelineAlpha alpha_blend;
 		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+		LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		
 		//-------------------------------------------------------------
 		// create coordinates of the geometry for the dot
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 1fd7c7d3ce856db0edd4662e6d7a65e00bf1964e..d6bd9c3b662abe8f06ffcd1a2b0b5b976f464dee 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4971,7 +4971,10 @@ static LLTrace::BlockTimerStatHandle FTM_REGISTER_FACE("Register Face");
 void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
 {
 	LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE);
-	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))
+	if (   type == LLRenderPass::PASS_ALPHA 
+		&& facep->getTextureEntry()->getMaterialParams().notNull() 
+		&& !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)
+		&& LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1)
 	{
 		LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
 	}
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 707fe76cef19d12d62f2a18833a27f1c4082391d..93d1dacf1fa01f829ddbe1204e87412bd5870acc 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -883,9 +883,14 @@ void LLWorldMapView::drawFrustum()
 	F32 half_width_pixels = half_width_meters * meters_to_pixels;
 	
 	// Compute the frustum coordinates. Take the UI scale into account.
-	F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
-	F32 ctr_x = (getLocalRect().getWidth() * 0.5f + sPanX)  * ui_scale_factor;
-	F32 ctr_y = (getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor;
+#if defined(LL_DARWIN)
+    F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
+    F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX)  * ui_scale_factor) * LLUI::getScaleFactor().mV[VX];
+    F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor) * LLUI::getScaleFactor().mV[VY];
+#else
+    F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX)  * LLUI::getScaleFactor().mV[VX]);
+    F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
+#endif
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 313edca34527e37b33e76599c6d9e731584a7250..65c04b6eac03601c0ce5a1eab20b82fd9238f957 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2599,9 +2599,12 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
 
 	if (scratch_space)
 	{
+        GLint bits = 0;
+        bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
+        bits |= GL_DEPTH_BUFFER_BIT;
 		scratch_space->copyContents(source, 
 									0, 0, source.getWidth(), source.getHeight(), 
-									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) : GL_COLOR_BUFFER_BIT, GL_NEAREST);
+									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), bits, GL_NEAREST);
 	}
 
 	dest.bindTarget();
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 164ae7a9d4cbe839ec4ebf77c2fca1a4c0659a3b..e14419efb1d53ffe34051fd45bd01bfd7df66b12 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -1615,10 +1615,6 @@ Geben Sie das Objekt zum Verkauf frei und versuchen Sie es erneut.
 		Möchten Sie Ihren Internetbrowser öffnen, um diesen Inhalt anzuzeigen?
 		<usetemplate ignoretext="Meinen Browser starten, um eine Webseite anzuzeigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		Der UI-Größenfaktor des Systems hat sich seit der letzten Ausführung geändert. Möchten Sie die Seite mit den UI-Größeneinstellungen öffnen?
-		<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		Möchten Sie Ihre [http://secondlife.com/account/ Startseite] aufrufen, um Ihr Konto zu verwalten?
 		<usetemplate ignoretext="Meinen Browser starten, um mein Konto zu verwalten" name="okcancelignore" notext="Abbrechen" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 4b202ec21e6afee431997ca65862b8ce0708dc6a..70bf3f7c147a917dce2a9e1ceab5fe992d44aaee 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -357,6 +357,18 @@
     tool_tip="Compresses textures in video memory, allowing for higher resolution textures to be loaded at the cost of some color quality."
     width="315" />
 
+  <check_box
+    control_name="RenderHiDPI"
+    height="16"
+    initial_value="true"
+    label="Enable support for HiDPI displays (requires restart)"
+    layout="topleft"
+    left="30"
+    top_delta="16"
+    name="use HiDPI"
+    tool_tip="Enable OpenGL for High-Resolution Drawing."
+    width="315" />
+
   <text
     type="string"
     length="1"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 8d6a78713393fbc2c3e0ab7f2e761587e38c9d6c..42b1a1ec1beff6c2708a0a8fcf78a939bbc62b57 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3936,18 +3936,6 @@ Do you want to open your Web browser to view this content?
      yestext="OK"/>
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="SystemUIScaleFactorChanged"
-   type="alertmodal">
-System UI size factor has changed since last run. Do you want to open UI size adjustment settings page?
-    <tag>confirm</tag>
-    <usetemplate
-     name="okcancelbuttons"
-     notext="Cancel"
-     yestext="OK"/>
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="WebLaunchJoinNow"
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 8c769d87de987db75b6e88e39d5cde0bcfe9d508..67b99ca5880dd032370a2c92c30c3bea68cbd4bd 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -603,11 +603,10 @@
              layout="topleft"
 			 label_width="205"
              left="10"
-             max_val="9999"
-             min_val="-9999"
+             max_val="360"
+             min_val="-360"
              name="TexRot"
              width="265" />
-
             <spinner
              follows="left|top"
              height="19"
@@ -617,6 +616,7 @@
              layout="topleft"
              left="10"
              min_val="-1"
+             max_val="1"
              name="TexOffsetU"
              width="265" />
             <spinner
@@ -628,6 +628,7 @@
              layout="topleft"
              left="10"
              min_val="-1"
+             max_val="1"
              name="TexOffsetV"
              width="265" />
             <spinner
@@ -667,10 +668,9 @@
 			 label_width="205"
              left="10"
              max_val="360"
-             min_val="0"
+             min_val="-360"
              name="bumpyRot"
              width="265" />
-
             <spinner
              follows="left|top"
              height="19"
@@ -679,7 +679,8 @@
              label_width="205"
              layout="topleft"
              left="10"
-             min_val="0"
+             min_val="-1"
+             max_val="1"
              name="bumpyOffsetU"
              width="265" />
             <spinner
@@ -690,7 +691,8 @@
              label_width="205"
              layout="topleft"
              left="10"
-             min_val="0"
+             min_val="-1"
+             max_val="1"
              name="bumpyOffsetV"
              width="265" />
             <spinner
@@ -730,10 +732,9 @@
 			 label_width="205"
              left="10"
              max_val="360"
-             min_val="0"
+             min_val="-360"
              name="shinyRot"
              width="265" />
-
             <spinner
              follows="left|top"
              height="19"
@@ -742,7 +743,8 @@
              label_width="205"
              layout="topleft"
              left="10"
-             min_val="0"
+             min_val="-1"
+             max_val="1"
              name="shinyOffsetU"
              width="265" />
             <spinner
@@ -753,7 +755,8 @@
              label_width="205"
              layout="topleft"
              left="10"
-             min_val="0"
+             min_val="-1"
+             max_val="1"
              name="shinyOffsetV"
              width="265" />
             <check_box
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index f4f0d0a3ed5609af6be2f0f46156e4398fdae733..8ba8144cb62f49827e78877d39f90108d6abb74e 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -1605,10 +1605,6 @@ Por favor, pon en venta el objeto y vuelve a intentarlo.
 		¿Quieres abrir tu navegador para ver este contenido?
 		<usetemplate ignoretext="Abrir mi navegador para ver una página web" name="okcancelignore" notext="Cancelar" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		El factor de tamaño de IU del sistema ha cambiado desde la última ejecución. ¿Deseas abrir la página de ajustes de tamaño de la IU?
-		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Aceptar"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		¿Ir al [http://secondlife.com/account/ Panel de Control] para administrar tu cuenta?
 		<usetemplate ignoretext="Abrir mi navegador para administrar mi cuenta" name="okcancelignore" notext="Cancelar" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index dd6fe2f3dbc580b2e1e6496f0c94b460ad8b30de..7fbea9c0ae70f65d76a89e0b8cf8a3a1c8467542 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -1598,10 +1598,6 @@ Veuillez choisir un objet à vendre et réessayer.
 		Voulez-vous ouvrir votre navigateur web système pour afficher ce contenu ?
 		<usetemplate ignoretext="Ouvrir mon navigateur pour consulter une page web" name="okcancelignore" notext="Annuler" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		Le facteur de taille de l’interface système a changé depuis la dernière exécution. Voulez-vous ouvrir la page des paramètres d’ajustement de la taille de l’interface ?
-		<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		Accéder à votre [http://secondlife.com/account/ Page d&apos;accueil] pour gérer votre compte ?
 		<usetemplate ignoretext="Lancer mon navigateur pour gérer mon compte" name="okcancelignore" notext="Annuler" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index c0f7df522738d19894a399cd0621bdaa5f8f4199..1baf8e1b873a638159de9e24bb1431b959557315 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -1601,10 +1601,6 @@ Imposta l&apos;oggetto per la vendita e riprova.
 		Vuoi aprire il browser per vedere questi contenuti?
 		<usetemplate ignoretext="Lancia il browser per consultare una pagina web" name="okcancelignore" notext="Annulla" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		Il fattore dimensioni UI del sistema è cambiato rispetto all&apos;ultima sessione. Vuoi aprire la pagina delle impostazioni di regolazione delle dimensioni UI?
-		<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		Vuoi andare su [http://secondlife.com/account/ Dashboard] per gestire il tuo account?
 		<usetemplate ignoretext="Lancia il browser per gestire il mio account" name="okcancelignore" notext="Annulla" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 7bdae9c2bce0560db516fef93dcbcec71c585de3..9251a8e5ffee09d0d7f83e2ec99b137cc2538b5c 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -1630,10 +1630,6 @@ SHA1 フィンガープリント: [MD5_DIGEST]
 		Web ブラウザを開いてこのコンテンツを表示しますか?
 		<usetemplate ignoretext="ブラウザを起動して Web ページを見るとき" name="okcancelignore" notext="キャンセル" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		前回実行時からシステム UI サイズ係数が変更されています。UI サイズ調整設定ページを開きますか?
-		<usetemplate name="okcancelbuttons" notext="取り消し" yestext="OK"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		[http://jp.secondlife.com/account/ マイアカウント] ページに移動してアカウントを管理しますか?
 		<usetemplate ignoretext="ブラウザを起動してアカウントを管理するとき" name="okcancelignore" notext="取り消し" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 75c3b0ec58c55bc6fd6e5ced6f1b238d1e8d8aa4..59c84b781d4b738993d6241807a0948cd4f22ca2 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -1592,10 +1592,6 @@ Por favor, ponha o objeto à venda e tente novamente.
 		Abrir uma janela do navegador para ver essas informações?
 		<usetemplate ignoretext="Abrir o navegador para acessar uma página na web" name="okcancelignore" notext="Cancelar" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		O fator de tamanho da interface do sistema foi alterado desde a última execução. Deseja abrir a página de configurações de ajuste de tamanho da interface?
-		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		Deseja abrir o [http://secondlife.com/account/ Painel] para gerenciar sua conta?
 		<usetemplate ignoretext="Abrir o navegador para acessar minha conta" name="okcancelignore" notext="Cancelar" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index e46e569a3942fa8c2e6e16fca9a6aa9f9cd5b282..663cb808ae63b56a8ca5eb3e8b5fd117ebd5c513 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -1600,10 +1600,6 @@
 		Открыть браузер для просмотра этого контента?
 		<usetemplate ignoretext="Запустить браузер для просмотра веб-страницы" name="okcancelignore" notext="Отмена" yestext="OK"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		Со времени последнего запуска изменился системный коэффициент размера интерфейса. Открыть страницу настроек размера интерфейса?
-		<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		Перейти на [http://secondlife.com/account/ информационную панель] для управления вашим аккаунтом?
 		<usetemplate ignoretext="Запустить браузер для управления аккаунтом" name="okcancelignore" notext="Отмена" yestext="OK"/>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 7651e4078b0f6ef7e24b3bcf99e1e94998ec5438..5cca46d483a6b8b0c6ff12cafbada187d56d374b 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -1601,10 +1601,6 @@ Nesneyi satılık olarak ayarlayıp tekrar deneyin.
 		Bu içeriği görüntülemek için Web tarayıcınızı açmak istiyor musunuz?
 		<usetemplate ignoretext="Bir web sayfasını görüntülemek için tarayıcımı başlat" name="okcancelignore" notext="İptal" yestext="Tamam"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		Sistem kullanıcı arayüzü faktörü son çalıştırmadan bu yana değişti. Kullanıcı arayüzü büyüklük değiştirme ayarları sayfasını açmak istiyor musunuz?
-		<usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		Hesabınızı yönetmek için [http://secondlife.com/account/ Kontrol Paneli] adresine gidilsin mi?
 		<usetemplate ignoretext="Hesabımı yönetmek için tarayıcımı başlat" name="okcancelignore" notext="İptal" yestext="Tamam"/>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index 186a850a1512ac30d9abd03792cb98b985e6d5aa..b1b35f0614da5f8a6e61072e2963863d1f5f174e 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -1597,10 +1597,6 @@ SHA1 指紋:[MD5_DIGEST]
 		你確定要開啟網頁瀏覽器去察看這個內容?
 		<usetemplate ignoretext="啟動我的網頁瀏覽器去察看網頁" name="okcancelignore" notext="取消" yestext="確定"/>
 	</notification>
-	<notification name="SystemUIScaleFactorChanged">
-		系統使用者介面的尺寸倍數自從上次執行後已經改變。 你想要開啟使用者介面尺寸調整的設定頁嗎?
-		<usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/>
-	</notification>
 	<notification name="WebLaunchJoinNow">
 		前往你的[http://secondlife.com/account/ 塗鴉牆]以進行管理你的帳戶?
 		<usetemplate ignoretext="啟動我的瀏覽器以管理我的帳戶" name="okcancelignore" notext="取消" yestext="確定"/>