From a4c3f5aaaec6a190381bfe31ceec97ed31e010f1 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 8 Nov 2017 12:13:50 +0200
Subject: MAINT-7940 Don't decrease character limit when sending snapshot to
 Twitter. Increase limit to 280

---
 indra/newview/llfloatertwitter.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp
index 4bab89ace2..803c80ac1a 100644
--- a/indra/newview/llfloatertwitter.cpp
+++ b/indra/newview/llfloatertwitter.cpp
@@ -404,13 +404,12 @@ void LLTwitterPhotoPanel::clearAndClose()
 void LLTwitterPhotoPanel::updateStatusTextLength(BOOL restore_old_status_text)
 {
 	bool add_location = mLocationCheckbox->getValue().asBoolean();
-	bool add_photo = mPhotoCheckbox->getValue().asBoolean();
 
 	// Restrict the status text length to Twitter's character limit
 	LLTextEditor* status_text_box = dynamic_cast<LLTextEditor*>(mStatusTextBox);
 	if (status_text_box)
 	{
-		int max_status_length = 140 - (add_location ? 40 : 0) - (add_photo ? 40 : 0);
+		int max_status_length = 280 - (add_location ? 40 : 0);
 		status_text_box->setMaxTextLength(max_status_length);
 		if (restore_old_status_text)
 		{
-- 
cgit v1.2.3


From 5ec95b764632c76edef6e986a275153cc574012d Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 9 Nov 2017 16:06:59 +0200
Subject: MAINT-7990 Fixed avatar physics twitching at high fps

---
 indra/newview/llphysicsmotion.cpp | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index 15d39c231f..69f5dd1914 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -491,12 +491,6 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
         //
 
         const F32 time_delta = time - mLastTime;
-
-	// Don't update too frequently, to avoid precision errors from small time slices.
-	if (time_delta <= .01)
-	{
-		return FALSE;
-	}
 	
 	// If less than 1FPS, we don't want to be spending time updating physics at all.
         if (time_delta > 1.0)
-- 
cgit v1.2.3


From 17c22d317f93abc61c68e05a36f56a0359f282ef Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 9 Nov 2017 16:09:51 +0200
Subject: MAINT-2880 Particle generator object doesn't start displaying
 particles, when unblocking the owner of this object

---
 indra/newview/llmutelist.cpp      |  9 +--------
 indra/newview/llviewerobject.cpp  | 27 ++++++++++++++++++++++++++-
 indra/newview/llviewerobject.h    |  5 +++++
 indra/newview/llviewerpartsim.cpp |  6 ++++++
 4 files changed, 38 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index bf1716e18c..64df449c26 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -316,14 +316,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
 				updateAdd(localmute);
 				notifyObservers();
 				notifyObserversDetailed(localmute);
-				if(!(localmute.mFlags & LLMute::flagParticles))
-				{
-					//Kill all particle systems owned by muted task
-					if(localmute.mType == LLMute::AGENT || localmute.mType == LLMute::OBJECT)
-					{
-						LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID);
-					}
-				}
+
 				//mute local lights that are attached to the avatar
 				LLVOAvatar *avatarp = find_avatar(localmute.mID);
 				if (avatarp)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 5de4029542..e86d39e9d0 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -270,7 +270,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mPhysicsShapeUnknown(true),
 	mAttachmentItemID(LLUUID::null),
 	mLastUpdateType(OUT_UNKNOWN),
-	mLastUpdateCached(FALSE)
+	mLastUpdateCached(FALSE),
+	mCachedMuteListUpdateTime(0),
+	mCachedOwnerInMuteList(false)
 {
 	if (!is_global)
 	{
@@ -5116,6 +5118,29 @@ void LLViewerObject::updateText()
 	}
 }
 
+bool LLViewerObject::isOwnerInMuteList()
+{
+	if (isAvatar() || mOwnerID.isNull())
+	{
+		return false;
+	}
+	bool muted = false;
+	F64 now = LLFrameTimer::getTotalSeconds();
+	if (now < mCachedMuteListUpdateTime)
+	{
+		muted = mCachedOwnerInMuteList;
+	}
+	else
+	{
+		muted = LLMuteList::getInstance()->isMuted(mOwnerID);
+
+		const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1;
+		mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES;
+		mCachedOwnerInMuteList = muted;
+	}
+	return muted;
+}
+
 LLVOAvatar* LLViewerObject::asAvatar()
 {
 	return NULL;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 7a490f6957..4f826b9eac 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -422,6 +422,8 @@ public:
 	void updateText(); // update text label position
 	virtual void updateDrawable(BOOL force_damped); // force updates on static objects
 
+	bool isOwnerInMuteList();
+
 	void setDrawableState(U32 state, BOOL recursive = TRUE);
 	void clearDrawableState(U32 state, BOOL recursive = TRUE);
 	BOOL isDrawableState(U32 state, BOOL recursive = TRUE) const;
@@ -823,6 +825,9 @@ private:
 	static BOOL sVelocityInterpolate;
 	static BOOL sPingInterpolate;
 
+	bool mCachedOwnerInMuteList;
+	F64 mCachedMuteListUpdateTime;
+
 	//--------------------------------------------------------------------
 	// For objects that are attachments
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index b4617566ac..e8ea0eb26d 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -37,6 +37,7 @@
 #include "llviewerregion.h"
 #include "llvopartgroup.h"
 #include "llworld.h"
+#include "llmutelist.h"
 #include "pipeline.h"
 #include "llspatialpartition.h"
 #include "llvoavatarself.h"
@@ -711,6 +712,11 @@ void LLViewerPartSim::updateSimulation()
 				upd = FALSE;
 			}
 
+			if(vobj && vobj->isOwnerInMuteList())
+			{
+				upd = FALSE;
+			}
+
 			if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME))
 			{
 				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex())
-- 
cgit v1.2.3


From 83b0467f9f16387dc8e13ba7e4bf4f556512ddf3 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 10 Nov 2017 20:33:51 +0200
Subject: Backed out changeset: 544a91982eba

Originally a fix for MAINT-4773. This was causing a number of issues since
changes made in this code were pushing null textures into server and viewer
should not modify 'content' at server of own violition.
---
 indra/newview/llface.cpp          |  28 -----
 indra/newview/llface.h            |   5 +-
 indra/newview/llviewertexture.cpp |  28 -----
 indra/newview/llviewertexture.h   |   5 -
 indra/newview/llvovolume.cpp      | 225 ++------------------------------------
 indra/newview/llvovolume.h        |  22 +---
 6 files changed, 13 insertions(+), 300 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 3d5e2d356e..c6fff6e57a 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -344,34 +344,6 @@ void LLFace::dirtyTexture()
 	gPipeline.markTextured(drawablep);
 }
 
-void LLFace::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{
-	LLDrawable* drawablep = getDrawable();
-	if(mVObjp.notNull() && mVObjp->getVolume())
-	{
-		LLVOVolume *vobj = drawablep->getVOVolume();
-		if(vobj && vobj->notifyAboutCreatingTexture(texture))
-		{
-			gPipeline.markTextured(drawablep);
-			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
-		}
-	}
-}
-
-void LLFace::notifyAboutMissingAsset(LLViewerTexture *texture)
-{
-	LLDrawable* drawablep = getDrawable();
-	if(mVObjp.notNull() && mVObjp->getVolume())
-	{
-		LLVOVolume *vobj = drawablep->getVOVolume();
-		if(vobj && vobj->notifyAboutMissingAsset(texture))
-		{
-			gPipeline.markTextured(drawablep);
-			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
-		}
-	}
-}
-
 void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
 {
 	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index ee545acb94..2d88c6fa58 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -230,13 +230,10 @@ public:
 
 	static U32 getRiggedDataMask(U32 type);
 
-	void	notifyAboutCreatingTexture(LLViewerTexture *texture);
-	void	notifyAboutMissingAsset(LLViewerTexture *texture);
-
 public: //aligned members
 	LLVector4a		mExtents[2];
 
-private:
+private:	
 	F32         adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
 	BOOL        calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
 public:
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e5a1bed48c..840176c1e0 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -669,36 +669,12 @@ S8 LLViewerTexture::getType() const
 
 void LLViewerTexture::cleanup()
 {
-	notifyAboutMissingAsset();
-
 	mFaceList[LLRender::DIFFUSE_MAP].clear();
 	mFaceList[LLRender::NORMAL_MAP].clear();
 	mFaceList[LLRender::SPECULAR_MAP].clear();
 	mVolumeList.clear();
 }
 
-void LLViewerTexture::notifyAboutCreatingTexture()
-{
-	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
-	{
-		for(U32 f = 0; f < mNumFaces[ch]; f++)
-		{
-			mFaceList[ch][f]->notifyAboutCreatingTexture(this);
-		}
-	}
-}
-
-void LLViewerTexture::notifyAboutMissingAsset()
-{
-	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
-	{
-		for(U32 f = 0; f < mNumFaces[ch]; f++)
-		{
-			mFaceList[ch][f]->notifyAboutMissingAsset(this);
-		}
-	}
-}
-
 // virtual
 void LLViewerTexture::dump()
 {
@@ -1498,8 +1474,6 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 
 	res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
 
-	notifyAboutCreatingTexture();
-
 	setActive();
 
 	if (!needsToSaveRawImage())
@@ -2224,8 +2198,6 @@ void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing)
 	}
 	if (is_missing)
 	{
-		notifyAboutMissingAsset();
-
 		if (mUrl.empty())
 		{
 			LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index c9dea17f63..9208b4813e 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -175,10 +175,6 @@ protected:
 	void init(bool firstinit) ;
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
-
-	void notifyAboutMissingAsset();
-	void notifyAboutCreatingTexture();
-
 private:
 	friend class LLBumpImageList;
 	friend class LLUIImageList;
@@ -316,7 +312,6 @@ public:
 
 	void addToCreateTexture();
 
-
 	 // ONLY call from LLViewerTextureList
 	BOOL createTexture(S32 usename = 0);
 	void destroyTexture() ;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f77b48ff80..20c54d06d3 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2051,230 +2051,27 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 	return res;
 }
 
-bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{ //Ok, here we have confirmation about texture creation, check our wait-list
-  //and make changes, or return false
-
-	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-
-	typedef std::map<U8, LLMaterialPtr> map_te_material;
-	map_te_material new_material;
-
-	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
-	{
-		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-
-		//here we just interesting in DIFFUSE_MAP only!
-		if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat())
-		{ //ok let's check the diffuse mode
-			switch(cur_material->getDiffuseAlphaMode())
-			{
-			case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
-			case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
-			case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
-				{ //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-
-					LLMaterialPtr mat = NULL;
-					map_te_material::iterator it = new_material.find(range_it->second.te);
-					if(new_material.end() == it) {
-						mat = new LLMaterial(cur_material->asLLSD());
-						new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-					} else {
-						mat = it->second;
-					}
-
-					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-
-				} break;
-			} //switch
-		} //if
-	} //for
-
-	//setup new materials
-	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
-	{
-		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
-		LLViewerObject::setTEMaterialParams(it->first, it->second);
-	}
-
-	//clear wait-list
-	mWaitingTextureInfo.erase(range.first, range.second);
-
-	return 0 != new_material.size();
-}
-
-bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
-{ //Ok, here if we wait information about texture and it's missing
-  //then depending from the texture map (diffuse, normal, or specular)
-  //make changes in material and confirm it. If not return false.
-	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-	if(range.first == range.second) return false;
-
-	typedef std::map<U8, LLMaterialPtr> map_te_material;
-	map_te_material new_material;
-	
-	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
-	{
-		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-		if (cur_material.isNull())
-			continue;
-
-		switch(range_it->second.map)
-		{
-		case LLRender::DIFFUSE_MAP:
-			{
-				if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
-				{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-					LLMaterialPtr mat = NULL;
-					map_te_material::iterator it = new_material.find(range_it->second.te);
-					if(new_material.end() == it) {
-						mat = new LLMaterial(cur_material->asLLSD());
-						new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-					} else {
-						mat = it->second;
-					}
-
-					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-				}
-			} break;
-		case LLRender::NORMAL_MAP:
-			{ //missing texture => reset material texture id
-				LLMaterialPtr mat = NULL;
-				map_te_material::iterator it = new_material.find(range_it->second.te);
-				if(new_material.end() == it) {
-					mat = new LLMaterial(cur_material->asLLSD());
-					new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-				} else {
-					mat = it->second;
-				}
-
-				mat->setNormalID(LLUUID::null);
-			} break;
-		case LLRender::SPECULAR_MAP:
-			{ //missing texture => reset material texture id
-				LLMaterialPtr mat = NULL;
-				map_te_material::iterator it = new_material.find(range_it->second.te);
-				if(new_material.end() == it) {
-					mat = new LLMaterial(cur_material->asLLSD());
-					new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-				} else {
-					mat = it->second;
-				}
-
-				mat->setSpecularID(LLUUID::null);
-			} break;
-		case LLRender::NUM_TEXTURE_CHANNELS:
-				//nothing to do, make compiler happy
-			break;
-		} //switch
-	} //for
-
-	//setup new materials
-	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
-	{
-		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
-		LLViewerObject::setTEMaterialParams(it->first, it->second);
-	}
-
-	//clear wait-list
-	mWaitingTextureInfo.erase(range.first, range.second);
-
-	return 0 != new_material.size();
-}
-
 S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
 {
 	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
 
 	if(pMaterialParams)
-	{ //check all of them according to material settings
-
-		LLViewerTexture *img_diffuse = getTEImage(te);
-		LLViewerTexture *img_normal = getTENormalMap(te);
-		LLViewerTexture *img_specular = getTESpecularMap(te);
-
-		llassert(NULL != img_diffuse);
-
-		LLMaterialPtr new_material = NULL;
-
-		//diffuse
-		if(NULL != img_diffuse)
-		{ //guard
-			if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
-			{ //ok here we don't have information about texture, let's belief and leave material settings
-			  //but we remember this case
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
-			}
-			else
-			{
-				bool bSetDiffuseNone = false;
-				if(img_diffuse->isMissingAsset())
-				{
-					bSetDiffuseNone = true;
-				}
-				else
-				{
-					switch(pMaterialParams->getDiffuseAlphaMode())
-					{
-					case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
-					case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
-					case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
-						{ //all of them modes available only for 32 bit textures
-							if(GL_RGBA != img_diffuse->getPrimaryFormat())
-							{
-								bSetDiffuseNone = true;
-							}
-						} break;
-					}
-				} //else
-
-
-				if(bSetDiffuseNone)
-				{ //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-					new_material = new LLMaterial(pMaterialParams->asLLSD());
-					new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-				}
-			}
-		}
-
-		//normal
-		if(LLUUID::null != pMaterialParams->getNormalID())
-		{
-			if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
-			{
-				if(!new_material) {
-					new_material = new LLMaterial(pMaterialParams->asLLSD());
-				}
-				new_material->setNormalID(LLUUID::null);
-			}
-			else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
-			{ //ok here we don't have information about texture, let's belief and leave material settings
-				//but we remember this case
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
-			}
-
-		}
+	{
+		LLViewerTexture* image = getTEImage(te);
+		LLGLenum image_format = image ? image->getPrimaryFormat() : GL_RGB;
+		LLMaterialPtr current_material = getTEMaterialParams(te);
 
+		U8 new_diffuse_alpha_mode = pMaterialParams->getDiffuseAlphaMode();
 
-		//specular
-		if(LLUUID::null != pMaterialParams->getSpecularID())
+		if(new_diffuse_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 		{
-			if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
-			{
-				if(!new_material) {
-					new_material = new LLMaterial(pMaterialParams->asLLSD());
-				}
-				new_material->setSpecularID(LLUUID::null);
-			}
-			else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
-			{ //ok here we don't have information about texture, let's belief and leave material settings
-				//but we remember this case
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
-			}
+			new_diffuse_alpha_mode = (GL_RGB == image_format || 0 == image_format ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : new_diffuse_alpha_mode);
 		}
 
-		if(new_material) {
-			pMaterial = new_material;
+		if(pMaterialParams->getDiffuseAlphaMode() != new_diffuse_alpha_mode) {
+			//create new material
+			pMaterial = new LLMaterial(pMaterialParams->asLLSD());
+			pMaterial->setDiffuseAlphaMode(new_diffuse_alpha_mode);
 			LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
 		}
 	}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a331908320..b07d416363 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -380,7 +380,7 @@ public:
 	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
 	static F32 sLODFactor;				// LOD scale factor
 	static F32 sDistanceFactor;			// LOD distance factor
-
+		
 	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
 	static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
 
@@ -388,26 +388,6 @@ protected:
 	static S32 sNumLODChanges;
 
 	friend class LLVolumeImplFlexible;
-
-public:
-	bool notifyAboutCreatingTexture(LLViewerTexture *texture);
-	bool notifyAboutMissingAsset(LLViewerTexture *texture);
-
-private:
-	struct material_info 
-	{
-		LLRender::eTexIndex map;
-		U8 te;
-
-		material_info(LLRender::eTexIndex map_, U8 te_)
-			: map(map_)
-			, te(te_)
-		{}
-	};
-
-	typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
-	mmap_UUID_MAP_t	mWaitingTextureInfo;
-
 };
 
 #endif // LL_LLVOVOLUME_H
-- 
cgit v1.2.3


From 6464016c117693d391f8e5cdbc14816e298ec265 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 15 Nov 2017 19:15:49 +0200
Subject: MAINT-7997 Fixed dialog text failing to get focus when selected

---
 indra/newview/skins/default/xui/en/panel_notification.xml | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index 4d9316768b..c1a68fb9af 100644
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
@@ -71,7 +71,6 @@
       mouse_opaque="false"
       name="text_editor_box"
       read_only="true"
-      tab_stop="false"
       text_color="White"
       text_readonly_color="White"
       top="10"
-- 
cgit v1.2.3


From ab7c9526450e54a379edf60db5fc8f28b3acbca6 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <none@none>
Date: Thu, 16 Nov 2017 00:24:54 +0200
Subject: MAINT-7988 Received Items should be searchable via inventory

---
 indra/newview/llinventorybridge.cpp                | 20 ++++++++++--
 indra/newview/llpanelmaininventory.cpp             | 24 ++++++++++++--
 indra/newview/llpanelmarketplaceinbox.cpp          | 37 ++++++++++++++++++++++
 indra/newview/llpanelmarketplaceinbox.h            |  6 +++-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |  6 ++++
 indra/newview/llpanelmarketplaceinboxinventory.h   |  1 +
 6 files changed, 88 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 904bc29929..4d1a6451e5 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -43,6 +43,7 @@
 #include "llfloatermarketplacelistings.h"
 #include "llfloateroutfitphotopreview.h"
 #include "llfloatersidepanelcontainer.h"
+#include "llsidepanelinventory.h"
 #include "llfloaterworldmap.h"
 #include "llfolderview.h"
 #include "llfriendcard.h"
@@ -1828,11 +1829,24 @@ void LLItemBridge::gotoItem()
 	LLInventoryObject *obj = getInventoryObject();
 	if (obj && obj->getIsLinkType())
 	{
-		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
-		if (active_panel)
+		const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+		if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id))
 		{
-			active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
+			LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+			if (sidepanel_inventory && sidepanel_inventory->getInboxPanel())
+			{
+				sidepanel_inventory->getInboxPanel()->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
+			}
+		}
+		else
+		{
+			LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
+			if (active_panel)
+			{
+				active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
+			}
 		}
+
 	}
 }
 
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index ec80ff8de7..bf59d89b80 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -44,6 +44,7 @@
 #include "llfloaterreg.h"
 #include "llmenubutton.h"
 #include "lloutfitobserver.h"
+#include "llpanelmarketplaceinbox.h"
 #include "llpreviewtexture.h"
 #include "llresmgr.h"
 #include "llscrollcontainer.h"
@@ -483,7 +484,7 @@ void LLPanelMainInventory::onClearSearch()
 	if (mActivePanel && (getActivePanel() != mWornItemsPanel))
 	{
 		initially_active = mActivePanel->getFilter().isNotDefault();
-		mActivePanel->setFilterSubString(LLStringUtil::null);
+		setFilterSubString(LLStringUtil::null);
 		mActivePanel->setFilterTypes(0xffffffffffffffffULL);
 		mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS);
 	}
@@ -503,6 +504,16 @@ void LLPanelMainInventory::onClearSearch()
 		mActivePanel->getRootFolder()->scrollToShowSelection();
 	}
 	mFilterSubString = "";
+
+	LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+	if (sidepanel_inventory)
+	{
+		LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
+		if (inbox_panel)
+		{
+			inbox_panel->onClearSearch();
+		}
+	}
 }
 
 void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
@@ -534,6 +545,16 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
 
 	// set new filter string
 	setFilterSubString(mFilterSubString);
+
+	LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+	if (sidepanel_inventory)
+	{
+		LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
+		if (inbox_panel)
+		{
+			inbox_panel->onFilterEdit(search_string);
+		}
+	}
 }
 
 
@@ -848,7 +869,6 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
 
 	// Get data needed for filter display
 	U32 filter_types = mFilter->getFilterObjectTypes();
-	std::string filter_string = mFilter->getFilterSubString();
 	LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
 	U32 hours = mFilter->getHoursAgo();
 	U32 date_search_direction = mFilter->getDateSearchDirection();
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 79e079f6bd..8a86f4f63d 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -51,11 +51,15 @@ LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
 	, mFreshCountCtrl(NULL)
 	, mInboxButton(NULL)
 	, mInventoryPanel(NULL)
+	, mSavedFolderState(NULL)
 {
+	mSavedFolderState = new LLSaveFolderState();
+	mSavedFolderState->setApply(FALSE);
 }
 
 LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
 {
+	delete mSavedFolderState;
 }
 
 // virtual
@@ -96,6 +100,7 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 	// Set the sort order newest to oldest
 	mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE);
 	mInventoryPanel->getFilter().markDefault();
+	mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
 
 	// Set selection callback for proper update of inventory status buttons
 	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
@@ -193,6 +198,38 @@ U32 LLPanelMarketplaceInbox::getTotalItemCount() const
 	return item_count;
 }
 
+void LLPanelMarketplaceInbox::onClearSearch()
+{
+	if (mInventoryPanel)
+	{
+		mInventoryPanel->setFilterSubString(LLStringUtil::null);
+		mSavedFolderState->setApply(TRUE);
+		mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+		LLOpenFoldersWithSelection opener;
+		mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
+		mInventoryPanel->getRootFolder()->scrollToShowSelection();
+	}
+}
+
+void LLPanelMarketplaceInbox::onFilterEdit(const std::string& search_string)
+{
+	if (mInventoryPanel)
+	{
+
+		if (search_string == "")
+		{
+			onClearSearch();
+		}
+
+		if (!mInventoryPanel->getFilter().isNotDefault())
+		{
+			mSavedFolderState->setApply(FALSE);
+			mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+		}
+		mInventoryPanel->setFilterSubString(search_string);
+	}
+}
+
 std::string LLPanelMarketplaceInbox::getBadgeString() const
 {
 	std::string item_count_str("");
diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h
index 9eb74581a2..952e3a333a 100644
--- a/indra/newview/llpanelmarketplaceinbox.h
+++ b/indra/newview/llpanelmarketplaceinbox.h
@@ -28,7 +28,7 @@
 #define LL_LLPANELMARKETPLACEINBOX_H
 
 #include "llpanel.h"
-
+#include "llfolderview.h"
 class LLButton;
 class LLInventoryPanel;
 class LLUICtrl;
@@ -56,6 +56,9 @@ public:
 	
 	LLInventoryPanel * setupInventoryPanel();
 
+	void onClearSearch();
+	void onFilterEdit(const std::string& search_string);
+
 	U32 getFreshItemCount() const;
 	U32 getTotalItemCount() const;
 
@@ -71,6 +74,7 @@ private:
 	LLUICtrl *			mFreshCountCtrl;
 	LLButton *			mInboxButton;
 	LLInventoryPanel *	mInventoryPanel;
+	LLSaveFolderState*			mSavedFolderState;
 };
 
 
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index c5fda3c136..e08670eff3 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -62,6 +62,12 @@ LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params
 LLInboxInventoryPanel::~LLInboxInventoryPanel()
 {}
 
+void LLInboxInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
+{
+	LLInventoryPanel::initFromParams(params);
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
+}
+
 LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop)
 {
 	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index 66aafe83d1..b1335e2d71 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -46,6 +46,7 @@ public:
 	~LLInboxInventoryPanel();
 
 	// virtual
+	void initFromParams(const LLInventoryPanel::Params&);
 	LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
 	LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
 };
-- 
cgit v1.2.3


From 6fb3b50a29b03fb416db81a1871658219a9279b9 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 16 Nov 2017 18:11:38 +0200
Subject: MAINT-8006 FIXED The items from 'Received items' panel are not
 displayed in 'Worn' tab

---
 indra/newview/llinventorypanel.cpp     | 31 ++++---------------------------
 indra/newview/llpanelmaininventory.cpp |  4 +++-
 2 files changed, 7 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d610b920b9..798434a257 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1376,38 +1376,15 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 	if (active_panel)
 	{
 		LL_DEBUGS("Messaging") << "Highlighting" << obj_id  << LL_ENDL;
-		
-		LLViewerInventoryItem * item = gInventory.getItem(obj_id);
-		LLViewerInventoryCategory * cat = gInventory.getCategory(obj_id);
-		
-		bool in_inbox = false;
-		
-		LLViewerInventoryCategory * parent_cat = NULL;
-		
-		if (item)
-		{
-			parent_cat = gInventory.getCategory(item->getParentUUID());
-		}
-		else if (cat)
-		{
-			parent_cat = gInventory.getCategory(cat->getParentUUID());
-		}
-		
-		if (parent_cat)
-		{
-			in_inbox = (LLFolderType::FT_INBOX == parent_cat->getPreferredType());
-		}
+
+		bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
 		
 		if (in_inbox)
 		{
 			LLSidepanelInventory * sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
 			LLInventoryPanel * inventory_panel = NULL;
-			
-			if (in_inbox)
-			{
-				sidepanel_inventory->openInbox();
-				inventory_panel = sidepanel_inventory->getInboxPanel();
-			}
+			sidepanel_inventory->openInbox();
+			inventory_panel = sidepanel_inventory->getInboxPanel();
 
 			if (inventory_panel)
 			{
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index bf59d89b80..b004226bd5 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -179,7 +179,9 @@ BOOL LLPanelMainInventory::postBuild()
 		mWornItemsPanel->setFilterWorn();
 		mWornItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
 		mWornItemsPanel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS);
-		mWornItemsPanel->getFilter().markDefault();
+		LLInventoryFilter& worn_filter = mWornItemsPanel->getFilter();
+		worn_filter.setFilterCategoryTypes(worn_filter.getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
+		worn_filter.markDefault();
 		mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2));
 	}
 	mSearchTypeCombo  = getChild<LLComboBox>("search_type");
-- 
cgit v1.2.3


From 667f2fedef33b6fb217939290e6b097d7447de92 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 17 Nov 2017 17:21:25 +0200
Subject: MAINT-8013 FIXED Unnecessary tab change after using 'Show in Main
 panel' for items from 'Received items' panel

---
 indra/newview/llinventorypanel.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 798434a257..6e7f62d84a 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1367,7 +1367,9 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL main_panel)
 {
 	LLInventoryPanel *active_panel;
-	if (main_panel)
+	bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
+
+	if (main_panel && !in_inbox)
 	{
 		LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory")->selectAllItemsPanel();
 	}
@@ -1377,8 +1379,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 	{
 		LL_DEBUGS("Messaging") << "Highlighting" << obj_id  << LL_ENDL;
 
-		bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
-		
 		if (in_inbox)
 		{
 			LLSidepanelInventory * sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
-- 
cgit v1.2.3


From 8da9e0ffd73e30a55734864e49a6ec917e3bee00 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 17 Nov 2017 17:33:10 +0200
Subject: MAINT-72 unmapBuffer crash

---
 indra/llrender/llvertexbuffer.cpp | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6de2a973d2..8a4c21d6e4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1921,7 +1921,21 @@ void LLVertexBuffer::unmapBuffer()
 					const MappedRegion& region = mMappedVertexRegions[i];
 					S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
 					S32 length = sTypeSize[region.mType]*region.mCount;
-					glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
+					if (mSize >= length + offset)
+					{
+						glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*)mMappedData + offset);
+					}
+					else
+					{
+						GLint size = 0;
+						glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+						LL_WARNS() << "Attempted to map regions to a buffer that is too small, " 
+							<< "mapped size: " << mSize
+							<< ", gl buffer size: " << size
+							<< ", length: " << length
+							<< ", offset: " << offset
+							<< LL_ENDL;
+					}
 					stop_glerror();
 				}
 
@@ -1989,7 +2003,21 @@ void LLVertexBuffer::unmapBuffer()
 					const MappedRegion& region = mMappedIndexRegions[i];
 					S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
 					S32 length = sizeof(U16)*region.mCount;
-					glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
+					if (mIndicesSize >= length + offset)
+					{
+						glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
+					}
+					else
+					{
+						GLint size = 0;
+						glGetBufferParameterivARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+						LL_WARNS() << "Attempted to map regions to a buffer that is too small, " 
+							<< "mapped size: " << mIndicesSize
+							<< ", gl buffer size: " << size
+							<< ", length: " << length
+							<< ", offset: " << offset
+							<< LL_ENDL;
+					}
 					stop_glerror();
 				}
 
-- 
cgit v1.2.3


From 9de2af8b2dde7dc326f970d61950bebc565883f6 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 13 Nov 2017 14:26:15 +0200
Subject: MAINT-7847 Remake of 'white alpfa' fix

---
 indra/llprimitive/llmaterial.cpp   |  14 ++-
 indra/llprimitive/llmaterial.h     |  11 +++
 indra/newview/lldrawpoolavatar.cpp |   4 +-
 indra/newview/llface.cpp           |  36 +++++++-
 indra/newview/llface.h             |   5 +-
 indra/newview/llviewertexture.cpp  |  28 ++++++
 indra/newview/llviewertexture.h    |   5 +
 indra/newview/llvovolume.cpp       | 183 +++++++++++++++++++++++++++++++------
 indra/newview/llvovolume.h         |  22 ++++-
 indra/newview/pipeline.cpp         |   4 +-
 10 files changed, 270 insertions(+), 42 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index 57ceb3e11b..e6d2790a5f 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -106,10 +106,16 @@ LLMaterial::LLMaterial()
 	, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
 	, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 	, mAlphaMaskCutoff(0)
+	, mIsDiffuseAlphaInvalid(false)
+	, mIsNormalInvalid(false)
+	, mIsSpecularInvalid(false)
 {
 }
 
 LLMaterial::LLMaterial(const LLSD& material_data)
+	: mIsDiffuseAlphaInvalid(false)
+	, mIsNormalInvalid(false)
+	, mIsSpecularInvalid(false)
 {
 	fromLLSD(material_data);
 }
@@ -199,13 +205,17 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)
 	{
 		ret = getDiffuseAlphaMode();
 	}
+	if (mIsDiffuseAlphaInvalid && ret != DIFFUSE_ALPHA_MODE_DEFAULT)
+	{
+		ret = alpha_mode != DIFFUSE_ALPHA_MODE_NONE;
+	}
 
 	llassert(ret < SHADER_COUNT);
 
 	//next bit is whether or not specular map is present
 	const U32 SPEC_BIT = 0x4;
 
-	if (getSpecularID().notNull())
+	if (getSpecularID().notNull() && !mIsSpecularInvalid)
 	{
 		ret |= SPEC_BIT;
 	}
@@ -214,7 +224,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)
 	
 	//next bit is whether or not normal map is present
 	const U32 NORM_BIT = 0x8;
-	if (getNormalID().notNull())
+	if (getNormalID().notNull() && !mIsNormalInvalid)
 	{
 		ret |= NORM_BIT;
 	}
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index 9f52a3f6c1..2f23a50973 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -120,6 +120,13 @@ public:
 	void		setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
 
 	bool		isNull() const;
+	bool		isDiffuseAlphaInvalid() const { return mIsDiffuseAlphaInvalid; }
+	void		setDiffuseAlphaInvalid(bool is_invalid) { mIsDiffuseAlphaInvalid = is_invalid; }
+	bool		isNormalInvalid() const { return mIsNormalInvalid; }
+	void		setNormalInvalid(bool is_invalid) { mIsNormalInvalid = is_invalid; }
+	bool		isSpecularInvalid() const { return mIsSpecularInvalid; }
+	void		setSpecularInvalid(bool is_invalid) { mIsSpecularInvalid = is_invalid; }
+
 	static const LLMaterial null;
 
 	bool		operator == (const LLMaterial& rhs) const;
@@ -147,6 +154,10 @@ protected:
 	U8			mEnvironmentIntensity;
 	U8			mDiffuseAlphaMode;
 	U8			mAlphaMaskCutoff;
+
+	bool mIsDiffuseAlphaInvalid;
+	bool mIsNormalInvalid;
+	bool mIsSpecularInvalid;
 };
 
 typedef LLPointer<LLMaterial> LLMaterialPtr;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 8128790eb6..97dda072e7 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1818,7 +1818,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 				F32 env = mat->getEnvironmentIntensity()/255.f;
 
-				if (mat->getSpecularID().isNull())
+				if (mat->getSpecularID().isNull() || mat->isSpecularInvalid())
 				{
 					env = te->getShiny()*0.25f;
 					col.set(env,env,env,0);
@@ -1831,7 +1831,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
 				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
 
-				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && !mat->isDiffuseAlphaInvalid())
 				{
 					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
 				}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index c6fff6e57a..d502e686c7 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -344,6 +344,34 @@ void LLFace::dirtyTexture()
 	gPipeline.markTextured(drawablep);
 }
 
+void LLFace::notifyAboutCreatingTexture(LLViewerTexture *texture)
+{
+	LLDrawable* drawablep = getDrawable();
+	if(mVObjp.notNull() && mVObjp->getVolume())
+	{
+		LLVOVolume *vobj = drawablep->getVOVolume();
+		if(vobj && vobj->notifyAboutCreatingTexture(texture))
+		{
+			gPipeline.markTextured(drawablep);
+			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
+		}
+	}
+}
+
+void LLFace::notifyAboutMissingAsset(LLViewerTexture *texture)
+{
+	LLDrawable* drawablep = getDrawable();
+	if(mVObjp.notNull() && mVObjp->getVolume())
+	{
+		LLVOVolume *vobj = drawablep->getVOVolume();
+		if(vobj && vobj->notifyAboutMissingAsset(texture))
+		{
+			gPipeline.markTextured(drawablep);
+			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
+		}
+	}
+}
+
 void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
 {
 	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
@@ -1056,7 +1084,7 @@ bool LLFace::canRenderAsMask()
 	}
 	
 	LLMaterial* mat = te->getMaterialParams();
-	if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+	if (mat && !mat->isDiffuseAlphaInvalid() && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 	{
 		return false;
 	}
@@ -1290,14 +1318,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 			
 			if (LLPipeline::sRenderDeferred)
 			{ //store shiny in alpha if we don't have a specular map
-				if  (!mat || mat->getSpecularID().isNull())
+				if  (!mat || mat->getSpecularID().isNull() || mat->isSpecularInvalid())
 				{
 					shiny_in_alpha = true;
 				}
 			}
 			else
 			{
-				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK || mat->isDiffuseAlphaInvalid())
 				{
 					shiny_in_alpha = true;
 				}
@@ -1783,7 +1811,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 				std::vector<LLVector2> bump_tc;
 		
-				if (mat && !mat->getNormalID().isNull())
+				if (mat && !(mat->getNormalID().isNull() || mat->isNormalInvalid()))
 				{ //writing out normal and specular texture coordinates, not bump offsets
 					do_bump = false;
 				}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 2d88c6fa58..ee545acb94 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -230,10 +230,13 @@ public:
 
 	static U32 getRiggedDataMask(U32 type);
 
+	void	notifyAboutCreatingTexture(LLViewerTexture *texture);
+	void	notifyAboutMissingAsset(LLViewerTexture *texture);
+
 public: //aligned members
 	LLVector4a		mExtents[2];
 
-private:	
+private:
 	F32         adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
 	BOOL        calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
 public:
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 840176c1e0..e5a1bed48c 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -669,12 +669,36 @@ S8 LLViewerTexture::getType() const
 
 void LLViewerTexture::cleanup()
 {
+	notifyAboutMissingAsset();
+
 	mFaceList[LLRender::DIFFUSE_MAP].clear();
 	mFaceList[LLRender::NORMAL_MAP].clear();
 	mFaceList[LLRender::SPECULAR_MAP].clear();
 	mVolumeList.clear();
 }
 
+void LLViewerTexture::notifyAboutCreatingTexture()
+{
+	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+	{
+		for(U32 f = 0; f < mNumFaces[ch]; f++)
+		{
+			mFaceList[ch][f]->notifyAboutCreatingTexture(this);
+		}
+	}
+}
+
+void LLViewerTexture::notifyAboutMissingAsset()
+{
+	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+	{
+		for(U32 f = 0; f < mNumFaces[ch]; f++)
+		{
+			mFaceList[ch][f]->notifyAboutMissingAsset(this);
+		}
+	}
+}
+
 // virtual
 void LLViewerTexture::dump()
 {
@@ -1474,6 +1498,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 
 	res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
 
+	notifyAboutCreatingTexture();
+
 	setActive();
 
 	if (!needsToSaveRawImage())
@@ -2198,6 +2224,8 @@ void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing)
 	}
 	if (is_missing)
 	{
+		notifyAboutMissingAsset();
+
 		if (mUrl.empty())
 		{
 			LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 9208b4813e..c9dea17f63 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -175,6 +175,10 @@ protected:
 	void init(bool firstinit) ;
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
+
+	void notifyAboutMissingAsset();
+	void notifyAboutCreatingTexture();
+
 private:
 	friend class LLBumpImageList;
 	friend class LLUIImageList;
@@ -312,6 +316,7 @@ public:
 
 	void addToCreateTexture();
 
+
 	 // ONLY call from LLViewerTextureList
 	BOOL createTexture(S32 usename = 0);
 	void destroyTexture() ;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 20c54d06d3..206d34d7ea 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2051,28 +2051,148 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 	return res;
 }
 
+bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
+{
+	// Texture was created, process it and remove from wait list
+
+	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
+	if(range.first == range.second) return false;
+
+	bool needs_update = false;
+
+	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
+	{
+		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+		if (cur_material.isNull())
+		{
+			continue;
+		}
+
+		if (LLRender::DIFFUSE_MAP == range_it->second.map
+			&& GL_RGBA != texture->getPrimaryFormat()
+			&& cur_material->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+			&& cur_material->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT)
+		{
+			// We have non 32 bit texture with alpha, it is invalid
+
+			cur_material->setDiffuseAlphaInvalid(true);
+			needs_update = true;
+		}
+	}
+
+	//clear wait-list
+	mWaitingTextureInfo.erase(range.first, range.second);
+
+	return needs_update;
+}
+
+bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
+{
+	// Texture was marked as missing, process it and remove from wait list
+
+	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
+	if(range.first == range.second) return false;
+	
+	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
+	{
+		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+		if (cur_material.isNull())
+		{
+			continue;
+		}
+
+		switch (range_it->second.map)
+		{
+		case LLRender::DIFFUSE_MAP:
+			{
+				cur_material->setDiffuseAlphaInvalid(true);
+				break;
+			}
+		case LLRender::NORMAL_MAP:
+			{
+				cur_material->setNormalInvalid(true);
+				break;
+			}
+		case LLRender::SPECULAR_MAP:
+			{
+				cur_material->setSpecularInvalid(true);
+				break;
+			}
+		default:
+			break;
+		}
+	}
+
+	//clear wait-list
+	mWaitingTextureInfo.erase(range.first, range.second);
+
+	return true;
+}
+
 S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
 {
 	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
 
 	if(pMaterialParams)
-	{
-		LLViewerTexture* image = getTEImage(te);
-		LLGLenum image_format = image ? image->getPrimaryFormat() : GL_RGB;
-		LLMaterialPtr current_material = getTEMaterialParams(te);
+	{ //check all of them according to material settings
 
-		U8 new_diffuse_alpha_mode = pMaterialParams->getDiffuseAlphaMode();
+		LLViewerTexture *img_diffuse = getTEImage(te);
+		LLViewerTexture *img_normal = getTENormalMap(te);
+		LLViewerTexture *img_specular = getTESpecularMap(te);
 
-		if(new_diffuse_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+		llassert(NULL != img_diffuse);
+
+		//diffuse
+		if(NULL != img_diffuse)
 		{
-			new_diffuse_alpha_mode = (GL_RGB == image_format || 0 == image_format ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : new_diffuse_alpha_mode);
+			if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
+			{
+				// Texture information is missing, wait for it
+				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
+			}
+			else
+			{
+				if(img_diffuse->isMissingAsset())
+				{
+					pMaterial->setDiffuseAlphaInvalid(true);
+				}
+				else if (GL_RGBA != img_diffuse->getPrimaryFormat()
+						&& pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+						&& pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT)
+				{
+					pMaterial->setDiffuseAlphaInvalid(true);
+				}
+			}
 		}
 
-		if(pMaterialParams->getDiffuseAlphaMode() != new_diffuse_alpha_mode) {
-			//create new material
-			pMaterial = new LLMaterial(pMaterialParams->asLLSD());
-			pMaterial->setDiffuseAlphaMode(new_diffuse_alpha_mode);
-			LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
+		//normal
+		if(LLUUID::null != pMaterialParams->getNormalID())
+		{
+			if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
+			{
+				pMaterial->setNormalInvalid(true);
+			}
+			else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
+			{
+				// Texture information is missing, wait for it
+				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
+			}
+
+		}
+
+
+		//specular
+		if(LLUUID::null != pMaterialParams->getSpecularID())
+		{
+			if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
+			{
+				pMaterial->setSpecularInvalid(true);
+			}
+			else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
+			{
+				// Texture information is missing, wait for it
+				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
+			}
 		}
 	}
 
@@ -4365,7 +4485,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 				}
 
 				draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
-				draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+				draw_info->mDiffuseAlphaMode = mat->isDiffuseAlphaInvalid() ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : mat->getDiffuseAlphaMode();
 				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
 				
 		}
@@ -4634,11 +4754,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						}
 
 						LLMaterial* mat = te->getMaterialParams().get();
+						U8 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+						if (mat && !mat->isDiffuseAlphaInvalid())
+						{
+							alpha_mode = mat->getDiffuseAlphaMode();
+						}
 
 						if (mat && LLPipeline::sRenderDeferred)
 						{
-							U8 alpha_mode = mat->getDiffuseAlphaMode();
-
 							bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
 								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
 								te->getColor().mV[3] < 0.999f);
@@ -4658,11 +4781,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						{
 							bool fullbright = te->getFullbright();
 							bool is_alpha = type == LLDrawPool::POOL_ALPHA;
-							U8 mode = mat->getDiffuseAlphaMode();
-							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
-												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+							bool can_be_shiny = alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+												alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
 							
-							if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
+							if (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
 							{
 								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
 							}
@@ -4862,9 +4984,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull()  && !te->getMaterialID().isNull())
 							{
 								LLMaterial* mat = te->getMaterialParams().get();
-								if (mat->getNormalID().notNull())
+								if (mat->getNormalID().notNull() && !mat->isNormalInvalid())
 								{
-									if (mat->getSpecularID().notNull())
+									if (mat->getSpecularID().notNull() && !mat->isSpecularInvalid())
 									{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
 										if (normspec_count < MAX_FACE_COUNT)
 										{
@@ -4879,7 +5001,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 										}
 									}
 								}
-								else if (mat->getSpecularID().notNull())
+								else if (mat->getSpecularID().notNull() && !mat->isSpecularInvalid())
 								{ //has specular map but no normal map, needs texcoord2
 									if (spec_count < MAX_FACE_COUNT)
 									{
@@ -5536,13 +5658,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
 		
 			LLMaterial* mat = te->getMaterialParams().get();
-
+			U8 diffuse_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
 			bool can_be_shiny = true;
+
 			if (mat)
 			{
-				U8 mode = mat->getDiffuseAlphaMode();
-				can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
-								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+				diffuse_mode = mat->isDiffuseAlphaInvalid() ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : mat->getDiffuseAlphaMode();
+				can_be_shiny = diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+						diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
 			}
 
 			bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
@@ -5558,7 +5681,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 				//
 				if (te->getFullbright())
 				{
-					if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+					if (diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 					{
 						if (opaque)
 						{
@@ -5637,7 +5760,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 			}
 			else if (mat)
 			{
-				U8 mode = mat->getDiffuseAlphaMode();
+				U8 mode = diffuse_mode;
 				if (te->getColor().mV[3] < 0.999f)
 				{
 					mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
@@ -5733,7 +5856,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 				}
 				else if (fullbright || bake_sunlight)
 				{ //fullbright
-					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+					if (mat && diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 					{
 						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
 					}
@@ -5755,7 +5878,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 					else
 					{ //all around simple
 						llassert(mask & LLVertexBuffer::MAP_NORMAL);
-						if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+						if (mat && diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 						{ //material alpha mask can be respected in non-deferred
 							registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
 						}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index b07d416363..a331908320 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -380,7 +380,7 @@ public:
 	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
 	static F32 sLODFactor;				// LOD scale factor
 	static F32 sDistanceFactor;			// LOD distance factor
-		
+
 	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
 	static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
 
@@ -388,6 +388,26 @@ protected:
 	static S32 sNumLODChanges;
 
 	friend class LLVolumeImplFlexible;
+
+public:
+	bool notifyAboutCreatingTexture(LLViewerTexture *texture);
+	bool notifyAboutMissingAsset(LLViewerTexture *texture);
+
+private:
+	struct material_info 
+	{
+		LLRender::eTexIndex map;
+		U8 te;
+
+		material_info(LLRender::eTexIndex map_, U8 te_)
+			: map(map_)
+			, te(te_)
+		{}
+	};
+
+	typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
+	mmap_UUID_MAP_t	mWaitingTextureInfo;
+
 };
 
 #endif // LL_LLVOVOLUME_H
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d3be5fea1a..138d186e06 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1691,7 +1691,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
 		alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
 	}
 
-	if (alpha && mat)
+	if (alpha && mat && !mat->isDiffuseAlphaInvalid())
 	{
 		switch (mat->getDiffuseAlphaMode())
 		{
@@ -1712,7 +1712,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
 	{
 		return LLDrawPool::POOL_ALPHA;
 	}
-	else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
+	else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull() || mat->isNormalInvalid()))
 	{
 		return LLDrawPool::POOL_BUMP;
 	}
-- 
cgit v1.2.3


From 3bf1e4cb46676fe230732c47b57a646d956b036e Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 20 Nov 2017 17:58:18 +0200
Subject: MAINT-581 Terrain detail remains on High when Graphics Quality is set
 to Low

---
 indra/newview/llfloaterpreference.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 5222637039..5de7ca5289 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1304,7 +1304,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
 	BOOL shaders = ctrl_shader_enable->get();
 	if (shaders)
 	{
-		terrain_detail->setValue(1);
 		terrain_detail->setEnabled(FALSE);
 		terrain_text->setEnabled(FALSE);
 	}
-- 
cgit v1.2.3


From f72015980d8238ad0837365c782866a3af52f01d Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 21 Nov 2017 11:19:56 +0200
Subject: MAINT-8007 Music do not start playing after disabling

---
 indra/newview/llviewermedia.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 01b0dd0077..7c6cce5c58 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -791,6 +791,14 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 					LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
 				}
 			}
+            else
+            {
+                if(gAudiop && LLViewerMedia::hasParcelAudio() && gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
+                {
+                    LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
+                }
+            }
+
 			pimpl->setPriority(new_priority);
 
 			if(pimpl->getUsedInUI())
-- 
cgit v1.2.3


From c1e55d37b6f96a46d1c187c90508979b500eddf4 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 21 Nov 2017 18:32:18 +0200
Subject: MAINT-8016 Crash in LLFloaterAvatarRenderSettings::removePicker()

---
 indra/newview/llfloateravatarrendersettings.cpp              | 11 -----------
 indra/newview/llfloateravatarrendersettings.h                |  1 -
 indra/newview/skins/default/xui/en/floater_avatar_picker.xml |  5 -----
 3 files changed, 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
index 8bdb70a20d..b8f854feb3 100644
--- a/indra/newview/llfloateravatarrendersettings.cpp
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -89,20 +89,11 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()
     LLFloater::postBuild();
     mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
     mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
-    this->setVisibleCallback(boost::bind(&LLFloaterAvatarRenderSettings::removePicker, this));
     getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
 
 	return TRUE;
 }
 
-void LLFloaterAvatarRenderSettings::removePicker()
-{
-    if(mPicker.get())
-    {
-        mPicker.get()->closeFloater();
-    }
-}
-
 void LLFloaterAvatarRenderSettings::draw()
 {
     if(mNeedsUpdate)
@@ -263,8 +254,6 @@ void LLFloaterAvatarRenderSettings::onClickAdd(const LLSD& userdata)
     {
         root_floater->addDependentFloater(picker);
     }
-
-    mPicker = picker->getHandle();
 }
 
 void LLFloaterAvatarRenderSettings::callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting)
diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h
index 6790b24b90..00ee074f17 100644
--- a/indra/newview/llfloateravatarrendersettings.h
+++ b/indra/newview/llfloateravatarrendersettings.h
@@ -66,7 +66,6 @@ private:
     bool mNeedsUpdate;
     LLListContextMenu* mContextMenu;
     LLNameListCtrl* mAvatarSettingsList;
-    LLHandle<LLFloater> mPicker;
 
     std::string mNameFilter;
 };
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
index dddb258ed9..af6d11f47e 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
@@ -47,7 +47,6 @@
      top="20"
      width="500">
         <panel
-         border="none"
          height="150"
          label="Search"
          layout="topleft"
@@ -108,7 +107,6 @@
           </scroll_list>
         </panel>
         <panel
-         border="none"
          height="150"
          label="Friends"
          layout="topleft"
@@ -144,7 +142,6 @@
             <scroll_list
              follows="all"
              height="120"
-             border="false"
              layout="topleft"
              left="0"
              name="Friends"
@@ -154,7 +151,6 @@
         </panel>
 
         <panel
-         border="none"
          height="150"
          label="Near Me"
          layout="topleft"
@@ -213,7 +209,6 @@
              draw_heading="true"
              follows="all"
              height="100"
-             border="false"
              layout="topleft"
              left="0"
              name="NearMe"
-- 
cgit v1.2.3


From f1c76a376c1aeb194ddf7cfddc7e50fd4a9645af Mon Sep 17 00:00:00 2001
From: Ansariel <none@none>
Date: Mon, 16 Oct 2017 10:41:45 +0200
Subject: STORM-2151: Respect "Hide cursor while typing" user setting on
 Windows

---
 indra/llwindow/llwindowwin32.cpp | 19 ++++++++++++++++++-
 indra/llwindow/llwindowwin32.h   |  2 ++
 2 files changed, 20 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index b5ed53fd4f..62179e4d80 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -421,6 +421,11 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 	mKeyVirtualKey = 0;
 	mhDC = NULL;
 	mhRC = NULL;
+	
+	if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0))
+	{
+		mMouseVanish = TRUE;
+	}
 
 	// Initialize the keyboard
 	gKeyboard = new LLKeyboardWin32();
@@ -1680,7 +1685,7 @@ void LLWindowWin32::showCursorFromMouseMove()
 
 void LLWindowWin32::hideCursorUntilMouseMove()
 {
-	if (!mHideCursorPermanent)
+	if (!mHideCursorPermanent && mMouseVanish)
 	{
 		hideCursor();
 		mHideCursorPermanent = FALSE;
@@ -2668,6 +2673,18 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
 			return 0;			
 
 			break;
+
+		case WM_SETTINGCHANGE:
+			{
+				if (w_param == SPI_SETMOUSEVANISH)
+				{
+					if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0))
+					{
+						window_imp->mMouseVanish = TRUE;
+					}
+				}
+			}
+			break;
 		}
 
 	window_imp->mCallbacks->handlePauseWatchdog(window_imp);	
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 39ef9b31a4..cd6e5e4fa8 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -214,6 +214,8 @@ protected:
 	U32				mRawWParam;
 	U32				mRawLParam;
 
+	BOOL			mMouseVanish;
+
 	friend class LLWindowManager;
 };
 
-- 
cgit v1.2.3


From 629840e9a80d47d7224dbb6d557af07f194ca099 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 22 Nov 2017 16:48:54 +0200
Subject: MAINT-1804 Fixed bulk upload failures due to non-ansi symbols in
 names

---
 indra/newview/llfilepicker.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 7e92643b93..125a823e58 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -341,7 +341,7 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
 					dirname = filename + "\\";
 				else
 					mFiles.push_back(dirname + filename);
-				tptrw += filename.size();
+				tptrw += wcslen(tptrw);
 			}
 		}
 	}
-- 
cgit v1.2.3


From 6a025ddbbcbf5d37485192fc29dea6f275bc97b9 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 22 Nov 2017 16:58:17 +0200
Subject: MAINT-8027 Fixed URL-named group is displayed as a link in 'Group
 Inspector'

---
 indra/newview/llinspectgroup.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index a4fce36783..8332443162 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -205,7 +205,7 @@ void LLInspectGroup::nameUpdatedCallback(
 {
 	if (id == mGroupID)
 	{
-		getChild<LLUICtrl>("group_name")->setValue( LLSD(name) );
+		getChild<LLUICtrl>("group_name")->setValue(LLSD("<nolink>" + name + "</nolink>"));
 	}
 	
 	// Otherwise possibly a request for an older inspector, ignore it
-- 
cgit v1.2.3


From 22049830334de572ab703132aab353f2b20a3c15 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 24 Nov 2017 14:22:46 +0200
Subject: MAINT-8017 Avatar walks in half-bent position , without disabling
 "away" status

---
 indra/newview/llviewerwindow.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7b4895b862..364de1d810 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1405,11 +1405,6 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
 	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
 	LLVoiceClient::getInstance()->keyDown(key, mask);
 	
-	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
-	{
-		gAgent.clearAFK();
-	}
-
 	// *NOTE: We want to interpret KEY_RETURN later when it arrives as
 	// a Unicode char, not as a keydown.  Otherwise when client frame
 	// rate is really low, hitting return sends your chat text before
@@ -1423,7 +1418,13 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
     		return FALSE;
 	}
 
-	return gViewerKeyboard.handleKey(key, mask, repeated);
+	BOOL handled = gViewerKeyboard.handleKey(key, mask, repeated);
+	if (!handled || (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME))
+	{
+		gAgent.clearAFK();
+	}
+
+	return handled;
 }
 
 BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key,  MASK mask)
-- 
cgit v1.2.3


From 3d7dedff268cdedbea586c3e329c0682ee841290 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 24 Nov 2017 17:58:02 +0200
Subject: MAINT-8023 Viewer breaks URLs with internationalized domain names

---
 indra/llui/llurlentry.cpp    | 11 ++++++-----
 indra/llui/llurlregistry.cpp | 35 +++--------------------------------
 2 files changed, 9 insertions(+), 37 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index a4243ebfa1..a4dc5bcde1 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -190,31 +190,32 @@ bool LLUrlEntryBase::isWikiLinkCorrect(std::string url)
 
 std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
 {
-	LLUriParser up(unescapeUrl(url));
+	LLUriParser up(escapeUrl(url));
 	up.normalize();
 
 	std::string label;
 	up.extractParts();
 	up.glueFirst(label);
 
-	return label;
+	return unescapeUrl(label);
 }
 
 std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
 {
-	LLUriParser up(unescapeUrl(url));
+	std::string escaped_url = escapeUrl(url);
+	LLUriParser up(escaped_url);
 
 	std::string label;
 	up.extractParts();
 	up.glueFirst(label, false);
 
-	size_t pos = url.find(label);
+	size_t pos = escaped_url.find(label);
 	if (pos == std::string::npos)
 	{
 		return "";
 	}
 	pos += label.size();
-	return url.substr(pos);
+	return unescapeUrl(escaped_url.substr(pos));
 }
 
 
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index fa6593267a..ba6fa1e2e9 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -212,7 +212,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
 			}
 		}
 	}
-	
+
 	// did we find a match? if so, return its details in the match object
 	if (match_entry)
 	{
@@ -223,33 +223,6 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
 		// fill in the LLUrlMatch object and return it
 		std::string url = text.substr(match_start, match_end - match_start + 1);
 
-		LLUrlEntryBase *stripped_entry = NULL;
-		if((match_entry != mUrlEntryNoLink) && (match_entry != mUrlEntryHTTPLabel) && (match_entry !=mUrlEntrySLLabel)
-		        && LLStringUtil::containsNonprintable(url))
-		{
-			LLStringUtil::stripNonprintable(url);
-
-			std::vector<LLUrlEntryBase *>::iterator iter;
-			for (iter = mUrlEntry.begin(); iter != mUrlEntry.end(); ++iter)
-			{
-				LLUrlEntryBase *url_entry = *iter;
-				U32 start = 0, end = 0;
-				if (matchRegex(url.c_str(), url_entry->getPattern(), start, end))
-				{
-					if (mLLUrlEntryInvalidSLURL == *iter)
-					{
-						if(url_entry && url_entry->isSLURLvalid(url))
-						{
-							continue;
-						}
-					}
-					stripped_entry = url_entry;
-					break;
-				}
-			}
-		}
-
-
 		if (match_entry == mUrlEntryTrusted)
 		{
 			LLUriParser up(url);
@@ -257,12 +230,10 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
 			url = up.normalizedUri();
 		}
 
-		std::string url_label = stripped_entry? stripped_entry->getLabel(url, cb) : match_entry->getLabel(url, cb);
-		std::string url_query = stripped_entry? stripped_entry->getQuery(url) : match_entry->getQuery(url);
 		match.setValues(match_start, match_end,
 						match_entry->getUrl(url),
-						url_label,
-						url_query,
+						match_entry->getLabel(url, cb),
+						match_entry->getQuery(url),
 						match_entry->getTooltip(url),
 						match_entry->getIcon(url),
 						match_entry->getStyle(),
-- 
cgit v1.2.3


From 6d7c19623d44bbd9dcfcd047e3b3ab2120916481 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 27 Nov 2017 19:04:41 +0200
Subject: MAINT-8022 Crashes in unzip_llsd

---
 indra/llcommon/llsdserialize.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 3a219eb998..7f286f5e68 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -2188,7 +2188,6 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 		U8* new_result = (U8*)realloc(result, cur_size + have);
 		if (new_result == NULL)
 		{
-			LL_WARNS() << "Failed to unzip LLSD block: can't reallocate memory, current size: " << cur_size << " bytes; requested " << cur_size + have << " bytes." << LL_ENDL;
 			inflateEnd(&strm);
 			if (result)
 			{
-- 
cgit v1.2.3


From e5ef898728b5881eb1f233aa4e0dc9dbbd0991a5 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 27 Nov 2017 15:02:33 +0200
Subject: MAINT-8028 Fixed memory leak in allocateDataSize()

---
 indra/llimage/llimage.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 04085eb703..0fa0ef79d9 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -748,7 +748,11 @@ U8* LLImageBase::allocateData(S32 size)
 	{
 		size = 0;
 		mWidth = mHeight = 0;
-		mData = NULL;
+		if (mData)
+		{
+			deleteData(); // virtual
+			mData = NULL;
+		}
 	}
 	mDataSize = size;
 	claimMem(mDataSize);
@@ -775,6 +779,7 @@ U8* LLImageBase::reallocateData(S32 size)
 	disclaimMem(mDataSize);
 	mDataSize = size;
 	claimMem(mDataSize);
+	mBadBufferAllocation = false;
 	return mData;
 }
 
-- 
cgit v1.2.3


From dcfccc6f435610077592bbddcef2468c64f27f2f Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 28 Nov 2017 15:55:40 +0200
Subject: MAINT-8022 Crashes in unzip_llsd #2

---
 indra/llcommon/llsdserialize.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 7f286f5e68..ede212181d 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -2144,7 +2144,11 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 		
 	const U32 CHUNK = 65536;
 
-	U8 *in = new U8[size];
+	U8 *in = new(std::nothrow) U8[size];
+	if (!in)
+	{
+		return false;
+	}
 	is.read((char*) in, size); 
 
 	U8 out[CHUNK];
-- 
cgit v1.2.3


From 1c711ca0272a23895c7004f14caf035f16ecefdf Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 28 Nov 2017 16:05:29 +0200
Subject: MAINT-8029 Crash in onCompleted()

---
 indra/newview/llmeshrepository.cpp | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index df708013fc..850a25107f 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2918,9 +2918,12 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
 			// handler, optional first that takes a body, fallback second
 			// that requires a temporary allocation and data copy.
 			body_offset = mOffset - offset;
-			data = new U8[data_size - body_offset];
-			body->read(body_offset, (char *) data, data_size - body_offset);
-			LLMeshRepository::sBytesReceived += data_size;
+			data = new(std::nothrow) U8[data_size - body_offset];
+			if (data)
+			{
+				body->read(body_offset, (char *) data, data_size - body_offset);
+				LLMeshRepository::sBytesReceived += data_size;
+			}
 		}
 
 		processData(body, body_offset, data, data_size - body_offset);
@@ -2969,7 +2972,9 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 									  U8 * data, S32 data_size)
 {
 	LLUUID mesh_id = mMeshParams.getSculptID();
-	bool success = (! MESH_HEADER_PROCESS_FAILED) && gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+	bool success = (! MESH_HEADER_PROCESS_FAILED)
+		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
+		&& gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
 	llassert(success);
 	if (! success)
 	{
@@ -3093,7 +3098,9 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status)
 void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
 								   U8 * data, S32 data_size)
 {
-	if ((! MESH_LOD_PROCESS_FAILED) && gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))
+	if ((!MESH_LOD_PROCESS_FAILED)
+		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
+		&& gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))
 	{
 		// good fetch from sim, write to VFS for caching
 		LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);
@@ -3141,7 +3148,9 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status)
 void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
 										U8 * data, S32 data_size)
 {
-	if ((! MESH_SKIN_INFO_PROCESS_FAILED) && gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size))
+	if ((!MESH_SKIN_INFO_PROCESS_FAILED)
+		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
+		&& gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size))
 	{
 		// good fetch from sim, write to VFS for caching
 		LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
@@ -3187,7 +3196,9 @@ void LLMeshDecompositionHandler::processFailure(LLCore::HttpStatus status)
 void LLMeshDecompositionHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
 											 U8 * data, S32 data_size)
 {
-	if ((! MESH_DECOMP_PROCESS_FAILED) && gMeshRepo.mThread->decompositionReceived(mMeshID, data, data_size))
+	if ((!MESH_DECOMP_PROCESS_FAILED)
+		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
+		&& gMeshRepo.mThread->decompositionReceived(mMeshID, data, data_size))
 	{
 		// good fetch from sim, write to VFS for caching
 		LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
@@ -3232,7 +3243,9 @@ void LLMeshPhysicsShapeHandler::processFailure(LLCore::HttpStatus status)
 void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
 											U8 * data, S32 data_size)
 {
-	if ((! MESH_PHYS_SHAPE_PROCESS_FAILED) && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size))
+	if ((!MESH_PHYS_SHAPE_PROCESS_FAILED)
+		&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
+		&& gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size))
 	{
 		// good fetch from sim, write to VFS for caching
 		LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
-- 
cgit v1.2.3


From 110c6ad1521a3a412f2696289483cc705bd5b5e8 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 29 Nov 2017 16:14:43 +0200
Subject: MAINT-8033 Trash Count - folders are included in Alert

---
 indra/newview/skins/default/xui/en/notifications.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9af4b299de..c6460c3c72 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6233,7 +6233,7 @@ The folder &apos;[FOLDERNAME]&apos; is a system folder. Deleting system folders
    icon="alertmodal.tga"
    name="ConfirmEmptyTrash"
    type="alertmodal">
-[COUNT] items will be permanently deleted. Are you sure you want to permanently delete the contents of your Trash?
+[COUNT] items and folders will be permanently deleted. Are you sure you want to permanently delete the contents of your Trash?
     <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
-- 
cgit v1.2.3


From 62390a7e0a33f744de059fa51bc96643d707c2ec Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 1 Dec 2017 15:58:22 +0200
Subject: MAINT-8034 Folder depth was not counted correctly

---
 indra/newview/llinventoryfunctions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 8b50e4248e..e056ccebee 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1178,7 +1178,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn
     int incoming_folder_depth = get_folder_levels(inv_cat);
     // Compute the nested folders level we're inserting ourselves in
     // Note: add 1 when inserting under a listing folder as we need to take the root listing folder in the count
-    int insertion_point_folder_depth = (root_folder ? get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()) + 1 : 0);
+    int insertion_point_folder_depth = (root_folder ? get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()) + 1 : 1);
 
     // Get the version folder: that's where the folders and items counts start from
     const LLViewerInventoryCategory * version_folder = (insertion_point_folder_depth >= 2 ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL);
-- 
cgit v1.2.3


From f32f0aff4b19461677cedfcab7bd3f66689cfe03 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 1 Dec 2017 18:50:39 +0200
Subject: MAINT-8036 Fixed Viewer freezing when overwriting existing snpshot
 with new one.

---
 indra/newview/llviewerwindow.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 364de1d810..28f6837679 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4442,7 +4442,8 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
 		err = LLFile::stat( filepath, &stat_info );
 		i++;
 	}
-	while( -1 != err );  // search until the file is not found (i.e., stat() gives an error).
+	while( -1 != err  // Search until the file is not found (i.e., stat() gives an error).
+			&& is_snapshot_name_loc_set); // Or stop if we are rewriting.
 
 	LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
 	return image->save(filepath);
-- 
cgit v1.2.3


From b44e479893a1d000886a65bec5161f447e6a325a Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 4 Dec 2017 19:04:09 +0200
Subject: MAINT-7993 Fixed on uploading inventory will show up but won't
 display uploaded item

---
 indra/newview/llinventorypanel.cpp    | 11 ++++++++---
 indra/newview/llinventorypanel.h      |  8 ++++++--
 indra/newview/llmeshrepository.cpp    | 16 +++++++++++-----
 indra/newview/llviewerassetupload.cpp | 15 ++++++++++-----
 4 files changed, 35 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 6e7f62d84a..83a8678c86 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1364,7 +1364,7 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 }
 
 //static
-void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL main_panel)
+void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL main_panel, BOOL take_keyboard_focus, BOOL reset_filter)
 {
 	LLInventoryPanel *active_panel;
 	bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
@@ -1379,6 +1379,11 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 	{
 		LL_DEBUGS("Messaging") << "Highlighting" << obj_id  << LL_ENDL;
 
+		if (reset_filter)
+		{
+			reset_inventory_filter();
+		}
+
 		if (in_inbox)
 		{
 			LLSidepanelInventory * sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
@@ -1388,7 +1393,7 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 
 			if (inventory_panel)
 			{
-				inventory_panel->setSelection(obj_id, TAKE_FOCUS_YES);
+				inventory_panel->setSelection(obj_id, take_keyboard_focus);
 			}
 		}
 		else
@@ -1398,7 +1403,7 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 			{
 				floater_inventory->setFocus(TRUE);
 			}
-			active_panel->setSelection(obj_id, TAKE_FOCUS_YES);
+			active_panel->setSelection(obj_id, take_keyboard_focus);
 		}
 	}
 }
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index d849647bb6..ace0ea7f42 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -220,8 +220,12 @@ public:
 	// Find whichever inventory panel is active / on top.
 	// "Auto_open" determines if we open an inventory panel if none are open.
 	static LLInventoryPanel *getActiveInventoryPanel(BOOL auto_open = TRUE);
-	
-	static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL main_panel = FALSE);
+
+	static void openInventoryPanelAndSetSelection(BOOL auto_open,
+													const LLUUID& obj_id,
+													BOOL main_panel = FALSE,
+													BOOL take_keyboard_focus = TAKE_FOCUS_YES,
+													BOOL reset_filter = FALSE);
 
 	void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
 	void removeItemID(const LLUUID& id);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 850a25107f..29a4ad001a 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4840,26 +4840,32 @@ void on_new_single_inventory_upload_complete(
         gInventory.notifyObservers();
         success = true;
 
+        LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
+
         // Show the preview panel for textures and sounds to let
         // user know that the image (or snapshot) arrived intact.
-        LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
+        LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
         if (panel)
         {
-            LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
 
             panel->setSelection(
                 server_response["new_inventory_item"].asUUID(),
                 TAKE_FOCUS_NO);
-
-            // restore keyboard focus
-            gFocusMgr.setKeyboardFocus(focus);
         }
+        else
+        {
+            LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, server_response["new_inventory_item"].asUUID(), TRUE, TAKE_FOCUS_NO, TRUE);
+        }
+
+        // restore keyboard focus
+        gFocusMgr.setKeyboardFocus(focus);
     }
     else
     {
         LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
     }
 
+    // Todo: This is mesh repository code, is following code really needed?
     // remove the "Uploading..." message
     LLUploadDialog::modalUploadFinished();
 
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 01b4fcfbe1..4f68c9a98e 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -760,17 +760,22 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
         {
             success = true;
 
+            LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
+
             // Show the preview panel for textures and sounds to let
             // user know that the image (or snapshot) arrived intact.
-            LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
+            LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
             if (panel)
             {
-                LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
                 panel->setSelection(serverInventoryItem, TAKE_FOCUS_NO);
-
-                // restore keyboard focus
-                gFocusMgr.setKeyboardFocus(focus);
             }
+            else
+            {
+                LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, TRUE, TAKE_FOCUS_NO, TRUE);
+            }
+
+            // restore keyboard focus
+            gFocusMgr.setKeyboardFocus(focus);
         }
         else
         {
-- 
cgit v1.2.3


From 57337ffbbb78d5b7d2f5d4ef59eabe687eb2d3cd Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 5 Dec 2017 12:34:41 +0200
Subject: revert change for MAINT-8017

---
 indra/newview/llviewerwindow.cpp | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 364de1d810..a5ab38e62d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1404,7 +1404,12 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
 {
 	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
 	LLVoiceClient::getInstance()->keyDown(key, mask);
-	
+
+	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+	{
+		gAgent.clearAFK();
+	}
+
 	// *NOTE: We want to interpret KEY_RETURN later when it arrives as
 	// a Unicode char, not as a keydown.  Otherwise when client frame
 	// rate is really low, hitting return sends your chat text before
@@ -1418,13 +1423,7 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
     		return FALSE;
 	}
 
-	BOOL handled = gViewerKeyboard.handleKey(key, mask, repeated);
-	if (!handled || (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME))
-	{
-		gAgent.clearAFK();
-	}
-
-	return handled;
+	return gViewerKeyboard.handleKey(key, mask, repeated);
 }
 
 BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key,  MASK mask)
-- 
cgit v1.2.3


From 8bceb809022981221baa288df673fbb2c59cdd04 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 5 Dec 2017 18:19:30 +0200
Subject: MAINT-2880 Particle generator object doesn't start displaying
 particles, when unblocking the owner of this object

---
 indra/newview/llviewerobject.cpp  | 7 ++++---
 indra/newview/llviewerobject.h    | 2 +-
 indra/newview/llviewerpartsim.cpp | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index e86d39e9d0..228c686065 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5118,9 +5118,10 @@ void LLViewerObject::updateText()
 	}
 }
 
-bool LLViewerObject::isOwnerInMuteList()
+bool LLViewerObject::isOwnerInMuteList(LLUUID id)
 {
-	if (isAvatar() || mOwnerID.isNull())
+	LLUUID owner_id = id.isNull() ? mOwnerID : id;
+	if (isAvatar() || owner_id.isNull())
 	{
 		return false;
 	}
@@ -5132,7 +5133,7 @@ bool LLViewerObject::isOwnerInMuteList()
 	}
 	else
 	{
-		muted = LLMuteList::getInstance()->isMuted(mOwnerID);
+		muted = LLMuteList::getInstance()->isMuted(owner_id);
 
 		const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1;
 		mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 4f826b9eac..21c95d5533 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -422,7 +422,7 @@ public:
 	void updateText(); // update text label position
 	virtual void updateDrawable(BOOL force_damped); // force updates on static objects
 
-	bool isOwnerInMuteList();
+	bool isOwnerInMuteList(LLUUID item_id = LLUUID());
 
 	void setDrawableState(U32 state, BOOL recursive = TRUE);
 	void clearDrawableState(U32 state, BOOL recursive = TRUE);
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index e8ea0eb26d..b066793e3d 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -712,7 +712,7 @@ void LLViewerPartSim::updateSimulation()
 				upd = FALSE;
 			}
 
-			if(vobj && vobj->isOwnerInMuteList())
+			if(vobj && vobj->isOwnerInMuteList(mViewerPartSources[i]->getOwnerUUID()))
 			{
 				upd = FALSE;
 			}
-- 
cgit v1.2.3


From 34d3b49d1f6ae7e07d615cb1f98d5ad45fbb638d Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 5 Dec 2017 17:54:17 +0200
Subject: MAINT-2124 Texture allocation issues

---
 indra/llimage/llimagej2c.cpp     | 25 ++++++++++++++++--------
 indra/newview/lltexturecache.cpp | 41 +++++++++++++++++++++++++---------------
 indra/newview/lltexturefetch.cpp | 16 +++++++++++++---
 3 files changed, 56 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 68694496bc..c40df009d8 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -369,19 +369,28 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)
 	else
 	{
 		U8 *data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), file_size);
-		apr_size_t bytes_read = file_size;
-		apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read	
-		infile.close() ;
-
-		if (s != APR_SUCCESS || (S32)bytes_read != file_size)
+		if (!data)
 		{
-			FREE_MEM(LLImageBase::getPrivatePool(), data);
-			setLastError("Unable to read entire file");
+			infile.close();
+			setLastError("Out of memory", filename);
 			res = false;
 		}
 		else
 		{
-			res = validate(data, file_size);
+			apr_size_t bytes_read = file_size;
+			apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read	
+			infile.close();
+
+			if (s != APR_SUCCESS || (S32)bytes_read != file_size)
+			{
+				FREE_MEM(LLImageBase::getPrivatePool(), data);
+				setLastError("Unable to read entire file");
+				res = false;
+			}
+			else
+			{
+				res = validate(data, file_size);
+			}
 		}
 	}
 	
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 435d833345..6da6aba4fb 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -452,27 +452,38 @@ bool LLTextureCacheRemoteWorker::doRead()
 		size = llmin(size, mDataSize);
 		// Allocate the read buffer
 		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), size);
-		S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, 
-											 mReadData, offset, size, mCache->getLocalAPRFilePool());
-		if (bytes_read != size)
+		if (mReadData)
+		{
+			S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, 
+												 mReadData, offset, size, mCache->getLocalAPRFilePool());
+			if (bytes_read != size)
+			{
+				LL_WARNS() << "LLTextureCacheWorker: "  << mID
+						<< " incorrect number of bytes read from header: " << bytes_read
+						<< " / " << size << LL_ENDL;
+				FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+				mReadData = NULL;
+				mDataSize = -1; // failed
+				done = true;
+			}
+			// If we already read all we expected, we're actually done
+			if (mDataSize <= bytes_read)
+			{
+				done = true;
+			}
+			else
+			{
+				mState = BODY;
+			}
+		}
+		else
 		{
 			LL_WARNS() << "LLTextureCacheWorker: "  << mID
-					<< " incorrect number of bytes read from header: " << bytes_read
-					<< " / " << size << LL_ENDL;
-			FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+				<< " failed to allocate memory for reading: " << mDataSize << LL_ENDL;
 			mReadData = NULL;
 			mDataSize = -1; // failed
 			done = true;
 		}
-		// If we already read all we expected, we're actually done
-		if (mDataSize <= bytes_read)
-		{
-			done = true;
-		}
-		else
-		{
-			mState = BODY;
-		}
 	}
 
 	// Fourth state / stage : read the rest of the data from the UUID based cached file
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index f917faadd4..1f7796e6d0 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -1760,7 +1760,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mRequestedSize -= src_offset;			// Make requested values reflect useful part
 				mRequestedOffset += src_offset;
 			}
-			
+
+			U8 * buffer = (U8 *)ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size);
+			if (!buffer)
+			{
+				// abort. If we have no space for packet, we have not enough space to decode image
+				setState(DONE);
+				LL_WARNS(LOG_TXT) << mID << " abort: out of memory" << LL_ENDL;
+				releaseHttpSemaphore();
+				return true;
+			}
+
 			if (mFormattedImage.isNull())
 			{
 				// For now, create formatted image based on extension
@@ -1780,10 +1790,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			{
 				mFileSize = total_size + 1 ; //flag the file is not fully loaded.
 			}
-			
-			U8 * buffer = (U8 *) ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size);
+
 			if (cur_size > 0)
 			{
+				// Copy previously collected data into buffer
 				memcpy(buffer, mFormattedImage->getData(), cur_size);
 			}
 			mHttpBufferArray->read(src_offset, (char *) buffer + cur_size, append_size);
-- 
cgit v1.2.3


From 84ea0ab778e486279d32c101f4d9f5377ef94109 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 6 Dec 2017 17:48:01 +0200
Subject: MAINT-8042 Crash in LLViewerRegion::capabilitiesReceived()

---
 indra/newview/llvoicevivox.cpp | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 25df528d89..025b315b1d 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -776,13 +776,8 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
 bool LLVivoxVoiceClient::provisionVoiceAccount()
 {
     LL_INFOS("Voice") << "Provisioning voice account." << LL_ENDL;
-    while (!gAgent.getRegion())
-    {
-        // *TODO* Set up a call back on agent that sends a message to a pump we can use to wake up.
-        llcoro::suspend();
-    }
 
-    while (!gAgent.getRegion()->capabilitiesReceived())
+    while (!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived())
     {
         // *TODO* Pump a message for wake up.
         llcoro::suspend();
-- 
cgit v1.2.3


From bc179e3b269aca63ad1c856d305e26969836e774 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 7 Dec 2017 11:10:51 +0200
Subject: MAINT-8059 New head attachment slots are not rendered invisible in
 mouselook

---
 indra/newview/character/avatar_lad.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 90f06746c9..df30f46002 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -530,7 +530,7 @@
      location="ATTACH_FACE_JAW"
      position="0.000 0.000 0.000"
      rotation="0 0 0"
-     visible_in_first_person="true"/>
+     visible_in_first_person="false"/>
 
     <attachment_point
      id="48"
@@ -541,7 +541,7 @@
      location="ATTACH_FACE_LEAR"
      position="0.000 0.000 0.000"
      rotation="0 0 0"
-     visible_in_first_person="true"/>
+     visible_in_first_person="false"/>
 
     <attachment_point
      id="49"
@@ -552,7 +552,7 @@
      location="ATTACH_FACE_REAR"
      position="0.000 0.000 0.000"
      rotation="0 0 0"
-     visible_in_first_person="true"/>
+     visible_in_first_person="false"/>
 
     <attachment_point
      id="50"
@@ -563,7 +563,7 @@
      location="ATTACH_FACE_LEYE"
      position="0.000 0.000 0.000"
      rotation="0 0 0"
-     visible_in_first_person="true"/>
+     visible_in_first_person="false"/>
 
     <attachment_point
      id="51"
@@ -574,7 +574,7 @@
      location="ATTACH_FACE_REYE"
      position="0.000 0.000 0.000"
      rotation="0 0 0"
-     visible_in_first_person="true"/>
+     visible_in_first_person="false"/>
 
     <attachment_point
      id="52"
@@ -585,7 +585,7 @@
      location="ATTACH_FACE_TONGUE"
      position="0.000 0.000 0.000"
      rotation="0 0 0"
-     visible_in_first_person="true"/>
+     visible_in_first_person="false"/>
 
     <attachment_point
      id="53"
-- 
cgit v1.2.3


From 6fe00fd9adb967ff4da8b1ee53030a7f2e0ff052 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 6 Dec 2017 19:40:58 +0200
Subject: MAINT-8058 Fixed background requests on every prim edit

---
 indra/newview/llfloatermediasettings.cpp      |  8 +++--
 indra/newview/llfloatertools.cpp              | 49 ++++++++++++++++++---------
 indra/newview/llfloatertools.h                |  4 +--
 indra/newview/llpanelmediasettingsgeneral.cpp |  7 ++--
 indra/newview/llpanelmediasettingsgeneral.h   |  2 +-
 5 files changed, 47 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 4fd5c0587a..2afd889609 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -171,8 +171,12 @@ void LLFloaterMediaSettings::onClose(bool app_quitting)
 void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable )
 {
 	if (sInstance->hasFocus()) return;
-	
-	sInstance->clearValues(editable);
+
+	// Clear values
+	sInstance->mPanelMediaSettingsGeneral->clearValues(sInstance->mPanelMediaSettingsGeneral, editable, false /*don't update preview*/);
+	sInstance->mPanelMediaSettingsSecurity->clearValues(sInstance->mPanelMediaSettingsSecurity,	editable);
+	sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions,  editable);
+
 	// update all panels with values from simulator
 	sInstance->mPanelMediaSettingsGeneral->
 		initValues( sInstance->mPanelMediaSettingsGeneral, media_settings, editable );
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 2869256d09..9c3f0922b8 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -1317,7 +1317,6 @@ void LLFloaterTools::getMediaState()
 	
 	std::string multi_media_info_str = LLTrans::getString("Multiple Media");
 	std::string media_title = "";
-	mNeedMediaTitle = false;
 	// update UI depending on whether "object" (prim or face) has media
 	// and whether or not you are allowed to edit it.
 	
@@ -1335,17 +1334,18 @@ void LLFloaterTools::getMediaState()
 			{
 				// initial media title is the media URL (until we get the name)
 				media_title = media_data_get.getHomeURL();
-
-				// kick off a navigate and flag that we need to update the title
-				navigateToTitleMedia( media_data_get.getHomeURL() );
-				mNeedMediaTitle = true;
+				navigateToTitleMedia(media_title);
+			}
+			else
+			{
+				// all faces might be empty. Make sure we will navigate next time.
+				navigateToTitleMedia(std::string());
 			}
-			// else all faces might be empty. 
 		}
 		else // there' re Different Medias' been set on on the faces.
 		{
 			media_title = multi_media_info_str;
-			mNeedMediaTitle = false;
+			navigateToTitleMedia(media_title);
 		}
 		
 		getChildView("media_tex")->setEnabled(bool_has_media && editable);
@@ -1362,7 +1362,7 @@ void LLFloaterTools::getMediaState()
 		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
 		{
 			media_title = multi_media_info_str;
-			mNeedMediaTitle = false;
+			navigateToTitleMedia(media_title);
 		}
 		else
 		{
@@ -1371,10 +1371,12 @@ void LLFloaterTools::getMediaState()
 			{
 				// initial media title is the media URL (until we get the name)
 				media_title = media_data_get.getHomeURL();
-
-				// kick off a navigate and flag that we need to update the title
-				navigateToTitleMedia( media_data_get.getHomeURL() );
-				mNeedMediaTitle = true;
+				navigateToTitleMedia(media_title);
+			}
+			else
+			{
+				// Make sure we will navigate next time.
+				navigateToTitleMedia(std::string());
 			}
 		}
 		
@@ -1472,16 +1474,31 @@ void LLFloaterTools::clearMediaSettings()
 //
 void LLFloaterTools::navigateToTitleMedia( const std::string url )
 {
-	if ( mTitleMedia )
+	std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+	if (url.empty() || multi_media_info_str == url)
+	{
+		// nothing to show
+		mNeedMediaTitle = false;
+	}
+	else if (mTitleMedia)
 	{
 		LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
-		if ( media_plugin )
+
+		if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin?
 		{
 			// if it's a movie, we don't want to hear it
 			media_plugin->setVolume( 0 );
 		};
-		mTitleMedia->navigateTo( url );
-	};
+
+		// check if url changed or if we need a new media source
+		if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+		{
+			mTitleMedia->navigateTo( url );
+		}
+
+		// flag that we need to update the title (even if no request were made)
+		mNeedMediaTitle = true;
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 8f586f7da6..ffff564ad4 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -102,8 +102,6 @@ public:
 	void onClickBtnAddMedia();
 	void onClickBtnEditMedia();
 	void clearMediaSettings();
-	void updateMediaTitle();
-	void navigateToTitleMedia( const std::string url );
 	bool selectedMediaEditable();
 	void updateLandImpacts();
 
@@ -116,6 +114,8 @@ private:
 	void refreshMedia();
 	void getMediaState();
 	void updateMediaSettings();
+	void navigateToTitleMedia( const std::string url ); // navigate if changed
+	void updateMediaTitle();
 	static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
 	static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
 	static void setObjectType( LLPCode pcode );
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index d7c43c224c..3522189842 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -196,7 +196,7 @@ void LLPanelMediaSettingsGeneral::draw()
 
 ////////////////////////////////////////////////////////////////////////////////
 // static 
-void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable)
+void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable, bool update_preview)
 {	
 	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
 	self->mAutoLoop->clear();
@@ -217,7 +217,10 @@ void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable)
 	self->mHeightPixels ->setEnabled(editable);
 	self->mHomeURL ->setEnabled(editable);
 	self->mWidthPixels ->setEnabled(editable);
-	self->updateMediaPreview();
+	if (update_preview)
+	{
+		self->updateMediaPreview();
+	}
 }
 
 // static
diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h
index 0ae1401ab2..06793d91fc 100644
--- a/indra/newview/llpanelmediasettingsgeneral.h
+++ b/indra/newview/llpanelmediasettingsgeneral.h
@@ -59,7 +59,7 @@ public:
 
 	void setParent( LLFloaterMediaSettings* parent );
 	static void initValues( void* userdata, const LLSD& media_settings ,bool editable);
-	static void clearValues( void* userdata, bool editable);
+	static void clearValues( void* userdata, bool editable, bool update_preview = true);
 	
 	// Navigates the current selected face to the Home URL.
 	// If 'only_if_current_is_empty' is "true", it only performs
-- 
cgit v1.2.3


From 72b0ce5cb081c400972b01b1fbe23cba4b95b007 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 6 Dec 2017 19:40:58 +0200
Subject: MAINT-8058 Simplification

---
 indra/newview/llfloatertools.cpp | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 9c3f0922b8..c9d664c7c4 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -1334,18 +1334,12 @@ void LLFloaterTools::getMediaState()
 			{
 				// initial media title is the media URL (until we get the name)
 				media_title = media_data_get.getHomeURL();
-				navigateToTitleMedia(media_title);
-			}
-			else
-			{
-				// all faces might be empty. Make sure we will navigate next time.
-				navigateToTitleMedia(std::string());
 			}
+			// else all faces might be empty. 
 		}
 		else // there' re Different Medias' been set on on the faces.
 		{
 			media_title = multi_media_info_str;
-			navigateToTitleMedia(media_title);
 		}
 		
 		getChildView("media_tex")->setEnabled(bool_has_media && editable);
@@ -1362,7 +1356,6 @@ void LLFloaterTools::getMediaState()
 		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
 		{
 			media_title = multi_media_info_str;
-			navigateToTitleMedia(media_title);
 		}
 		else
 		{
@@ -1371,12 +1364,6 @@ void LLFloaterTools::getMediaState()
 			{
 				// initial media title is the media URL (until we get the name)
 				media_title = media_data_get.getHomeURL();
-				navigateToTitleMedia(media_title);
-			}
-			else
-			{
-				// Make sure we will navigate next time.
-				navigateToTitleMedia(std::string());
 			}
 		}
 		
@@ -1385,6 +1372,8 @@ void LLFloaterTools::getMediaState()
 		getChildView("delete_media")->setEnabled(TRUE);
 		getChildView("add_media")->setEnabled(editable);
 	}
+
+	navigateToTitleMedia(media_title);
 	media_info->setText(media_title);
 	
 	// load values for media settings
-- 
cgit v1.2.3


From fbbac52dd93b013cf237445855d4b1510fff56e5 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Fri, 8 Dec 2017 19:58:01 +0200
Subject: MAINT-8044 Fixed crash in LLFloaterIMNearbyChatToastPanel::init();
 algorythmic improvement for MAINT-6891

---
 indra/newview/llchatitemscontainerctrl.cpp | 35 +++++++++++++++---------------
 1 file changed, 18 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index f5721fb348..eddc87efcd 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -242,27 +242,28 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
 
 	S32 chars_in_line = mMsgText->getRect().getWidth() / messageFont->getWidth("c");
 	S32 max_lines = notification["available_height"].asInteger() / (mMsgText->getTextPixelHeight() + 4);
-	S32 new_line_chars = std::count(messageText.begin(), messageText.end(), '\n');
-	S32 lines_count = (messageText.size() - new_line_chars) / chars_in_line + new_line_chars + 1;
+	int lines = 0;
+	int chars = 0;
 
-	//Remove excessive chars if message is not fit in available height. MAINT-6891
-	if(lines_count > max_lines)
+	//Remove excessive chars if message does not fit in available height. MAINT-6891
+	std::string::iterator it;
+	for (it = messageText.begin(); it < messageText.end() && lines < max_lines; it++)
 	{
-		while(lines_count > max_lines)
+		if (*it == '\n')
+			++lines;
+		else
+			++chars;
+
+		if (chars >= chars_in_line)
 		{
-			std::size_t nl_pos = messageText.rfind('\n');
-			if (nl_pos != std::string::npos)
-			{
-				nl_pos = nl_pos > messageText.length() - chars_in_line? nl_pos : messageText.length() - chars_in_line;
-				messageText.erase(messageText.begin() + nl_pos, messageText.end());
-			}
-			else
-			{
-				messageText.erase(messageText.end() - chars_in_line, messageText.end());
-			}
-			new_line_chars = std::count(messageText.begin(), messageText.end(), '\n');
-			lines_count = (messageText.size() - new_line_chars) / chars_in_line + new_line_chars;
+			chars = 0;
+			++lines;
 		}
+	}
+
+	if (it < messageText.end())
+	{
+		messageText.erase(it, messageText.end());
 		messageText += " ...";
 	}
 
-- 
cgit v1.2.3


From d86616cc6670882da2ecd23c3089d71869bb7c2c Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Mon, 11 Dec 2017 13:50:24 +0000
Subject: Merged in MAINT-8066 "Breasts Bounce" increases at low fps.

Approved-by: Andrey Lihatskiy <andreylproductengine@lindenlab.com>
Approved-by: Simon Linden <simon@lindenlab.com>
Approved-by: Maxim Nikolenko <maximnproductengine@lindenlab.com>
---
 indra/newview/llphysicsmotion.cpp | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index 69f5dd1914..08d734ddac 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -44,7 +44,7 @@ typedef std::map<std::string, std::string> controller_map_t;
 typedef std::map<std::string, F32> default_controller_map_t;
 
 #define MIN_REQUIRED_PIXEL_AREA_AVATAR_PHYSICS_MOTION 0.f
-#define TIME_ITERATION_STEP 0.1f
+#define TIME_ITERATION_STEP 0.05f
 
 inline F64 llsgn(const F64 a)
 {
@@ -549,6 +549,18 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
 	
 	// Break up the physics into a bunch of iterations so that differing framerates will show
 	// roughly the same behavior.
+	// Explanation/example: Lets assume we have a bouncing object. Said abjects bounces at a
+	// trajectory that has points A>B>C. Object bounces from A to B with specific speed.
+	// It needs time T to move from A to B.
+	// As long as our frame's time significantly smaller then T our motion will be split into
+	// multiple parts. with each part speed will decrease. Object will reach B position (roughly)
+	// and bounce/fall back to A.
+	// But if frame's time (F_T) is larger then T, object will move with same speed for whole F_T
+	// and will jump over point B up to C ending up with increased amplitude. To avoid that we
+	// split F_T into smaller portions so that when frame's time is too long object can virtually
+	// bounce at right (relatively) position.
+	// Note: this doesn't look to be optimal, since it provides only "roughly same" behavior, but
+	// irregularity at higher fps looks to be insignificant so it works good enough for low fps.
 	for (F32 time_iteration = 0; time_iteration <= time_delta; time_iteration += TIME_ITERATION_STEP)
 	{
 		F32 time_iteration_step = TIME_ITERATION_STEP;
-- 
cgit v1.2.3


From 4133caebe36b3433036c6b7a4301288f0f695de9 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 11 Dec 2017 19:31:36 +0200
Subject: MAINT-2177 User was able to create a landmark for remote location

---
 indra/newview/llpanelplaces.cpp | 22 ++++++++++++++++++++--
 indra/newview/llpanelplaces.h   |  4 ++++
 2 files changed, 24 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index ed942fc7fc..48dd45480e 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -395,11 +395,16 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 			mPlaceInfoType = key_type;
 			mPosGlobal.setZero();
 			mItem = NULL;
+			mRegionId.setNull();
 			togglePlaceInfoPanel(TRUE);
 
 			if (mPlaceInfoType == AGENT_INFO_TYPE)
 			{
 				mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
+				if (gAgent.getRegion())
+				{
+					mRegionId = gAgent.getRegion()->getRegionID();
+				}
 			}
 			else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
 			{
@@ -472,6 +477,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	if (!parcel_mgr)
 		return;
 
+	mParcelLocalId = parcel_mgr->getAgentParcel()->getLocalID();
+
 	// Start using LLViewerParcelMgr for land selection if
 	// information about nearby land is requested.
 	// Otherwise stop using land selection and deselect land.
@@ -828,10 +835,21 @@ void LLPanelPlaces::onOverflowButtonClicked()
 	{
 		menu = mPlaceMenu;
 
+		bool landmark_item_enabled = false;
+		LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+		if (is_agent_place_info_visible
+			&& gAgent.getRegion()
+			&& mRegionId == gAgent.getRegion()->getRegionID()
+			&& parcel_mgr
+			&& parcel_mgr->getAgentParcel()->getLocalID() == mParcelLocalId)
+		{
+			// Floater still shows location identical to agent's position
+			landmark_item_enabled = !LLLandmarkActions::landmarkAlreadyExists();
+		}
+
 		// Enable adding a landmark only for agent current parcel and if
 		// there is no landmark already pointing to that parcel in agent's inventory.
-		menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(is_agent_place_info_visible &&
-																 !LLLandmarkActions::landmarkAlreadyExists());
+		menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(landmark_item_enabled);
 		// STORM-411
 		// Creating landmarks for remote locations is impossible.
 		// So hide menu item "Make a Landmark" in "Teleport History Profile" panel.
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index c3d1b9bc53..27f991c202 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -146,6 +146,10 @@ private:
 	// Information type currently shown in Place Information panel
 	std::string					mPlaceInfoType;
 
+	// Region and parcel ids, to detect location changes in case of AGENT_INFO_TYPE
+	LLUUID						mRegionId;
+	S32							mParcelLocalId;
+
 	bool						isLandmarkEditModeOn;
 
 	// Holds info whether "My Landmarks" and "Teleport History" tabs have been created.
-- 
cgit v1.2.3


From 27a3961168b958ce612bb12f0e56891a60144864 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 12 Dec 2017 16:54:59 +0200
Subject: MAINT-8071 Handle initialization crash better

---
 indra/newview/llviewerwindow.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index df0921954c..e9ecd1fca6 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1957,7 +1957,11 @@ void LLViewerWindow::initBase()
 	// (But wait to add it as a child of the root view so that it will be in front of the 
 	// other views.)
 	MainPanel* main_view = new MainPanel();
-	main_view->buildFromFile("main_view.xml");
+	if (!main_view->buildFromFile("main_view.xml"))
+	{
+		LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file main_view.xml, "
+				<< "if this problem happens again, please validate your installation." << LL_ENDL;
+	}
 	main_view->setShape(full_window);
 	getRootView()->addChild(main_view);
 
-- 
cgit v1.2.3


From 9db2de69f15723518b7129dd198332520e958b85 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 13 Dec 2017 12:47:25 +0200
Subject: MAINT-8061 Consider including folder count along with object count

---
 indra/newview/llinventorybridge.cpp                | 18 +++++++-
 indra/newview/llinventorybridge.h                  |  3 ++
 indra/newview/llinventorypanel.cpp                 | 50 ++++++++++++++++++++++
 indra/newview/llinventorypanel.h                   |  2 +
 indra/newview/llpanelmaininventory.cpp             | 10 +++++
 indra/newview/llpanelmaininventory.h               |  6 ++-
 .../skins/default/xui/en/panel_main_inventory.xml  |  9 ++--
 7 files changed, 90 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 4d1a6451e5..77c77023b1 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2213,8 +2213,22 @@ std::string LLFolderBridge::getLabelSuffix() const
     {
         return llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str());
     }
-    
-    return LLInvFVBridge::getLabelSuffix();
+    std::string suffix = "";
+    if(mShowDescendantsCount)
+    {
+        LLInventoryModel::cat_array_t cat_array;
+        LLInventoryModel::item_array_t item_array;
+        gInventory.collectDescendents(getUUID(), cat_array, item_array, TRUE);
+        S32 count = item_array.size();
+        if(count > 0)
+        {
+            std::ostringstream oss;
+            oss << count;
+            suffix = " ( " + oss.str() + " Items )";
+        }
+    }
+
+    return LLInvFVBridge::getLabelSuffix() + suffix;
 }
 
 LLFontGL::StyleFlags LLFolderBridge::getLabelStyle() const
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index fd532c609c..8fa15c082b 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -293,6 +293,8 @@ public:
 	virtual std::string getLabelSuffix() const;
 	virtual LLFontGL::StyleFlags getLabelStyle() const;
 
+	void setShowDescendantsCount(bool show_count) {mShowDescendantsCount = show_count;}
+
 	virtual BOOL renameItem(const std::string& new_name);
 
 	virtual BOOL removeItem();
@@ -373,6 +375,7 @@ protected:
 	bool							mCallingCards;
 	bool							mWearables;
 	bool							mIsLoading;
+	bool							mShowDescendantsCount;
 	LLTimer							mTimeSinceRequestStart;
     std::string                     mMessage;
 	LLRootHandle<LLFolderBridge> mHandle;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 83a8678c86..2762c7af82 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1110,6 +1110,56 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 			fv->startRenamingSelectedItem();
 		}
 	}
+
+	std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();
+	LLFolderViewItem* prev_folder_item = getItemByID(mPreviousSelectedFolder);
+
+	if (selected_items.size() == 1)
+	{
+		std::set<LLFolderViewItem*>::const_iterator iter = selected_items.begin();
+		LLFolderViewItem* folder_item = (*iter);
+		if(folder_item && (folder_item != prev_folder_item))
+		{
+			LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem());
+			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
+			{
+				if(prev_folder_item)
+				{
+					LLFolderBridge* prev_bridge = (LLFolderBridge*)prev_folder_item->getViewModelItem();
+					if(prev_bridge)
+					{
+						prev_bridge->clearDisplayName();
+						prev_bridge->setShowDescendantsCount(false);
+						prev_folder_item->refresh();
+					}
+				}
+
+				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
+				if(bridge)
+				{
+					bridge->clearDisplayName();
+					bridge->setShowDescendantsCount(true);
+					folder_item->refresh();
+					mPreviousSelectedFolder = bridge->getUUID();
+				}
+			}
+		}
+	}
+	else
+	{
+		if(prev_folder_item)
+		{
+			LLFolderBridge* prev_bridge = (LLFolderBridge*)prev_folder_item->getViewModelItem();
+			if(prev_bridge)
+			{
+				prev_bridge->clearDisplayName();
+				prev_bridge->setShowDescendantsCount(false);
+				prev_folder_item->refresh();
+			}
+		}
+		mPreviousSelectedFolder = LLUUID();
+	}
+
 }
 
 void LLInventoryPanel::doCreate(const LLSD& userdata)
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index ace0ea7f42..3829fb734d 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -258,6 +258,8 @@ protected:
 	LLHandle<LLFolderView>      mFolderRoot;
 	LLScrollContainer*			mScroller;
 
+	LLUUID						mPreviousSelectedFolder;
+
 	LLFolderViewModelInventory	mInventoryViewModel;
     LLPointer<LLFolderViewGroupedItemBridge> mGroupedItemBridge;
 	Params						mParams;	// stored copy of parameter block
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index b004226bd5..db9d61c637 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -708,8 +708,17 @@ void LLPanelMainInventory::updateItemcountText()
 		LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
 	}
 
+	if(mCategoryCount != gInventory.getCategoryCount())
+	{
+		mCategoryCount = gInventory.getCategoryCount();
+		mCategoryCountString = "";
+		LLLocale locale(LLLocale::USER_LOCALE);
+		LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
+	}
+
 	LLStringUtil::format_map_t string_args;
 	string_args["[ITEM_COUNT]"] = mItemCountString;
+	string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
 	string_args["[FILTER]"] = getFilterText();
 
 	std::string text = "";
@@ -728,6 +737,7 @@ void LLPanelMainInventory::updateItemcountText()
 	}
 	
     mCounterCtrl->setValue(text);
+    mCounterCtrl->setToolTip(text);
 }
 
 void LLPanelMainInventory::onFocusReceived()
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 2904d5de76..732a3b04e3 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -132,7 +132,7 @@ private:
 
 	LLFilterEditor*				mFilterEditor;
 	LLTabContainer*				mFilterTabs;
-    LLUICtrl*                   mCounterCtrl;
+	LLUICtrl*					mCounterCtrl;
 	LLHandle<LLFloater>			mFinderHandle;
 	LLInventoryPanel*			mActivePanel;
 	LLInventoryPanel*			mWornItemsPanel;
@@ -141,7 +141,9 @@ private:
 	std::string					mFilterText;
 	std::string					mFilterSubString;
 	S32							mItemCount;
-	std::string 				mItemCountString;
+	std::string					mItemCountString;
+	S32							mCategoryCount;
+	std::string					mCategoryCountString;
 	LLComboBox*					mSearchTypeCombo;
 
 
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index df70398599..d77fbdec0a 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -13,26 +13,27 @@
   </panel.string>
   <panel.string
    name="ItemcountFetching">
-    Fetching [ITEM_COUNT] Items... [FILTER]
+    Fetching [ITEM_COUNT] Items and [CATEGORY_COUNT] Folders... [FILTER]
   </panel.string>
   <panel.string
    name="ItemcountCompleted">
-    [ITEM_COUNT] Items [FILTER]
+    [ITEM_COUNT] Items and [CATEGORY_COUNT] Folders [FILTER]
   </panel.string>
   <panel.string
    name="ItemcountUnknown">
-    Fetched [ITEM_COUNT] Items [FILTER]
+    Fetched [ITEM_COUNT] Items and [CATEGORY_COUNT] Folders [FILTER]
   </panel.string>
   <text
 		     type="string"
 		     length="1"
-		     follows="left|top"
+		     follows="left|top|right"
 		     height="13"
 		     layout="topleft"
     		 left="12"
 		     name="ItemcountText"
 		     font="SansSerifMedium"
 		     text_color="EmphasisColor"
+		     use_ellipses="true"
 		     top_pad="0"
 		     width="300">
     Items:
-- 
cgit v1.2.3


From b309f058084d87744534adf647226b0a209a65f9 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 13 Dec 2017 14:20:50 +0200
Subject: MAINT-8061 Consider including folder count along with object count

---
 indra/newview/llinventorybridge.cpp            | 4 +++-
 indra/newview/llinventorybridge.h              | 3 ++-
 indra/newview/skins/default/xui/en/strings.xml | 2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 77c77023b1..3acfaeb049 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2224,7 +2224,9 @@ std::string LLFolderBridge::getLabelSuffix() const
         {
             std::ostringstream oss;
             oss << count;
-            suffix = " ( " + oss.str() + " Items )";
+            LLStringUtil::format_map_t args;
+            args["[ITEMS_COUNT]"] = oss.str();
+            suffix = " " + LLTrans::getString("InventoryItemsCount", args);
         }
     }
 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 8fa15c082b..fd5c0433b1 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -268,7 +268,8 @@ public:
 	:	LLInvFVBridge(inventory, root, uuid),
 		mCallingCards(FALSE),
 		mWearables(FALSE),
-		mIsLoading(false)
+		mIsLoading(false),
+		mShowDescendantsCount(false)
 	{}
 		
 	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE);
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index d7c8f95a3a..2aa5d2e5df 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2329,7 +2329,7 @@ If you continue to receive this message, please contact Second Life support for
 	<string name="InventoryMarketplaceListingsNoItems">
         Drag folders to this area to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].
 	</string>
-
+	<string name="InventoryItemsCount">( [ITEMS_COUNT] Items )</string>
 	<string name="Marketplace Validation Log"></string>
 	<string name="Marketplace Validation Warning Stock">stock folder must be contained by a version folder</string>
 	<string name="Marketplace Validation Error Mixed Stock">: Error: all items in a stock folder must be no-copy and of the same type</string>
-- 
cgit v1.2.3


From ae41f0497e17afb5c87bf9f10a21393fd36e3ffb Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 13 Dec 2017 17:08:38 +0200
Subject: MAINT-8085 'Edit Outfit' in "Appearance" continuously display
 "Loading...", when in this section no objects.

---
 indra/newview/llwearableitemslist.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index ee2270c323..5fb3d62445 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -645,7 +645,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
 		setRightMouseDownCallback(boost::bind(&LLWearableItemsList::onRightClick, this, _2, _3));
 	}
 	mWornIndicationEnabled = p.worn_indication_enabled;
-	setNoItemsCommentText(LLTrans::getString("LoadingData"));
+	setNoItemsCommentText(LLTrans::getString("NoneFound"));
 }
 
 // virtual
-- 
cgit v1.2.3


From 8fb9dd88df33a20667697a13294fc6c5ed902c00 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 14 Dec 2017 15:48:02 +0200
Subject: MAINT-8089 FIXED User A can't unblock text from user B when use
 right-click menu in chat

---
 indra/newview/llavataractions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 8fe684ad79..f0b74e7439 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -1011,7 +1011,7 @@ void LLAvatarActions::toggleMute(const LLUUID& id, U32 flags)
 	LLAvatarNameCache::get(id, &av_name);
 
 	LLMuteList* mute_list = LLMuteList::getInstance();
-	bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
+	bool is_muted = mute_list->isMuted(id, flags);
 
 	LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 	if (!is_muted)
-- 
cgit v1.2.3


From 062be76dd515d3c6630c0a2c8ff953ef22ff3a0d Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 15 Dec 2017 12:43:54 +0000
Subject: MAINT-4354 Render stalls in object heavy regions

---
 indra/newview/llviewerobjectlist.cpp  | 10 +++++++---
 indra/newview/llviewertexturelist.cpp |  5 +----
 indra/newview/llviewertexturelist.h   |  3 ---
 3 files changed, 8 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 3c83e3a006..fede9a792f 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -732,9 +732,9 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 	S32 num_updates, max_value;
 	if (NUM_BINS - 1 == mCurBin)
 	{
+		// Remainder (mObjects.size() could have changed)
 		num_updates = (S32) mObjects.size() - mCurLazyUpdateIndex;
 		max_value = (S32) mObjects.size();
-		gTextureList.setUpdateStats(TRUE);
 	}
 	else
 	{
@@ -791,10 +791,14 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 	mCurLazyUpdateIndex = max_value;
 	if (mCurLazyUpdateIndex == mObjects.size())
 	{
+		// restart
 		mCurLazyUpdateIndex = 0;
+		mCurBin = 0; // keep in sync with index (mObjects.size() could have changed)
+	}
+	else
+	{
+		mCurBin = (mCurBin + 1) % NUM_BINS;
 	}
-
-	mCurBin = (mCurBin + 1) % NUM_BINS;
 
 	LLVOAvatar::cullAvatarsByPixelArea();
 }
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d7080051da..fb8e897dbd 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -92,7 +92,6 @@ LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type)
 
 LLViewerTextureList::LLViewerTextureList() 
 	: mForceResetTextureStats(FALSE),
-	mUpdateStats(FALSE),
 	mMaxResidentTexMemInMegaBytes(0),
 	mMaxTotalTextureMemInMegaBytes(0),
 	mInitialized(FALSE)
@@ -103,7 +102,6 @@ void LLViewerTextureList::init()
 {			
 	mInitialized = TRUE ;
 	sNumImages = 0;
-	mUpdateStats = TRUE;
 	mMaxResidentTexMemInMegaBytes = (U32Bytes)0;
 	mMaxTotalTextureMemInMegaBytes = (U32Bytes)0;
 	
@@ -1171,7 +1169,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
 
 void LLViewerTextureList::updateImagesUpdateStats()
 {
-	if (mUpdateStats && mForceResetTextureStats)
+	if (mForceResetTextureStats)
 	{
 		for (image_priority_list_t::iterator iter = mImageList.begin();
 			 iter != mImageList.end(); )
@@ -1179,7 +1177,6 @@ void LLViewerTextureList::updateImagesUpdateStats()
 			LLViewerFetchedTexture* imagep = *iter++;
 			imagep->resetTextureStats();
 		}
-		mUpdateStats = FALSE;
 		mForceResetTextureStats = FALSE;
 	}
 }
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 070544063a..281d23c671 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -124,8 +124,6 @@ public:
 
 	void handleIRCallback(void **data, const S32 number);
 
-	void setUpdateStats(BOOL b)			{ mUpdateStats = b; }
-
 	S32Megabytes	getMaxResidentTexMem() const	{ return mMaxResidentTexMemInMegaBytes; }
 	S32Megabytes getMaxTotalTextureMem() const   { return mMaxTotalTextureMemInMegaBytes;}
 	S32 getNumImages()					{ return mImageList.size(); }
@@ -224,7 +222,6 @@ private:
 	std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
 
 	BOOL mInitialized ;
-	BOOL mUpdateStats;
 	S32Megabytes	mMaxResidentTexMemInMegaBytes;
 	S32Megabytes mMaxTotalTextureMemInMegaBytes;
 	LLFrameTimer mForceDecodeTimer;
-- 
cgit v1.2.3


From efeab1d5b5146000b535bb68ad14e82ab8867c1b Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 15 Dec 2017 17:52:42 +0200
Subject: MAINT-8098 FIXED The Viewer uses http: for the splash page even when
 configured for https:

---
 indra/newview/llpanellogin.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 0bcbdf7e67..c76985f42e 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -801,7 +801,8 @@ void LLPanelLogin::loadLoginPage()
 	params["login_content_version"] = gSavedSettings.getString("LoginContentVersion");
 
 	// Make an LLURI with this augmented info
-	LLURI login_uri(LLURI::buildHTTP(login_page.authority(),
+	std::string url = login_page.scheme().empty()? login_page.authority() : login_page.scheme() + "://" + login_page.authority();
+	LLURI login_uri(LLURI::buildHTTP(url,
 									 login_page.path(),
 									 params));
 
-- 
cgit v1.2.3


From 5b60199bb08b70dde89bade04c1cb00a3361945e Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 15 Dec 2017 19:41:34 +0200
Subject: MAINT-8064 Crashes in lodReceived()

---
 indra/newview/llmeshrepository.cpp | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 29a4ad001a..25bd0d855e 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1727,8 +1727,17 @@ bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U
 	}
 
 	LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
-	std::string mesh_string((char*) data, data_size);
-	std::istringstream stream(mesh_string);
+	std::istringstream stream;
+	try
+	{
+		std::string mesh_string((char*)data, data_size);
+		stream.str(mesh_string);
+	}
+	catch (std::bad_alloc)
+	{
+		// out of memory, we won't be able to process this mesh
+		return false;
+	}
 
 	if (volume->unpackVolumeFaces(stream, data_size))
 	{
-- 
cgit v1.2.3


From 1f56b223d74ada38e287f034f21b71e2e4dbb1e5 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 18 Dec 2017 15:15:54 +0200
Subject: MAINT-8101 Added sanity check to confirm crash location

---
 indra/llrender/llvertexbuffer.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2761a90566..35c771b61b 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1057,10 +1057,12 @@ LLVertexBuffer::~LLVertexBuffer()
 
 	if (mFence)
 	{
+		// Sanity check. We have weird crashes in this destructor (on delete). Yet mFence is disabled.
+		// TODO: mFence was added in scope of SH-2038, but was never enabled, consider removing mFence.
+		LL_ERRS() << "LLVertexBuffer destruction failed" << LL_ENDL;
 		delete mFence;
+		mFence = NULL;
 	}
-	
-	mFence = NULL;
 
 	sVertexCount -= mNumVerts;
 	sIndexCount -= mNumIndices;
-- 
cgit v1.2.3


From dedaabe9ec74cdeb3d1ecc83fcd597696116d524 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 20 Dec 2017 18:46:41 +0200
Subject: MAINT-1251 Fixed Search Error when Double Clicking on Sales Tags in
 WorldMap

---
 indra/newview/llfloatersearch.cpp | 1 +
 indra/newview/llworldmapview.cpp  | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index a446b767ac..66e832111b 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -100,6 +100,7 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) :
 	mCategoryPaths["events"]       = "search/events";
 	mCategoryPaths["groups"]       = "search/groups";
 	mCategoryPaths["wiki"]         = "search/wiki";
+	mCategoryPaths["land"]         = "land";
 	mCategoryPaths["destinations"] = "destinations";
 	mCategoryPaths["classifieds"]  = "classifieds";
 }
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 62fad32246..9ae788a409 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1750,8 +1750,10 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
 		case MAP_ITEM_LAND_FOR_SALE:
 		case MAP_ITEM_LAND_FOR_SALE_ADULT:
 			{
+				LLVector3d pos_global = viewPosToGlobal(x, y);
+				LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
 				LLFloaterReg::hideInstance("world_map");
-				LLFloaterReg::showInstance("search", LLSD().with("category", "destinations").with("query", id));
+				LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", info->getName()));
 				break;
 			}
 		case MAP_ITEM_CLASSIFIED:
-- 
cgit v1.2.3


From d3ef8e02a9e6e5cb394a07e294a07aab051a060f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 21 Dec 2017 18:24:54 +0200
Subject: MAINT-8110 clear password field after failed login instead of showing
 fake dots

---
 indra/newview/llpanellogin.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index c76985f42e..fc8914c4f9 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -492,7 +492,7 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
 	LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
 	if(authenticator.isMap() && 
 	   authenticator.has("secret") && 
-	   (authenticator["secret"].asString().size() > 0))
+	   (authenticator["secret"].asString().size() > 0) && remember)
 	{
 		
 		// This is a MD5 hex digest of a password.
-- 
cgit v1.2.3


From 6ea525f6af15d83f32a3241cfa867b09ff3bdc2c Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 22 Dec 2017 14:20:25 +0200
Subject: MAINT-8120 Account that contains last name Resident cannot see his
 Favorites on Login Screen

---
 indra/newview/llpanellogin.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index fc8914c4f9..c876c1c149 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -299,12 +299,24 @@ void LLPanelLogin::addFavoritesToStartLocation()
 
 	// Load favorites into the combo.
 	std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
+	LLStringUtil::toLower(user_defined_name);
 	std::replace(user_defined_name.begin(), user_defined_name.end(), '.', ' ');
 	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
 	std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
 	mUsernameLength = user_defined_name.length();
 	updateLoginButtons();
 
+	std::string::size_type index = user_defined_name.find(' ');
+	if (index != std::string::npos)
+	{
+		std::string username = user_defined_name.substr(0, index);
+		std::string lastname = user_defined_name.substr(index+1);
+		if (lastname == "resident")
+		{
+			user_defined_name = username;
+		}
+	}
+
 	LLSD fav_llsd;
 	llifstream file;
 	file.open(filename.c_str());
-- 
cgit v1.2.3


From 7de6475a0a61dcd79bd8b11519c01efba953293d Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 3 Jan 2018 18:45:02 +0200
Subject: MAINT-8125 "New" tag remains visible when searching items in Received
 Items panel

---
 indra/llui/llbadge.cpp                             |  2 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp | 10 ++++------
 indra/newview/llpanelmarketplaceinboxinventory.h   |  4 ++--
 3 files changed, 7 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp
index 42726de0ad..15b6899d74 100644
--- a/indra/llui/llbadge.cpp
+++ b/indra/llui/llbadge.cpp
@@ -224,7 +224,7 @@ void LLBadge::draw()
 	{
 		LLView* owner_view = mOwner.get();
 
-		if (owner_view)
+		if (owner_view && owner_view->isInVisibleChain())
 		{
 			//
 			// Calculate badge size based on label text
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index e08670eff3..2d2ba30e9b 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -146,18 +146,16 @@ void LLInboxFolderViewFolder::draw()
 	LLFolderViewFolder::draw();
 }
 
-void LLInboxFolderViewFolder::selectItem()
+BOOL LLInboxFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	deFreshify();
-
-	LLFolderViewFolder::selectItem();
+	return LLFolderViewFolder::handleMouseDown(x, y, mask);
 }
 
-void LLInboxFolderViewFolder::toggleOpen()
+BOOL LLInboxFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
 	deFreshify();
-
-	LLFolderViewFolder::toggleOpen();
+	return LLFolderViewFolder::handleDoubleClick(x, y, mask);
 }
 
 void LLInboxFolderViewFolder::computeFreshness()
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index b1335e2d71..d398cdafed 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -69,8 +69,8 @@ public:
     void addItem(LLFolderViewItem* item);
 	void draw();
 	
-	void selectItem();
-	void toggleOpen();
+	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
 
 	void computeFreshness();
 	void deFreshify();
-- 
cgit v1.2.3


From 0daaf96436d4f597efe882e4c8978d5ffe1ebfc3 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 4 Jan 2018 19:52:42 +0200
Subject: MAINT-8107 Fixed Framerate drops when facing away from objects

Don't clear buffers if they are already free
---
 indra/newview/llvovolume.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f77b48ff80..7b4d8ef329 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -628,7 +628,7 @@ void LLVOVolume::updateTextures()
 		if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
 		{ //delete vertex buffer to free up some VRAM
 			LLSpatialGroup* group  = mDrawable->getSpatialGroup();
-			if (group)
+			if (group && (group->mVertexBuffer.notNull() || !group->mBufferMap.empty() || !group->mDrawMap.empty()))
 			{
 				group->destroyGL(true);
 
-- 
cgit v1.2.3


From 7d156389e46cfb3c0bb135e1b3eb873b24beaebe Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Mon, 18 Dec 2017 20:29:50 +0200
Subject: MAINT-8043 Fix for bad_alloc crash in LLImageGL::setImage()

---
 indra/llrender/llimagegl.cpp | 40 +++++++++++++++++++++++++++++-----------
 indra/llrender/llimagegl.h   |  2 +-
 2 files changed, 30 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 20cba68f84..89500dcc04 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -622,7 +622,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
 }
 
 static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage");
-void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
+BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 {
 	LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
 	bool is_compressed = false;
@@ -787,19 +787,33 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						llassert(prev_mip_data);
 						llassert(cur_mip_size == bytes*4);
 #endif
-						U8* new_data = new U8[bytes];
+						U8* new_data = new(std::nothrow) U8[bytes];
+						if (!new_data)
+						{
+							stop_glerror();
+
+							if (prev_mip_data)
+								delete[] prev_mip_data;
+							if (cur_mip_data)
+								delete[] cur_mip_data;
+							
+							mGLTextureCreated = false;
+							return FALSE;
+						}
+						else
+						{
 
 #ifdef SHOW_ASSERT
-						llassert(prev_mip_data);
-						llassert(cur_mip_size == bytes*4);
-						llassert_always(new_data);
+							llassert(prev_mip_data);
+							llassert(cur_mip_size == bytes * 4);
 #endif
 
-						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
-						cur_mip_data = new_data;
+							LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
+							cur_mip_data = new_data;
 #ifdef SHOW_ASSERT
-						cur_mip_size = bytes; 
+							cur_mip_size = bytes;
 #endif
+						}
 
 					}
 					llassert(w > 0 && h > 0 && cur_mip_data);
@@ -886,6 +900,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 	}
 	stop_glerror();
 	mGLTextureCreated = true;
+	return TRUE;
 }
 
 BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
@@ -1355,8 +1370,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 	if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
 	{
 		// This will only be true if the size has not changed
-		setImage(data_in, data_hasmips);
-		return TRUE;
+		return setImage(data_in, data_hasmips);
 	}
 	
 	U32 old_name = mTexName;
@@ -1398,7 +1412,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 
 	mCurrentDiscardLevel = discard_level;	
 
-	setImage(data_in, data_hasmips);
+	if (!setImage(data_in, data_hasmips))
+	{
+		stop_glerror();
+		return FALSE;
+	}
 
 	// Set texture options to our defaults.
 	gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index ad2aea9067..2be54be062 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -105,7 +105,7 @@ public:
 		S32 category = sMaxCategories-1);
 	BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
 	void setImage(const LLImageRaw* imageraw);
-	void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
+	BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE);
 	BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
 	BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
 	BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
-- 
cgit v1.2.3


From 846927c286d7ac73be503b1a251b7f91dfeb7db9 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 19 Dec 2017 10:41:32 +0200
Subject: MAINT-8073 Stored favorites lose SLURLS after you re-order some
 favorite landmarks

---
 indra/newview/llfavoritesbar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index d614d612ff..5b4b7789b4 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -750,7 +750,7 @@ void LLFavoritesBarCtrl::updateButtons()
 		return;
 	}
 
-	if(mGetPrevItems)
+	if(mGetPrevItems && gInventory.isCategoryComplete(mFavoriteFolderId))
 	{
 	    for (LLInventoryModel::item_array_t::iterator it = mItems.begin(); it != mItems.end(); it++)
 	    {
-- 
cgit v1.2.3


From d9114e1bc4a1584fbe79111531e375e0e7f427ec Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 19 Dec 2017 15:24:22 +0200
Subject: MAINT-8102 Fixed release notes menu misbeheaving

---
 indra/newview/llstartup.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 89cc66cf33..02dcbd709f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -718,7 +718,6 @@ bool idle_startup()
 		set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());
 		display_startup();
 		// LLViewerMedia::initBrowser();
-		show_release_notes_if_required();
 		LLStartUp::setStartupState( STATE_LOGIN_SHOW );
 		return FALSE;
 	}
@@ -749,6 +748,7 @@ bool idle_startup()
 			initialize_spellcheck_menu();
 			init_menus();
 		}
+		show_release_notes_if_required();
 
 		if (show_connect_box)
 		{
-- 
cgit v1.2.3


From cdc23f48159410ee859eac7415c91cadeef849ef Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 19 Dec 2017 18:07:32 +0200
Subject: MAINT-8105 FIXED Button "Wear" is allowed in the empty outfit gallery

---
 indra/newview/lloutfitslist.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index f87ce8aa52..e2157f985e 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -995,7 +995,8 @@ void LLOutfitListBase::deselectOutfit(const LLUUID& category_id)
     // Reset selection if the outfit is selected.
     if (category_id == mSelectedOutfitUUID)
     {
-        signalSelectionOutfitUUID(LLUUID::null);
+        mSelectedOutfitUUID = LLUUID::null;
+        signalSelectionOutfitUUID(mSelectedOutfitUUID);
     }
 }
 
-- 
cgit v1.2.3


From de8ff2c7b397f22d1e15b21e7553a8c3e3933d45 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 20 Dec 2017 17:01:47 +0200
Subject: MAINT-8061 update folder label when item count changes

---
 indra/newview/llinventorypanel.cpp | 29 +++++++++++++++++++++++++++++
 indra/newview/llinventorypanel.h   |  2 ++
 2 files changed, 31 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 2762c7af82..93269db380 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -563,6 +563,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 				{
 					setSelection(item_id, FALSE);
 				}
+				updateFolderLabel(model_item->getParentUUID());
 			}
 
 			//////////////////////////////
@@ -574,6 +575,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 				// Don't process the item if it is the root
 				if (old_parent)
 				{
+					LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(old_parent->getViewModelItem());
 					LLFolderViewFolder* new_parent =   (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
 					// Item has been moved.
 					if (old_parent != new_parent)
@@ -591,6 +593,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 									setSelection(item_id, FALSE);
 								}
 							}
+							updateFolderLabel(model_item->getParentUUID());
 						}
 						else 
 						{
@@ -602,6 +605,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
 							// doesn't include trash).  Just remove the item's UI.
 							view_item->destroyView();
 						}
+						if(viewmodel_folder)
+						{
+							updateFolderLabel(viewmodel_folder->getUUID());
+						}
 						old_parent->getViewModelItem()->dirtyDescendantsFilter();
 					}
 				}
@@ -619,6 +626,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
 				if(parent)
 				{
 					parent->getViewModelItem()->dirtyDescendantsFilter();
+					LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(parent->getViewModelItem());
+					if(viewmodel_folder)
+					{
+						updateFolderLabel(viewmodel_folder->getUUID());
+					}
 				}
 			}
 		}
@@ -1162,6 +1174,23 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 
 }
 
+void LLInventoryPanel::updateFolderLabel(const LLUUID& folder_id)
+{
+	if(folder_id != mPreviousSelectedFolder) return;
+
+	LLFolderViewItem* folder_item = getItemByID(mPreviousSelectedFolder);
+	if(folder_item)
+	{
+		LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
+		if(bridge)
+		{
+			bridge->clearDisplayName();
+			bridge->setShowDescendantsCount(true);
+			folder_item->refresh();
+		}
+	}
+}
+
 void LLInventoryPanel::doCreate(const LLSD& userdata)
 {
 	reset_inventory_filter();
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 3829fb734d..12001f5a2b 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -209,6 +209,8 @@ public:
 	bool attachObject(const LLSD& userdata);
 	static void idle(void* user_data);
 
+	void updateFolderLabel(const LLUUID& folder_id);
+
 	// DEBUG ONLY:
 	static void dumpSelectionInformation(void* user_data);
 
-- 
cgit v1.2.3


From 9fe126e7e5be64ff4251b285eb168ff9c45e76fb Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 20 Dec 2017 22:03:06 +0200
Subject: Backed out changeset: 761e890970b2

---
 indra/llprimitive/llmaterial.cpp   |  14 +--
 indra/llprimitive/llmaterial.h     |  11 ---
 indra/newview/lldrawpoolavatar.cpp |   4 +-
 indra/newview/llface.cpp           |  36 +-------
 indra/newview/llface.h             |   5 +-
 indra/newview/llviewertexture.cpp  |  28 ------
 indra/newview/llviewertexture.h    |   5 -
 indra/newview/llvovolume.cpp       | 183 ++++++-------------------------------
 indra/newview/llvovolume.h         |  22 +----
 indra/newview/pipeline.cpp         |   4 +-
 10 files changed, 42 insertions(+), 270 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index e6d2790a5f..57ceb3e11b 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -106,16 +106,10 @@ LLMaterial::LLMaterial()
 	, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
 	, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 	, mAlphaMaskCutoff(0)
-	, mIsDiffuseAlphaInvalid(false)
-	, mIsNormalInvalid(false)
-	, mIsSpecularInvalid(false)
 {
 }
 
 LLMaterial::LLMaterial(const LLSD& material_data)
-	: mIsDiffuseAlphaInvalid(false)
-	, mIsNormalInvalid(false)
-	, mIsSpecularInvalid(false)
 {
 	fromLLSD(material_data);
 }
@@ -205,17 +199,13 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)
 	{
 		ret = getDiffuseAlphaMode();
 	}
-	if (mIsDiffuseAlphaInvalid && ret != DIFFUSE_ALPHA_MODE_DEFAULT)
-	{
-		ret = alpha_mode != DIFFUSE_ALPHA_MODE_NONE;
-	}
 
 	llassert(ret < SHADER_COUNT);
 
 	//next bit is whether or not specular map is present
 	const U32 SPEC_BIT = 0x4;
 
-	if (getSpecularID().notNull() && !mIsSpecularInvalid)
+	if (getSpecularID().notNull())
 	{
 		ret |= SPEC_BIT;
 	}
@@ -224,7 +214,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)
 	
 	//next bit is whether or not normal map is present
 	const U32 NORM_BIT = 0x8;
-	if (getNormalID().notNull() && !mIsNormalInvalid)
+	if (getNormalID().notNull())
 	{
 		ret |= NORM_BIT;
 	}
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index 2f23a50973..9f52a3f6c1 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -120,13 +120,6 @@ public:
 	void		setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
 
 	bool		isNull() const;
-	bool		isDiffuseAlphaInvalid() const { return mIsDiffuseAlphaInvalid; }
-	void		setDiffuseAlphaInvalid(bool is_invalid) { mIsDiffuseAlphaInvalid = is_invalid; }
-	bool		isNormalInvalid() const { return mIsNormalInvalid; }
-	void		setNormalInvalid(bool is_invalid) { mIsNormalInvalid = is_invalid; }
-	bool		isSpecularInvalid() const { return mIsSpecularInvalid; }
-	void		setSpecularInvalid(bool is_invalid) { mIsSpecularInvalid = is_invalid; }
-
 	static const LLMaterial null;
 
 	bool		operator == (const LLMaterial& rhs) const;
@@ -154,10 +147,6 @@ protected:
 	U8			mEnvironmentIntensity;
 	U8			mDiffuseAlphaMode;
 	U8			mAlphaMaskCutoff;
-
-	bool mIsDiffuseAlphaInvalid;
-	bool mIsNormalInvalid;
-	bool mIsSpecularInvalid;
 };
 
 typedef LLPointer<LLMaterial> LLMaterialPtr;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 97dda072e7..8128790eb6 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1818,7 +1818,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 				F32 env = mat->getEnvironmentIntensity()/255.f;
 
-				if (mat->getSpecularID().isNull() || mat->isSpecularInvalid())
+				if (mat->getSpecularID().isNull())
 				{
 					env = te->getShiny()*0.25f;
 					col.set(env,env,env,0);
@@ -1831,7 +1831,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
 				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
 
-				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && !mat->isDiffuseAlphaInvalid())
+				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 				{
 					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
 				}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index d502e686c7..c6fff6e57a 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -344,34 +344,6 @@ void LLFace::dirtyTexture()
 	gPipeline.markTextured(drawablep);
 }
 
-void LLFace::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{
-	LLDrawable* drawablep = getDrawable();
-	if(mVObjp.notNull() && mVObjp->getVolume())
-	{
-		LLVOVolume *vobj = drawablep->getVOVolume();
-		if(vobj && vobj->notifyAboutCreatingTexture(texture))
-		{
-			gPipeline.markTextured(drawablep);
-			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
-		}
-	}
-}
-
-void LLFace::notifyAboutMissingAsset(LLViewerTexture *texture)
-{
-	LLDrawable* drawablep = getDrawable();
-	if(mVObjp.notNull() && mVObjp->getVolume())
-	{
-		LLVOVolume *vobj = drawablep->getVOVolume();
-		if(vobj && vobj->notifyAboutMissingAsset(texture))
-		{
-			gPipeline.markTextured(drawablep);
-			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
-		}
-	}
-}
-
 void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
 {
 	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
@@ -1084,7 +1056,7 @@ bool LLFace::canRenderAsMask()
 	}
 	
 	LLMaterial* mat = te->getMaterialParams();
-	if (mat && !mat->isDiffuseAlphaInvalid() && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+	if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 	{
 		return false;
 	}
@@ -1318,14 +1290,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 			
 			if (LLPipeline::sRenderDeferred)
 			{ //store shiny in alpha if we don't have a specular map
-				if  (!mat || mat->getSpecularID().isNull() || mat->isSpecularInvalid())
+				if  (!mat || mat->getSpecularID().isNull())
 				{
 					shiny_in_alpha = true;
 				}
 			}
 			else
 			{
-				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK || mat->isDiffuseAlphaInvalid())
+				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 				{
 					shiny_in_alpha = true;
 				}
@@ -1811,7 +1783,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 				std::vector<LLVector2> bump_tc;
 		
-				if (mat && !(mat->getNormalID().isNull() || mat->isNormalInvalid()))
+				if (mat && !mat->getNormalID().isNull())
 				{ //writing out normal and specular texture coordinates, not bump offsets
 					do_bump = false;
 				}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index ee545acb94..2d88c6fa58 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -230,13 +230,10 @@ public:
 
 	static U32 getRiggedDataMask(U32 type);
 
-	void	notifyAboutCreatingTexture(LLViewerTexture *texture);
-	void	notifyAboutMissingAsset(LLViewerTexture *texture);
-
 public: //aligned members
 	LLVector4a		mExtents[2];
 
-private:
+private:	
 	F32         adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
 	BOOL        calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
 public:
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e5a1bed48c..840176c1e0 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -669,36 +669,12 @@ S8 LLViewerTexture::getType() const
 
 void LLViewerTexture::cleanup()
 {
-	notifyAboutMissingAsset();
-
 	mFaceList[LLRender::DIFFUSE_MAP].clear();
 	mFaceList[LLRender::NORMAL_MAP].clear();
 	mFaceList[LLRender::SPECULAR_MAP].clear();
 	mVolumeList.clear();
 }
 
-void LLViewerTexture::notifyAboutCreatingTexture()
-{
-	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
-	{
-		for(U32 f = 0; f < mNumFaces[ch]; f++)
-		{
-			mFaceList[ch][f]->notifyAboutCreatingTexture(this);
-		}
-	}
-}
-
-void LLViewerTexture::notifyAboutMissingAsset()
-{
-	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
-	{
-		for(U32 f = 0; f < mNumFaces[ch]; f++)
-		{
-			mFaceList[ch][f]->notifyAboutMissingAsset(this);
-		}
-	}
-}
-
 // virtual
 void LLViewerTexture::dump()
 {
@@ -1498,8 +1474,6 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 
 	res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
 
-	notifyAboutCreatingTexture();
-
 	setActive();
 
 	if (!needsToSaveRawImage())
@@ -2224,8 +2198,6 @@ void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing)
 	}
 	if (is_missing)
 	{
-		notifyAboutMissingAsset();
-
 		if (mUrl.empty())
 		{
 			LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index c9dea17f63..9208b4813e 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -175,10 +175,6 @@ protected:
 	void init(bool firstinit) ;
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
-
-	void notifyAboutMissingAsset();
-	void notifyAboutCreatingTexture();
-
 private:
 	friend class LLBumpImageList;
 	friend class LLUIImageList;
@@ -316,7 +312,6 @@ public:
 
 	void addToCreateTexture();
 
-
 	 // ONLY call from LLViewerTextureList
 	BOOL createTexture(S32 usename = 0);
 	void destroyTexture() ;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 206d34d7ea..20c54d06d3 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2051,148 +2051,28 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 	return res;
 }
 
-bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{
-	// Texture was created, process it and remove from wait list
-
-	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-	if(range.first == range.second) return false;
-
-	bool needs_update = false;
-
-	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
-	{
-		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-		if (cur_material.isNull())
-		{
-			continue;
-		}
-
-		if (LLRender::DIFFUSE_MAP == range_it->second.map
-			&& GL_RGBA != texture->getPrimaryFormat()
-			&& cur_material->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-			&& cur_material->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT)
-		{
-			// We have non 32 bit texture with alpha, it is invalid
-
-			cur_material->setDiffuseAlphaInvalid(true);
-			needs_update = true;
-		}
-	}
-
-	//clear wait-list
-	mWaitingTextureInfo.erase(range.first, range.second);
-
-	return needs_update;
-}
-
-bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
-{
-	// Texture was marked as missing, process it and remove from wait list
-
-	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-	if(range.first == range.second) return false;
-	
-	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
-	{
-		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-		if (cur_material.isNull())
-		{
-			continue;
-		}
-
-		switch (range_it->second.map)
-		{
-		case LLRender::DIFFUSE_MAP:
-			{
-				cur_material->setDiffuseAlphaInvalid(true);
-				break;
-			}
-		case LLRender::NORMAL_MAP:
-			{
-				cur_material->setNormalInvalid(true);
-				break;
-			}
-		case LLRender::SPECULAR_MAP:
-			{
-				cur_material->setSpecularInvalid(true);
-				break;
-			}
-		default:
-			break;
-		}
-	}
-
-	//clear wait-list
-	mWaitingTextureInfo.erase(range.first, range.second);
-
-	return true;
-}
-
 S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
 {
 	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
 
 	if(pMaterialParams)
-	{ //check all of them according to material settings
-
-		LLViewerTexture *img_diffuse = getTEImage(te);
-		LLViewerTexture *img_normal = getTENormalMap(te);
-		LLViewerTexture *img_specular = getTESpecularMap(te);
+	{
+		LLViewerTexture* image = getTEImage(te);
+		LLGLenum image_format = image ? image->getPrimaryFormat() : GL_RGB;
+		LLMaterialPtr current_material = getTEMaterialParams(te);
 
-		llassert(NULL != img_diffuse);
+		U8 new_diffuse_alpha_mode = pMaterialParams->getDiffuseAlphaMode();
 
-		//diffuse
-		if(NULL != img_diffuse)
+		if(new_diffuse_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 		{
-			if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
-			{
-				// Texture information is missing, wait for it
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
-			}
-			else
-			{
-				if(img_diffuse->isMissingAsset())
-				{
-					pMaterial->setDiffuseAlphaInvalid(true);
-				}
-				else if (GL_RGBA != img_diffuse->getPrimaryFormat()
-						&& pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-						&& pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT)
-				{
-					pMaterial->setDiffuseAlphaInvalid(true);
-				}
-			}
+			new_diffuse_alpha_mode = (GL_RGB == image_format || 0 == image_format ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : new_diffuse_alpha_mode);
 		}
 
-		//normal
-		if(LLUUID::null != pMaterialParams->getNormalID())
-		{
-			if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
-			{
-				pMaterial->setNormalInvalid(true);
-			}
-			else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
-			{
-				// Texture information is missing, wait for it
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
-			}
-
-		}
-
-
-		//specular
-		if(LLUUID::null != pMaterialParams->getSpecularID())
-		{
-			if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
-			{
-				pMaterial->setSpecularInvalid(true);
-			}
-			else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
-			{
-				// Texture information is missing, wait for it
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
-			}
+		if(pMaterialParams->getDiffuseAlphaMode() != new_diffuse_alpha_mode) {
+			//create new material
+			pMaterial = new LLMaterial(pMaterialParams->asLLSD());
+			pMaterial->setDiffuseAlphaMode(new_diffuse_alpha_mode);
+			LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
 		}
 	}
 
@@ -4485,7 +4365,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 				}
 
 				draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
-				draw_info->mDiffuseAlphaMode = mat->isDiffuseAlphaInvalid() ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : mat->getDiffuseAlphaMode();
+				draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
 				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
 				
 		}
@@ -4754,14 +4634,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						}
 
 						LLMaterial* mat = te->getMaterialParams().get();
-						U8 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-						if (mat && !mat->isDiffuseAlphaInvalid())
-						{
-							alpha_mode = mat->getDiffuseAlphaMode();
-						}
 
 						if (mat && LLPipeline::sRenderDeferred)
 						{
+							U8 alpha_mode = mat->getDiffuseAlphaMode();
+
 							bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
 								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
 								te->getColor().mV[3] < 0.999f);
@@ -4781,10 +4658,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						{
 							bool fullbright = te->getFullbright();
 							bool is_alpha = type == LLDrawPool::POOL_ALPHA;
-							bool can_be_shiny = alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
-												alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+							U8 mode = mat->getDiffuseAlphaMode();
+							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
 							
-							if (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
+							if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
 							{
 								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
 							}
@@ -4984,9 +4862,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull()  && !te->getMaterialID().isNull())
 							{
 								LLMaterial* mat = te->getMaterialParams().get();
-								if (mat->getNormalID().notNull() && !mat->isNormalInvalid())
+								if (mat->getNormalID().notNull())
 								{
-									if (mat->getSpecularID().notNull() && !mat->isSpecularInvalid())
+									if (mat->getSpecularID().notNull())
 									{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
 										if (normspec_count < MAX_FACE_COUNT)
 										{
@@ -5001,7 +4879,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 										}
 									}
 								}
-								else if (mat->getSpecularID().notNull() && !mat->isSpecularInvalid())
+								else if (mat->getSpecularID().notNull())
 								{ //has specular map but no normal map, needs texcoord2
 									if (spec_count < MAX_FACE_COUNT)
 									{
@@ -5658,14 +5536,13 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
 		
 			LLMaterial* mat = te->getMaterialParams().get();
-			U8 diffuse_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-			bool can_be_shiny = true;
 
+			bool can_be_shiny = true;
 			if (mat)
 			{
-				diffuse_mode = mat->isDiffuseAlphaInvalid() ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : mat->getDiffuseAlphaMode();
-				can_be_shiny = diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
-						diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+				U8 mode = mat->getDiffuseAlphaMode();
+				can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
 			}
 
 			bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
@@ -5681,7 +5558,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 				//
 				if (te->getFullbright())
 				{
-					if (diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+					if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 					{
 						if (opaque)
 						{
@@ -5760,7 +5637,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 			}
 			else if (mat)
 			{
-				U8 mode = diffuse_mode;
+				U8 mode = mat->getDiffuseAlphaMode();
 				if (te->getColor().mV[3] < 0.999f)
 				{
 					mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
@@ -5856,7 +5733,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 				}
 				else if (fullbright || bake_sunlight)
 				{ //fullbright
-					if (mat && diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 					{
 						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
 					}
@@ -5878,7 +5755,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
 					else
 					{ //all around simple
 						llassert(mask & LLVertexBuffer::MAP_NORMAL);
-						if (mat && diffuse_mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+						if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 						{ //material alpha mask can be respected in non-deferred
 							registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
 						}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a331908320..b07d416363 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -380,7 +380,7 @@ public:
 	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
 	static F32 sLODFactor;				// LOD scale factor
 	static F32 sDistanceFactor;			// LOD distance factor
-
+		
 	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
 	static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
 
@@ -388,26 +388,6 @@ protected:
 	static S32 sNumLODChanges;
 
 	friend class LLVolumeImplFlexible;
-
-public:
-	bool notifyAboutCreatingTexture(LLViewerTexture *texture);
-	bool notifyAboutMissingAsset(LLViewerTexture *texture);
-
-private:
-	struct material_info 
-	{
-		LLRender::eTexIndex map;
-		U8 te;
-
-		material_info(LLRender::eTexIndex map_, U8 te_)
-			: map(map_)
-			, te(te_)
-		{}
-	};
-
-	typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
-	mmap_UUID_MAP_t	mWaitingTextureInfo;
-
 };
 
 #endif // LL_LLVOVOLUME_H
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 138d186e06..d3be5fea1a 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1691,7 +1691,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
 		alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
 	}
 
-	if (alpha && mat && !mat->isDiffuseAlphaInvalid())
+	if (alpha && mat)
 	{
 		switch (mat->getDiffuseAlphaMode())
 		{
@@ -1712,7 +1712,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
 	{
 		return LLDrawPool::POOL_ALPHA;
 	}
-	else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull() || mat->isNormalInvalid()))
+	else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
 	{
 		return LLDrawPool::POOL_BUMP;
 	}
-- 
cgit v1.2.3


From 2897ea5c5b997ce19b9b7687a5bbc428c523c6ab Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 20 Dec 2017 22:03:38 +0200
Subject: Backed out changeset: b500f22775dd

---
 indra/newview/llface.cpp          |  28 +++++
 indra/newview/llface.h            |   5 +-
 indra/newview/llviewertexture.cpp |  28 +++++
 indra/newview/llviewertexture.h   |   5 +
 indra/newview/llvovolume.cpp      | 225 ++++++++++++++++++++++++++++++++++++--
 indra/newview/llvovolume.h        |  22 +++-
 6 files changed, 300 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index c6fff6e57a..3d5e2d356e 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -344,6 +344,34 @@ void LLFace::dirtyTexture()
 	gPipeline.markTextured(drawablep);
 }
 
+void LLFace::notifyAboutCreatingTexture(LLViewerTexture *texture)
+{
+	LLDrawable* drawablep = getDrawable();
+	if(mVObjp.notNull() && mVObjp->getVolume())
+	{
+		LLVOVolume *vobj = drawablep->getVOVolume();
+		if(vobj && vobj->notifyAboutCreatingTexture(texture))
+		{
+			gPipeline.markTextured(drawablep);
+			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
+		}
+	}
+}
+
+void LLFace::notifyAboutMissingAsset(LLViewerTexture *texture)
+{
+	LLDrawable* drawablep = getDrawable();
+	if(mVObjp.notNull() && mVObjp->getVolume())
+	{
+		LLVOVolume *vobj = drawablep->getVOVolume();
+		if(vobj && vobj->notifyAboutMissingAsset(texture))
+		{
+			gPipeline.markTextured(drawablep);
+			gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
+		}
+	}
+}
+
 void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
 {
 	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 2d88c6fa58..ee545acb94 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -230,10 +230,13 @@ public:
 
 	static U32 getRiggedDataMask(U32 type);
 
+	void	notifyAboutCreatingTexture(LLViewerTexture *texture);
+	void	notifyAboutMissingAsset(LLViewerTexture *texture);
+
 public: //aligned members
 	LLVector4a		mExtents[2];
 
-private:	
+private:
 	F32         adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
 	BOOL        calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
 public:
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 840176c1e0..e5a1bed48c 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -669,12 +669,36 @@ S8 LLViewerTexture::getType() const
 
 void LLViewerTexture::cleanup()
 {
+	notifyAboutMissingAsset();
+
 	mFaceList[LLRender::DIFFUSE_MAP].clear();
 	mFaceList[LLRender::NORMAL_MAP].clear();
 	mFaceList[LLRender::SPECULAR_MAP].clear();
 	mVolumeList.clear();
 }
 
+void LLViewerTexture::notifyAboutCreatingTexture()
+{
+	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+	{
+		for(U32 f = 0; f < mNumFaces[ch]; f++)
+		{
+			mFaceList[ch][f]->notifyAboutCreatingTexture(this);
+		}
+	}
+}
+
+void LLViewerTexture::notifyAboutMissingAsset()
+{
+	for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+	{
+		for(U32 f = 0; f < mNumFaces[ch]; f++)
+		{
+			mFaceList[ch][f]->notifyAboutMissingAsset(this);
+		}
+	}
+}
+
 // virtual
 void LLViewerTexture::dump()
 {
@@ -1474,6 +1498,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 
 	res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
 
+	notifyAboutCreatingTexture();
+
 	setActive();
 
 	if (!needsToSaveRawImage())
@@ -2198,6 +2224,8 @@ void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing)
 	}
 	if (is_missing)
 	{
+		notifyAboutMissingAsset();
+
 		if (mUrl.empty())
 		{
 			LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 9208b4813e..c9dea17f63 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -175,6 +175,10 @@ protected:
 	void init(bool firstinit) ;
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
+
+	void notifyAboutMissingAsset();
+	void notifyAboutCreatingTexture();
+
 private:
 	friend class LLBumpImageList;
 	friend class LLUIImageList;
@@ -312,6 +316,7 @@ public:
 
 	void addToCreateTexture();
 
+
 	 // ONLY call from LLViewerTextureList
 	BOOL createTexture(S32 usename = 0);
 	void destroyTexture() ;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 20c54d06d3..f77b48ff80 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2051,27 +2051,230 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 	return res;
 }
 
+bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
+{ //Ok, here we have confirmation about texture creation, check our wait-list
+  //and make changes, or return false
+
+	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
+
+	typedef std::map<U8, LLMaterialPtr> map_te_material;
+	map_te_material new_material;
+
+	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
+	{
+		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+
+		//here we just interesting in DIFFUSE_MAP only!
+		if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat())
+		{ //ok let's check the diffuse mode
+			switch(cur_material->getDiffuseAlphaMode())
+			{
+			case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
+			case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
+			case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
+				{ //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+
+					LLMaterialPtr mat = NULL;
+					map_te_material::iterator it = new_material.find(range_it->second.te);
+					if(new_material.end() == it) {
+						mat = new LLMaterial(cur_material->asLLSD());
+						new_material.insert(map_te_material::value_type(range_it->second.te, mat));
+					} else {
+						mat = it->second;
+					}
+
+					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+
+				} break;
+			} //switch
+		} //if
+	} //for
+
+	//setup new materials
+	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
+	{
+		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
+		LLViewerObject::setTEMaterialParams(it->first, it->second);
+	}
+
+	//clear wait-list
+	mWaitingTextureInfo.erase(range.first, range.second);
+
+	return 0 != new_material.size();
+}
+
+bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
+{ //Ok, here if we wait information about texture and it's missing
+  //then depending from the texture map (diffuse, normal, or specular)
+  //make changes in material and confirm it. If not return false.
+	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
+	if(range.first == range.second) return false;
+
+	typedef std::map<U8, LLMaterialPtr> map_te_material;
+	map_te_material new_material;
+	
+	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
+	{
+		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+		if (cur_material.isNull())
+			continue;
+
+		switch(range_it->second.map)
+		{
+		case LLRender::DIFFUSE_MAP:
+			{
+				if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
+				{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+					LLMaterialPtr mat = NULL;
+					map_te_material::iterator it = new_material.find(range_it->second.te);
+					if(new_material.end() == it) {
+						mat = new LLMaterial(cur_material->asLLSD());
+						new_material.insert(map_te_material::value_type(range_it->second.te, mat));
+					} else {
+						mat = it->second;
+					}
+
+					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+				}
+			} break;
+		case LLRender::NORMAL_MAP:
+			{ //missing texture => reset material texture id
+				LLMaterialPtr mat = NULL;
+				map_te_material::iterator it = new_material.find(range_it->second.te);
+				if(new_material.end() == it) {
+					mat = new LLMaterial(cur_material->asLLSD());
+					new_material.insert(map_te_material::value_type(range_it->second.te, mat));
+				} else {
+					mat = it->second;
+				}
+
+				mat->setNormalID(LLUUID::null);
+			} break;
+		case LLRender::SPECULAR_MAP:
+			{ //missing texture => reset material texture id
+				LLMaterialPtr mat = NULL;
+				map_te_material::iterator it = new_material.find(range_it->second.te);
+				if(new_material.end() == it) {
+					mat = new LLMaterial(cur_material->asLLSD());
+					new_material.insert(map_te_material::value_type(range_it->second.te, mat));
+				} else {
+					mat = it->second;
+				}
+
+				mat->setSpecularID(LLUUID::null);
+			} break;
+		case LLRender::NUM_TEXTURE_CHANNELS:
+				//nothing to do, make compiler happy
+			break;
+		} //switch
+	} //for
+
+	//setup new materials
+	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
+	{
+		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
+		LLViewerObject::setTEMaterialParams(it->first, it->second);
+	}
+
+	//clear wait-list
+	mWaitingTextureInfo.erase(range.first, range.second);
+
+	return 0 != new_material.size();
+}
+
 S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
 {
 	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
 
 	if(pMaterialParams)
-	{
-		LLViewerTexture* image = getTEImage(te);
-		LLGLenum image_format = image ? image->getPrimaryFormat() : GL_RGB;
-		LLMaterialPtr current_material = getTEMaterialParams(te);
+	{ //check all of them according to material settings
+
+		LLViewerTexture *img_diffuse = getTEImage(te);
+		LLViewerTexture *img_normal = getTENormalMap(te);
+		LLViewerTexture *img_specular = getTESpecularMap(te);
+
+		llassert(NULL != img_diffuse);
+
+		LLMaterialPtr new_material = NULL;
+
+		//diffuse
+		if(NULL != img_diffuse)
+		{ //guard
+			if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
+			{ //ok here we don't have information about texture, let's belief and leave material settings
+			  //but we remember this case
+				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
+			}
+			else
+			{
+				bool bSetDiffuseNone = false;
+				if(img_diffuse->isMissingAsset())
+				{
+					bSetDiffuseNone = true;
+				}
+				else
+				{
+					switch(pMaterialParams->getDiffuseAlphaMode())
+					{
+					case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
+					case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
+					case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
+						{ //all of them modes available only for 32 bit textures
+							if(GL_RGBA != img_diffuse->getPrimaryFormat())
+							{
+								bSetDiffuseNone = true;
+							}
+						} break;
+					}
+				} //else
 
-		U8 new_diffuse_alpha_mode = pMaterialParams->getDiffuseAlphaMode();
 
-		if(new_diffuse_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+				if(bSetDiffuseNone)
+				{ //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+					new_material = new LLMaterial(pMaterialParams->asLLSD());
+					new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+				}
+			}
+		}
+
+		//normal
+		if(LLUUID::null != pMaterialParams->getNormalID())
 		{
-			new_diffuse_alpha_mode = (GL_RGB == image_format || 0 == image_format ? LLMaterial::DIFFUSE_ALPHA_MODE_NONE : new_diffuse_alpha_mode);
+			if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
+			{
+				if(!new_material) {
+					new_material = new LLMaterial(pMaterialParams->asLLSD());
+				}
+				new_material->setNormalID(LLUUID::null);
+			}
+			else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
+			{ //ok here we don't have information about texture, let's belief and leave material settings
+				//but we remember this case
+				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
+			}
+
+		}
+
+
+		//specular
+		if(LLUUID::null != pMaterialParams->getSpecularID())
+		{
+			if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
+			{
+				if(!new_material) {
+					new_material = new LLMaterial(pMaterialParams->asLLSD());
+				}
+				new_material->setSpecularID(LLUUID::null);
+			}
+			else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
+			{ //ok here we don't have information about texture, let's belief and leave material settings
+				//but we remember this case
+				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
+			}
 		}
 
-		if(pMaterialParams->getDiffuseAlphaMode() != new_diffuse_alpha_mode) {
-			//create new material
-			pMaterial = new LLMaterial(pMaterialParams->asLLSD());
-			pMaterial->setDiffuseAlphaMode(new_diffuse_alpha_mode);
+		if(new_material) {
+			pMaterial = new_material;
 			LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
 		}
 	}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index b07d416363..a331908320 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -380,7 +380,7 @@ public:
 	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
 	static F32 sLODFactor;				// LOD scale factor
 	static F32 sDistanceFactor;			// LOD distance factor
-		
+
 	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
 	static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
 
@@ -388,6 +388,26 @@ protected:
 	static S32 sNumLODChanges;
 
 	friend class LLVolumeImplFlexible;
+
+public:
+	bool notifyAboutCreatingTexture(LLViewerTexture *texture);
+	bool notifyAboutMissingAsset(LLViewerTexture *texture);
+
+private:
+	struct material_info 
+	{
+		LLRender::eTexIndex map;
+		U8 te;
+
+		material_info(LLRender::eTexIndex map_, U8 te_)
+			: map(map_)
+			, te(te_)
+		{}
+	};
+
+	typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
+	mmap_UUID_MAP_t	mWaitingTextureInfo;
+
 };
 
 #endif // LL_LLVOVOLUME_H
-- 
cgit v1.2.3


From a35008993eef5b1fee5695804c83050cf922d146 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 2 Jan 2018 20:31:23 +0200
Subject: MAINT-8022 String crashes in unzip_llsd

---
 indra/llcommon/llsdserialize.cpp | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index ede212181d..71744aef3c 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -2217,24 +2217,42 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 
 	//result now points to the decompressed LLSD block
 	{
-		std::string res_str((char*) result, cur_size);
+		std::istringstream istr;
+		// Since we are using this for meshes, data we are dealing with tend to be large.
+		// So string can potentially fail to allocate, make sure this won't cause problems
+		try
+		{
+			std::string res_str((char*)result, cur_size);
+
+			std::string deprecated_header("<? LLSD/Binary ?>");
 
-		std::string deprecated_header("<? LLSD/Binary ?>");
+			if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
+			{
+				res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
+			}
+			cur_size = res_str.size();
 
-		if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
+			istr.str(res_str);
+		}
+		catch (std::length_error)
 		{
-			res_str = res_str.substr(deprecated_header.size()+1, cur_size);
+			LL_DEBUGS("UNZIP") << "String we are creating is too big" << LL_ENDL;
+			free(result);
+			return false;
+		}
+		catch (std::bad_alloc)
+		{
+			LL_DEBUGS("UNZIP") << "Failed to allocate for string" << LL_ENDL;
+			free(result);
+			return false;
 		}
-		cur_size = res_str.size();
 
-		std::istringstream istr(res_str);
-		
 		if (!LLSDSerialize::fromBinary(data, istr, cur_size))
 		{
-			LL_WARNS() << "Failed to unzip LLSD block" << LL_ENDL;
+			LL_WARNS("UNZIP") << "Failed to unzip LLSD block" << LL_ENDL;
 			free(result);
 			return false;
-		}		
+		}
 	}
 
 	free(result);
-- 
cgit v1.2.3


From c56298d4ba818aaa5b69a8c30e5b577f7e4596eb Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 3 Jan 2018 16:30:57 +0200
Subject: MAINT-8022 Make unzip silent yet include failure reason into output

---
 indra/llcommon/llsdserialize.cpp   | 34 ++++++++++++----------------------
 indra/llcommon/llsdserialize.h     | 18 +++++++++++++++++-
 indra/llmath/llvolume.cpp          |  5 +++--
 indra/llprimitive/llmodel.cpp      |  4 ++--
 indra/newview/llmaterialmgr.cpp    | 15 +++++++++------
 indra/newview/llmeshrepository.cpp |  8 ++++++--
 6 files changed, 49 insertions(+), 35 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 71744aef3c..be54ed053b 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -2121,22 +2121,13 @@ std::string zip_llsd(LLSD& data)
 	deflateEnd(&strm);
 	free(output);
 
-#if 0 //verify results work with unzip_llsd
-	std::istringstream test(result);
-	LLSD test_sd;
-	if (!unzip_llsd(test_sd, test, result.size()))
-	{
-		LL_ERRS() << "Invalid compression result!" << LL_ENDL;
-	}
-#endif
-
 	return result;
 }
 
 //decompress a block of LLSD from provided istream
 // not very efficient -- creats a copy of decompressed LLSD block in memory
 // and deserializes from that copy using LLSDSerialize
-bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
+LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
 {
 	U8* result = NULL;
 	U32 cur_size = 0;
@@ -2147,7 +2138,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 	U8 *in = new(std::nothrow) U8[size];
 	if (!in)
 	{
-		return false;
+		return ZR_MEM_ERROR;
 	}
 	is.read((char*) in, size); 
 
@@ -2171,7 +2162,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 			inflateEnd(&strm);
 			free(result);
 			delete [] in;
-			return false;
+			return ZR_DATA_ERROR;
 		}
 		
 		switch (ret)
@@ -2183,7 +2174,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 			inflateEnd(&strm);
 			free(result);
 			delete [] in;
-			return false;
+			return ZR_MEM_ERROR;
 			break;
 		}
 
@@ -2198,7 +2189,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 				free(result);
 			}
 			delete[] in;
-			return false;
+			return ZR_MEM_ERROR;
 		}
 		result = new_result;
 		memcpy(result+cur_size, out, have);
@@ -2212,7 +2203,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 	if (ret != Z_STREAM_END)
 	{
 		free(result);
-		return false;
+		return ZR_DATA_ERROR;
 	}
 
 	//result now points to the decompressed LLSD block
@@ -2234,29 +2225,28 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 
 			istr.str(res_str);
 		}
+#ifdef LL_WINDOWS
 		catch (std::length_error)
 		{
-			LL_DEBUGS("UNZIP") << "String we are creating is too big" << LL_ENDL;
 			free(result);
-			return false;
+			return ZR_SIZE_ERROR;
 		}
+#endif
 		catch (std::bad_alloc)
 		{
-			LL_DEBUGS("UNZIP") << "Failed to allocate for string" << LL_ENDL;
 			free(result);
-			return false;
+			return ZR_MEM_ERROR;
 		}
 
 		if (!LLSDSerialize::fromBinary(data, istr, cur_size))
 		{
-			LL_WARNS("UNZIP") << "Failed to unzip LLSD block" << LL_ENDL;
 			free(result);
-			return false;
+			return ZR_PARSE_ERROR;
 		}
 	}
 
 	free(result);
-	return true;
+	return ZR_OK;
 }
 //This unzip function will only work with a gzip header and trailer - while the contents
 //of the actual compressed data is the same for either format (gzip vs zlib ), the headers
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 23a0c8cfb1..9f58d44fe7 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -814,8 +814,24 @@ public:
 	}
 };
 
+class LL_COMMON_API LLUZipHelper : public LLRefCount
+{
+public:
+    typedef enum e_zip_result
+    {
+        ZR_OK = 0,
+        ZR_MEM_ERROR,
+        ZR_SIZE_ERROR,
+        ZR_DATA_ERROR,
+        ZR_PARSE_ERROR,
+    } EZipRresult;
+    // return OK or reason for failure
+    static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
+};
+
 //dirty little zip functions -- yell at davep
 LL_COMMON_API std::string zip_llsd(LLSD& data);
-LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
+
+
 LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
 #endif // LL_LLSDSERIALIZE_H
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 5068c9c685..b1be29f594 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2367,9 +2367,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 	//input stream is now pointing at a zlib compressed block of LLSD
 	//decompress block
 	LLSD mdl;
-	if (!unzip_llsd(mdl, is, size))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size);
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD, will probably fetch from sim again." << LL_ENDL;
+		LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
 		return false;
 	}
 	
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index db6d00bc2c..29af859cd0 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1354,7 +1354,7 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
 
 		LLSD skin_data;
 
-		if (unzip_llsd(skin_data, is, size))
+		if (LLUZipHelper::unzip_llsd(skin_data, is, size) == LLUZipHelper::ZR_OK)
 		{
 			mSkinInfo.fromLLSD(skin_data);
 			return true;
@@ -1375,7 +1375,7 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
 
 		LLSD data;
 
-		if (unzip_llsd(data, is, size))
+		if (LLUZipHelper::unzip_llsd(data, is, size) == LLUZipHelper::ZR_OK)
 		{
 			mPhysics.fromLLSD(data);
 			updateHullCenters();
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index f996557c17..3befdaf88d 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -410,9 +410,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI
 	std::istringstream content_stream(content_string);
 
 	LLSD response_data;
-	if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+		LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
 		return;
 	}
 
@@ -452,9 +453,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
 	std::istringstream content_stream(content_string);
 
 	LLSD response_data;
-	if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+		LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
 		return;
 	}
 
@@ -520,9 +522,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
 	std::istringstream content_stream(content_string);
 
 	LLSD response_data;
-	if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+		LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
 		return;
 	}
 	else
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 25bd0d855e..51ca7a8a51 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1765,9 +1765,11 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
 
 		std::istringstream stream(res_str);
 
-		if (!unzip_llsd(skin, stream, data_size))
+		U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
+		if (uzip_result != LLUZipHelper::ZR_OK)
 		{
 			LL_WARNS(LOG_MESH) << "Mesh skin info parse error.  Not a valid mesh asset!  ID:  " << mesh_id
+							   << " uzip result" << uzip_result
 							   << LL_ENDL;
 			return false;
 		}
@@ -1797,9 +1799,11 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
 
 		std::istringstream stream(res_str);
 
-		if (!unzip_llsd(decomp, stream, data_size))
+		U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
+		if (uzip_result != LLUZipHelper::ZR_OK)
 		{
 			LL_WARNS(LOG_MESH) << "Mesh decomposition parse error.  Not a valid mesh asset!  ID:  " << mesh_id
+							   << " uzip result: " << uzip_result
 							   << LL_ENDL;
 			return false;
 		}
-- 
cgit v1.2.3


From e358ef21c089dfcc0df5c42627bc2c89731cfa53 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 5 Jan 2018 17:56:35 +0200
Subject: MAINT-8143 viewer doen't respect allow media to autoplay unchecked

---
 indra/newview/llviewermedia.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 7c6cce5c58..99358f4451 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -784,18 +784,21 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 				}
 			}
 			// update the audio stream here as well
+			static bool restore_parcel_audio = false;
 			if( !inworld_audio_enabled)
 			{
 				if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio())
 				{
 					LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
+					restore_parcel_audio = true;
 				}
 			}
             else
             {
-                if(gAudiop && LLViewerMedia::hasParcelAudio() && gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
+                if(gAudiop && LLViewerMedia::hasParcelAudio() && restore_parcel_audio && gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
                 {
                     LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
+                    restore_parcel_audio = false;
                 }
             }
 
-- 
cgit v1.2.3


From 6ac2b2bb4f569b6663607894034b4ec64804e905 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 10 Jan 2018 18:51:20 +0200
Subject: MAINT-8167 Fixed uploading JPEG image from Unicode directory fails

---
 indra/llimage/llimagedimensionsinfo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index a5e546e977..97b543f3b6 100644
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -163,7 +163,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
 {
 	sJpegErrorEncountered = false;
 	clean();
-	FILE *fp = fopen (mSrcFilename.c_str(), "rb");
+	FILE *fp = LLFile::fopen(mSrcFilename, "rb");
 	if (fp == NULL) 
 	{
 		setLastError("Unable to open file for reading", mSrcFilename);
-- 
cgit v1.2.3


From bafe54c1fe5f83552a6be6c10b0f3b6e3ef69859 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 17 Jan 2018 18:46:56 +0200
Subject: MAINT-8183 Additional logging

---
 indra/llwindow/llwindowwin32.cpp | 24 ++++++++++++++++++++----
 indra/newview/llviewerwindow.cpp |  1 +
 2 files changed, 21 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 2ad6f7c8b5..9fa07d1d34 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -1101,7 +1101,14 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 		mhInstance,
 		NULL);
 
-	LL_INFOS("Window") << "window is created." << LL_ENDL ;
+	if (mWindowHandle)
+	{
+		LL_INFOS("Window") << "window is created." << LL_ENDL ;
+	}
+	else
+	{
+		LL_WARNS("Window") << "Window creation failed, code: " << GetLastError() << LL_ENDL;
+	}
 
 	//-----------------------------------------------------------------------
 	// Create GL drawing context
@@ -1416,7 +1423,16 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 			mhInstance,
 			NULL);
 
-		LL_INFOS("Window") << "recreate window done." << LL_ENDL ;
+
+		if (mWindowHandle)
+		{
+			LL_INFOS("Window") << "recreate window done." << LL_ENDL ;
+		}
+		else
+		{
+			// Note: if value is NULL GetDC retrieves the DC for the entire screen.
+			LL_WARNS("Window") << "Window recreation failed, code: " << GetLastError() << LL_ENDL;
+		}
 
 		if (!(mhDC = GetDC(mWindowHandle)))
 		{
@@ -2646,20 +2662,20 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
 			}
 
 		case WM_SETFOCUS:
-			window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS");
 			if (gDebugWindowProc)
 			{
 				LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
 			}
+			window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS");
 			window_imp->mCallbacks->handleFocus(window_imp);
 			return 0;
 
 		case WM_KILLFOCUS:
-			window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KILLFOCUS");
 			if (gDebugWindowProc)
 			{
 				LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
 			}
+			window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KILLFOCUS");
 			window_imp->mCallbacks->handleFocusLost(window_imp);
 			return 0;
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ca231c164c..74deaffe16 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2268,6 +2268,7 @@ void LLViewerWindow::shutdownGL()
 LLViewerWindow::~LLViewerWindow()
 {
 	LL_INFOS() << "Destroying Window" << LL_ENDL;
+	gDebugWindowProc = TRUE; // event catching, at this point it shouldn't output at all
 	destroyWindow();
 
 	delete mDebugText;
-- 
cgit v1.2.3


From 750d90cf592d22b9c717fa138f17b2c1e32dd1c7 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 22 Jan 2018 18:11:12 +0200
Subject: MAINT-8208 [Mac] Viewer crashes when uploading certain mesh model
 after enabling "Include skin weight"

---
 indra/llprimitive/llmodel.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 29af859cd0..8fbb4f6b96 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1034,8 +1034,11 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
 	{  //no exact match found, get closest point
 		const F32 epsilon = 1e-5f;
 		weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
-		weight_map::iterator iter_down = ++iter_up;
-
+		weight_map::iterator iter_down = iter_up;
+		if (iter_up != mSkinWeights.end())
+		{
+			iter_down = ++iter_up;
+		}
 		weight_map::iterator best = iter_up;
 
 		F32 min_dist = (iter->first - pos).magVec();
-- 
cgit v1.2.3


From e6f5aa7f61891395eaf0f376dca88c1d1a951d1b Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 22 Jan 2018 20:37:58 +0200
Subject: MAINT-8210 Fixed crash in avatar name cache

---
 indra/llmessage/llavatarnamecache.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 5a112b5432..abe0e46e5d 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -769,7 +769,7 @@ LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
 
     // Legacy method
     LLUUID id;
-    if (gCacheName->getUUID(name, id))
+    if (gCacheName && gCacheName->getUUID(name, id))
     {
         return id;
     }
-- 
cgit v1.2.3


From b654513257ea7e5f74d61c9b4586e480838be23c Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 24 Jan 2018 21:16:27 +0200
Subject: MAINT-8197 Fix for crash in gpu_benchmark() including safety checks
 and some refactoring

---
 indra/newview/llglsandbox.cpp | 192 ++++++++++++++++++++++++++----------------
 1 file changed, 118 insertions(+), 74 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 1b6494195b..63270e13fe 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -881,8 +881,100 @@ void LLViewerObjectList::renderObjectBeacons()
 }
 
 
+//-----------------------------------------------------------------------------
+// gpu_benchmark() helper classes
+//-----------------------------------------------------------------------------
+
+// This struct is used to ensure that once we call initProfile(), it will
+// definitely be matched by a corresponding call to finishProfile(). It's
+// a struct rather than a class simply because every member is public.
+struct ShaderProfileHelper
+{
+	ShaderProfileHelper()
+	{
+		LLGLSLShader::initProfile();
+	}
+	~ShaderProfileHelper()
+	{
+		LLGLSLShader::finishProfile(false);
+	}
+};
+
+// This helper class is used to ensure that each generateTextures() call
+// is matched by a corresponding deleteTextures() call. It also handles
+// the bindManual() calls using those textures.
+class TextureHolder
+{
+public:
+	TextureHolder(U32 unit, U32 size) :
+		texUnit(gGL.getTexUnit(unit)),
+		source(size)			// preallocate vector
+	{
+		// takes (count, pointer)
+		// &vector[0] gets pointer to contiguous array
+		LLImageGL::generateTextures(source.size(), &source[0]);
+	}
+
+	~TextureHolder()
+	{
+		// unbind
+		if (texUnit)
+		{
+			texUnit->unbind(LLTexUnit::TT_TEXTURE);
+		}
+		// ensure that we delete these textures regardless of how we exit
+		LLImageGL::deleteTextures(source.size(), &source[0]);
+	}
+
+	bool bind(U32 index)
+	{
+		if (texUnit) // should always be there with dummy (-1), but just in case
+		{
+			return texUnit->bindManual(LLTexUnit::TT_TEXTURE, source[index]);
+		}
+		return false;
+	}
+
+private:
+	// capture which LLTexUnit we're going to use
+	LLTexUnit* texUnit;
+
+	// use std::vector for implicit resource management
+	std::vector<U32> source;
+};
+
+class ShaderBinder
+{
+public:
+	ShaderBinder(LLGLSLShader& shader) :
+		mShader(shader)
+	{
+		mShader.bind();
+	}
+	~ShaderBinder()
+	{
+		mShader.unbind();
+	}
+
+private:
+	LLGLSLShader& mShader;
+};
+
+
+//-----------------------------------------------------------------------------
+// gpu_benchmark()
+//-----------------------------------------------------------------------------
 F32 gpu_benchmark()
 {
+#if LL_WINDOWS
+	if (gGLManager.mIsIntel
+		&& std::string::npos != LLOSInfo::instance().getOSStringSimple().find("Microsoft Windows 8")) // or 8.1
+	{ // don't run benchmark on Windows 8/8.1 based PCs with Intel GPU (MAINT-8197)
+		LL_WARNS() << "Skipping gpu_benchmark() for Intel graphics on Windows 8." << LL_ENDL;
+		return -1.f;
+	}
+#endif
+
 	if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery)
 	{ // don't bother benchmarking the fixed function
       // or venerable drivers which don't support accurate timing anyway
@@ -922,59 +1014,9 @@ F32 gpu_benchmark()
 
 	//number of samples to take
 	const S32 samples = 64;
-
-	// This struct is used to ensure that once we call initProfile(), it will
-	// definitely be matched by a corresponding call to finishProfile(). It's
-	// a struct rather than a class simply because every member is public.
-	struct ShaderProfileHelper
-	{
-		ShaderProfileHelper()
-		{
-			LLGLSLShader::initProfile();
-		}
-		~ShaderProfileHelper()
-		{
-			LLGLSLShader::finishProfile(false);
-		}
-	};
+		
 	ShaderProfileHelper initProfile;
-
-	// This helper class is used to ensure that each generateTextures() call
-	// is matched by a corresponding deleteTextures() call. It also handles
-	// the bindManual() calls using those textures.
-	class TextureHolder
-	{
-	public:
-		TextureHolder(U32 unit, U32 size):
-			texUnit(gGL.getTexUnit(unit)),
-			source(size)			// preallocate vector
-		{
-			// takes (count, pointer)
-			// &vector[0] gets pointer to contiguous array
-			LLImageGL::generateTextures(source.size(), &source[0]);
-		}
-
-		~TextureHolder()
-		{
-			// unbind
-			texUnit->unbind(LLTexUnit::TT_TEXTURE);
-			// ensure that we delete these textures regardless of how we exit
-			LLImageGL::deleteTextures(source.size(), &source[0]);
-		}
-
-		void bind(U32 index)
-		{
-			texUnit->bindManual(LLTexUnit::TT_TEXTURE, source[index]);
-		}
-
-	private:
-		// capture which LLTexUnit we're going to use
-		LLTexUnit* texUnit;
-
-		// use std::vector for implicit resource management
-		std::vector<U32> source;
-	};
-
+	
 	std::vector<LLRenderTarget> dest(count);
 	TextureHolder texHolder(0, count);
 	std::vector<F32> results;
@@ -987,18 +1029,31 @@ F32 gpu_benchmark()
 		pixels[i] = (U8) ll_rand(255);
 	}
 	
-
 	gGL.setColorMask(true, true);
 	LLGLDepthTest depth(GL_FALSE);
 
 	for (U32 i = 0; i < count; ++i)
-	{ //allocate render targets and textures
-		dest[i].allocate(res,res,GL_RGBA,false, false, LLTexUnit::TT_TEXTURE, true);
+	{
+		//allocate render targets and textures
+		if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
+		{
+			LL_WARNS() << "Failed to allocate render target." << LL_ENDL;
+			// abandon the benchmark test
+			delete[] pixels;
+			return -1.f;
+		}
 		dest[i].bindTarget();
 		dest[i].clear();
 		dest[i].flush();
 
-		texHolder.bind(i);
+		if (!texHolder.bind(i))
+		{
+			// can use a dummy value mDummyTexUnit = new LLTexUnit(-1);
+			LL_WARNS() << "Failed to bind tex unit." << LL_ENDL;
+			// abandon the benchmark test
+			delete[] pixels;
+			return -1.f;
+		}
 		LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 	}
 
@@ -1006,7 +1061,13 @@ F32 gpu_benchmark()
 
 	//make a dummy triangle to draw with
 	LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STATIC_DRAW_ARB);
-	buff->allocateBuffer(3, 0, true);
+
+	if (!buff->allocateBuffer(3, 0, true))
+	{
+		LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL;
+		// abandon the benchmark test
+		return -1.f;
+	}
 
 	LLStrider<LLVector3> v;
 	LLStrider<LLVector2> tc;
@@ -1029,22 +1090,6 @@ F32 gpu_benchmark()
 	buff->flush();
 
 	// ensure matched pair of bind() and unbind() calls
-	class ShaderBinder
-	{
-	public:
-		ShaderBinder(LLGLSLShader& shader):
-			mShader(shader)
-		{
-			mShader.bind();
-		}
-		~ShaderBinder()
-		{
-			mShader.unbind();
-		}
-
-	private:
-		LLGLSLShader& mShader;
-	};
 	ShaderBinder binder(gBenchmarkProgram);
 
 	buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -1103,4 +1148,3 @@ F32 gpu_benchmark()
 
 	return gbps;
 }
-
-- 
cgit v1.2.3


From b10e46167b7aa3b44c4d2fb3fcdcbdc4f6e11096 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Mon, 29 Jan 2018 12:40:44 +0000
Subject: MAINT-8234 Mesh tread protections and removed unnecessary try in
 staticRun()

---
 indra/llcommon/llthread.cpp        | 58 +++++++++++++-------------------------
 indra/newview/llmeshrepository.cpp | 21 ++++++++++++--
 2 files changed, 38 insertions(+), 41 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index b96b2ce4bc..e353230791 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -129,50 +129,32 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 
     sThreadID = threadp->mID;
 
-    try
+    // Run the user supplied function
+    do 
     {
-        // Run the user supplied function
-        do 
+        try
         {
-            try
-            {
-                threadp->run();
-            }
-            catch (const LLContinueError &e)
-            {
-                LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName <<
-                    "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
-                //output possible call stacks to log file.
-                LLError::LLCallStacks::print();
-
-                LOG_UNHANDLED_EXCEPTION("LLThread");
-                continue;
-            }
-            break;
-
-        } while (true);
+            threadp->run();
+        }
+        catch (const LLContinueError &e)
+        {
+            LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName <<
+                "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
+            //output possible call stacks to log file.
+            LLError::LLCallStacks::print();
 
-        //LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
+            LOG_UNHANDLED_EXCEPTION("LLThread");
+            continue;
+        }
+        break;
 
-        // We're done with the run function, this thread is done executing now.
-        //NB: we are using this flag to sync across threads...we really need memory barriers here
-        threadp->mStatus = STOPPED;
-    }
-    catch (std::bad_alloc)
-    {
-        threadp->mStatus = CRASHED;
-        LLMemory::logMemoryInfo(TRUE);
+    } while (true);
 
-        //output possible call stacks to log file.
-        LLError::LLCallStacks::print();
+    //LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
 
-        LL_ERRS("THREAD") << "Bad memory allocation in LLThread::staticRun() named '" << threadp->mName << "'!" << LL_ENDL;
-    }
-    catch (...)
-    {
-        threadp->mStatus = CRASHED;
-        CRASH_ON_UNHANDLED_EXCEPTION("LLThread");
-    }
+    // We're done with the run function, this thread is done executing now.
+    //NB: we are using this flag to sync across threads...we really need memory barriers here
+    threadp->mStatus = STOPPED;
 
     delete threadp->mRecorder;
     threadp->mRecorder = NULL;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 51ca7a8a51..fdaa28b22b 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1224,7 +1224,12 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 				LLMeshRepository::sCacheBytesRead += size;
 				++LLMeshRepository::sCacheReads;
 				file.seek(offset);
-				U8* buffer = new U8[size];
+				U8* buffer = new(std::nothrow) U8[size];
+				if (!buffer)
+				{
+					LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info" << LL_ENDL;
+					return false;
+				}
 				file.read(buffer, size);
 
 				//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
@@ -1316,7 +1321,12 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 				++LLMeshRepository::sCacheReads;
 
 				file.seek(offset);
-				U8* buffer = new U8[size];
+				U8* buffer = new(std::nothrow) U8[size];
+				if (!buffer)
+				{
+					LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition" << LL_ENDL;
+					return false;
+				}
 				file.read(buffer, size);
 
 				//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
@@ -1407,7 +1417,12 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 				LLMeshRepository::sCacheBytesRead += size;
 				++LLMeshRepository::sCacheReads;
 				file.seek(offset);
-				U8* buffer = new U8[size];
+				U8* buffer = new(std::nothrow) U8[size];
+				if (!buffer)
+				{
+					LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape" << LL_ENDL;
+					return false;
+				}
 				file.read(buffer, size);
 
 				//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
-- 
cgit v1.2.3


From bd786ada4f773b0ba13536f26a7858bd9ad69791 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Fri, 9 Feb 2018 14:19:31 +0200
Subject: MAINT-8279 Fix for crash on unset pcode

---
 indra/newview/llviewerobjectlist.cpp | 24 +++++++++++++++++-------
 indra/newview/llviewerpartsim.cpp    |  4 ++--
 2 files changed, 19 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index fede9a792f..dc54346d59 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -478,15 +478,25 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 			{
 				U32 flags = 0;
 				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
-                
-				if(flags & FLAGS_TEMPORARY_ON_REZ)
+
+				compressed_dp.unpackUUID(fullid, "ID");
+				compressed_dp.unpackU32(local_id, "LocalID");
+				compressed_dp.unpackU8(pcode, "PCode");
+				
+				if (pcode == 0)
 				{
-                    compressed_dp.unpackUUID(fullid, "ID");
-                    compressed_dp.unpackU32(local_id, "LocalID");
-                    compressed_dp.unpackU8(pcode, "PCode");
-                }
-				else //send to object cache
+					// object creation will fail, LLViewerObject::createObject()
+					LL_WARNS() << "Received object " << fullid
+						<< " with 0 PCode. Local id: " << local_id
+						<< " Flags: " << flags
+						<< " Region: " << regionp->getName()
+						<< " Region id: " << regionp->getRegionID() << LL_ENDL;
+					recorder.objectUpdateFailure(local_id, update_type, msg_size);
+					continue;
+				}
+				else if ((flags & FLAGS_TEMPORARY_ON_REZ) == 0)
 				{
+					//send to object cache
 					regionp->cacheFullUpdate(compressed_dp, flags);
 					continue;
 				}
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index b066793e3d..25cf082751 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -756,7 +756,7 @@ void LLViewerPartSim::updateSimulation()
 		LLViewerObject* vobj = mViewerPartGroups[i]->mVOPartGroupp;
 
 		S32 visirate = 1;
-		if (vobj)
+		if (vobj && !vobj->isDead() && vobj->mDrawable && !vobj->mDrawable->isDead())
 		{
 			LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
 			if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
@@ -767,7 +767,7 @@ void LLViewerPartSim::updateSimulation()
 
 		if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%visirate == 0)
 		{
-			if (vobj)
+			if (vobj && !vobj->isDead())
 			{
 				gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
 			}
-- 
cgit v1.2.3


From 9773809f71e24ad7fbd8dcdbc43f6e355b664a4f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 2 Feb 2018 18:06:16 +0200
Subject: MAINT-8262 Crash in LLInventoryModel::createNewCategory(..)

---
 indra/newview/llinventorymodel.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 054db2a3ec..6a1ec9f991 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -617,6 +617,11 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 		return LLUUID::null;
 	}
 
+	if (!gMessageSystem)
+	{
+		return LLUUID::null;
+	}
+
 	// Add the category to the internal representation
 	LLPointer<LLViewerInventoryCategory> cat =
 		new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID());
-- 
cgit v1.2.3


From 3b4ae3fe5250cd0343303ef6892d289c98462465 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 5 Feb 2018 16:52:13 +0200
Subject: MAINT-8269 Crahes in cacheOptimize()

---
 indra/llmath/llvolume.cpp | 61 +++++++++++++++++++++++++++++++++++++----------
 indra/llmath/llvolume.h   |  4 ++--
 2 files changed, 51 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 014de6b888..24f46d720b 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2677,11 +2677,17 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 			}
 		}
 	}
+
+	if (!cacheOptimize())
+	{
+		// Out of memory?
+		LL_WARNS() << "Failed to optimize!" << LL_ENDL;
+		mVolumeFaces.clear();
+		return false;
+	}
 	
 	mSculptLevel = 0;  // success!
 
-	cacheOptimize();
-
 	return true;
 }
 
@@ -2713,12 +2719,16 @@ void LLVolume::copyVolumeFaces(const LLVolume* volume)
 	mSculptLevel = 0;
 }
 
-void LLVolume::cacheOptimize()
+bool LLVolume::cacheOptimize()
 {
 	for (S32 i = 0; i < mVolumeFaces.size(); ++i)
 	{
-		mVolumeFaces[i].cacheOptimize();
+		if (!mVolumeFaces[i].cacheOptimize())
+		{
+			return false;
+		}
 	}
+	return true;
 }
 
 
@@ -5174,7 +5184,7 @@ public:
 };
 
 
-void LLVolumeFace::cacheOptimize()
+bool LLVolumeFace::cacheOptimize()
 { //optimize for vertex cache according to Forsyth method: 
   // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
 	
@@ -5185,7 +5195,7 @@ void LLVolumeFace::cacheOptimize()
 	
 	if (mNumVertices < 3)
 	{ //nothing to do
-		return;
+		return true;
 	}
 
 	//mapping of vertices to triangles and indices
@@ -5194,8 +5204,16 @@ void LLVolumeFace::cacheOptimize()
 	//mapping of triangles do vertices
 	std::vector<LLVCacheTriangleData> triangle_data;
 
-	triangle_data.resize(mNumIndices/3);
-	vertex_data.resize(mNumVertices);
+	try
+	{
+		triangle_data.resize(mNumIndices / 3);
+		vertex_data.resize(mNumVertices);
+	}
+	catch (std::bad_alloc)
+	{
+		LL_WARNS("LLVOLUME") << "Resize failed" << LL_ENDL;
+		return false;
+	}
 
 	for (U32 i = 0; i < mNumIndices; i++)
 	{ //populate vertex data and triangle data arrays
@@ -5307,7 +5325,8 @@ void LLVolumeFace::cacheOptimize()
 	LLVector4a* pos = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size);
 	if (pos == NULL)
 	{
-		LL_ERRS("LLVOLUME") << "Allocation of positions vector[" << sizeof(LLVector4a) * 2 * num_verts + size  << "] failed. " << LL_ENDL;
+		LL_WARNS("LLVOLUME") << "Allocation of positions vector[" << sizeof(LLVector4a) * 2 * num_verts + size  << "] failed. " << LL_ENDL;
+		return false;
 	}
 	LLVector4a* norm = pos + num_verts;
 	LLVector2* tc = (LLVector2*) (norm + num_verts);
@@ -5318,7 +5337,9 @@ void LLVolumeFace::cacheOptimize()
 		wght = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
 		if (wght == NULL)
 		{
-			LL_ERRS("LLVOLUME") << "Allocation of weights[" << sizeof(LLVector4a) * num_verts << "] failed" << LL_ENDL;
+			ll_aligned_free<64>(pos);
+			LL_WARNS("LLVOLUME") << "Allocation of weights[" << sizeof(LLVector4a) * num_verts << "] failed" << LL_ENDL;
+			return false;
 		}
 	}
 
@@ -5328,13 +5349,28 @@ void LLVolumeFace::cacheOptimize()
 		binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
 		if (binorm == NULL)
 		{
-			LL_ERRS("LLVOLUME") << "Allocation of binormals[" << sizeof(LLVector4a)*num_verts << "] failed" << LL_ENDL;
+			ll_aligned_free<64>(pos);
+			ll_aligned_free_16(wght);
+			LL_WARNS("LLVOLUME") << "Allocation of binormals[" << sizeof(LLVector4a)*num_verts << "] failed" << LL_ENDL;
+			return false;
 		}
 	}
 
 	//allocate mapping of old indices to new indices
 	std::vector<S32> new_idx;
-	new_idx.resize(mNumVertices, -1);
+
+	try
+	{
+		new_idx.resize(mNumVertices, -1);
+	}
+	catch (std::bad_alloc)
+	{
+		ll_aligned_free<64>(pos);
+		ll_aligned_free_16(wght);
+		ll_aligned_free_16(binorm);
+		LL_WARNS("LLVOLUME") << "Resize failed: " << mNumVertices << LL_ENDL;
+		return false;
+	}
 
 	S32 cur_idx = 0;
 	for (U32 i = 0; i < mNumIndices; ++i)
@@ -5380,6 +5416,7 @@ void LLVolumeFace::cacheOptimize()
 	//std::string result = llformat("ACMR pre/post: %.3f/%.3f  --  %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
 	//LL_INFOS() << result << LL_ENDL;
 
+	return true;
 }
 
 void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size)
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index bba691d243..a8089f3709 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -903,7 +903,7 @@ public:
 	};
 
 	void optimize(F32 angle_cutoff = 2.f);
-	void cacheOptimize();
+	bool cacheOptimize();
 
 	void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
 
@@ -1063,7 +1063,7 @@ public:
 	void copyVolumeFaces(const LLVolume* volume);
 	void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
 	void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
-	void cacheOptimize();
+	bool cacheOptimize();
 
 private:
 	void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
-- 
cgit v1.2.3


From 4d7a59c232aa5844a936e9883cb2bee4c01aaaba Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 6 Feb 2018 18:44:57 +0200
Subject: MAINT-8273 FIXED Crash in
 LLViewerInventoryMoveFromWorldObserver::isSelectionChanged()

---
 indra/newview/llviewermessage.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 94a86a7831..e9085f9327 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -871,7 +871,7 @@ private:
 	 */
 	bool isSelectionChanged()
 	{	
-		LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
+		LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel();
 
 		if (NULL == active_panel)
 		{
@@ -881,7 +881,7 @@ private:
 		// get selected items (without destination folder)
 		selected_items_t selected_items;
  		
- 		std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+		std::set<LLFolderViewItem*> selection = active_panel->getRootFolder()->getSelectionList();
 		for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end();
 			it != end_it;
 			++it)
-- 
cgit v1.2.3


From f8c76535a35aaf245e261357a59e977bac5b2501 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 1 Mar 2018 16:51:48 -0500
Subject: increment viewer version to 5.1.3

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 61fcc87350..cdb98d26e4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-5.1.2
+5.1.3
-- 
cgit v1.2.3