diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index c18917b66346296b862584875fb58f9a34d1ccf8..0cd96676444b18222b33cc4bacb766b951c62367 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -61,6 +61,8 @@ class LLTexture : public LLRefCount
 	//
 	//interfaces to access LLViewerTexture
 	//
+	virtual S8         getType() const = 0 ;
+	virtual void       setKnownDrawSize(S32 width, S32 height) = 0 ;
 	virtual bool       bindDefaultImage(const S32 stage = 0) const = 0 ;
 	virtual void       forceImmediateUpdate() = 0 ;
 	virtual void       setActive() = 0 ;
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 66c2ba682fc474b115c511c31c87ed0bd5ede5c5..82ffac9580f0fcba517492cd8f33704d6fc2df20 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -57,7 +57,9 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
 :	LLUICtrl(p),
 	mColor(p.color()),
 	mImagep(p.image),
-	mPriority(0)
+	mPriority(0),
+	mDrawWidth(0),
+	mDrawHeight(0)
 {
 	if (mImagep.notNull())
 	{
@@ -100,6 +102,8 @@ void LLIconCtrl::setValue(const LLSD& value )
 	{
 		mImagep = LLUI::getUIImage(tvalue.asString(), mPriority);
 	}
+
+	setIconImageDrawSize();
 }
 
 std::string LLIconCtrl::getImageName() const
@@ -109,3 +113,14 @@ std::string LLIconCtrl::getImageName() const
 	else
 		return std::string();
 }
+
+void LLIconCtrl::setIconImageDrawSize()
+{
+	if(mImagep.notNull() && mDrawWidth && mDrawHeight)
+	{
+		if(mImagep->getImage().notNull())
+		{
+			mImagep->getImage()->setKnownDrawSize(mDrawWidth, mDrawHeight) ;
+		}
+	}
+}
\ No newline at end of file
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index 90f1693060475846f53eb0526a9390cf6f64a0e4..66368f979b6a74d9baedc8294fe1f6d5c6d6b844 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -60,6 +60,7 @@ class LLIconCtrl
 protected:
 	LLIconCtrl(const Params&);
 	friend class LLUICtrlFactory;
+
 public:
 	virtual ~LLIconCtrl();
 
@@ -73,9 +74,16 @@ class LLIconCtrl
 
 	void			setColor(const LLColor4& color) { mColor = color; }
 	
+private:
+	void setIconImageDrawSize() ;
+
 protected:
 	S32 mPriority;
 
+	//the output size of the icon image if set.
+	S32 mDrawWidth ;
+	S32 mDrawHeight ;
+
 private:
 	LLUIColor mColor;
 	LLPointer<LLUIImage> mImagep;
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index ebcda13dd495310df29805b485192122db4f353c..b56e8d1ec2546009a1dcf2d893cec0b5680dc9ef 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -155,6 +155,8 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
 	mPriority = LLViewerFetchedTexture::BOOST_ICON;
 	
 	LLRect rect = p.rect;
+	mDrawWidth  = llmax(32, rect.getWidth()) ;
+	mDrawHeight = llmax(32, rect.getHeight()) ;
 
 	static LLUICachedControl<S32> llavatariconctrl_symbol_hpad("UIAvatariconctrlSymbolHPad", 2);
 	static LLUICachedControl<S32> llavatariconctrl_symbol_vpad("UIAvatariconctrlSymbolVPad", 2);
@@ -193,7 +195,6 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
 		LLIconCtrl::setValue("default_profile_picture.j2c");
 	}
 
-
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
 	registrar.add("AvatarIcon.Action", boost::bind(&LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked, this, _2));
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 09b3ce1e863b4acc51ddf94b35ec3845875d4b48..0276cd9a24577b30960c537faa4015c795ad5149 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -278,6 +278,16 @@ void LLFace::setTexture(LLViewerTexture* tex)
 	}
 
 	mTexture = tex ;
+
+	//check if this texture is replaced by a parcel media texture.
+	if(mTexture.notNull() && mTexture->hasParcelMedia()) 
+	{
+		LLViewerMediaTexture* mediap = LLViewerTextureManager::findMediaTexture(mTexture->getID()) ;
+		if(mediap)
+		{
+			mediap->addMediaToFace(this) ;
+		}
+	}
 }
 
 void LLFace::dirtyTexture()
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index d734b327d95f86c7e90b69c573da4f82101d67ea..2b134c8c3148c4eac66a7258a3677aceb6407b66 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -246,7 +246,7 @@ class LLFace
 
 	//atlas
 	LLPointer<LLTextureAtlasSlot> mAtlasInfop ;
-	BOOL                              mUsingAtlas ;
+	BOOL                          mUsingAtlas ;
 	
 protected:
 	static BOOL	sSafeRenderSelect;
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 216bca8262ceb96bff83b02da00dcefa146f0771..fc8790c1722f664ce1a7235693a6cf735e6d1adb 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -704,7 +704,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
 	}
 
 	if (volume->mLODChanged || volume->mFaceMappingChanged ||
-		volume->mVolumeChanged)
+		volume->mVolumeChanged || drawable->isState(LLDrawable::REBUILD_MATERIAL))
 	{
 		volume->regenFaces();
 		volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME);
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e5c53c91c90b03feff444d15dee23a9337dffedf..28ef128265b4191eb63252004b5b31548d982ce1 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -93,6 +93,7 @@ BOOL LLViewerTexture::sUseTextureAtlas        = FALSE ;
 
 const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
 const F32 desired_discard_bias_max = 1.5f; // max number of levels to reduce image quality by
+const F64 log_2 = log(2.0);
 
 //----------------------------------------------------------------------------------------------
 //namespace: LLViewerTextureAccess
@@ -134,7 +135,7 @@ LLViewerMediaTexture*  LLViewerTextureManager::getMediaTexture(const LLUUID& id,
 	return tex ;
 }
 
-LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error)
+LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLTexture* tex, BOOL report_error)
 {
 	if(!tex)
 	{
@@ -415,6 +416,7 @@ void LLViewerTexture::init(bool firstinit)
 	mDontDiscard = FALSE;
 	mMaxVirtualSize = 0.f;
 	mNeedsResetMaxVirtualSize = FALSE ;
+	mHasParcelMedia = FALSE ;
 }
 
 //virtual 
@@ -522,6 +524,12 @@ F32 LLViewerTexture::getMaxVirtualSize()
 	return mMaxVirtualSize ;
 }
 
+//virtual 
+void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
+{
+	//nothing here.
+}
+
 //virtual
 void LLViewerTexture::addFace(LLFace* facep) 
 {
@@ -852,6 +860,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
 
 	mKnownDrawWidth = 0;
 	mKnownDrawHeight = 0;
+	mKnownDrawSizeChanged = FALSE ;
 
 	if (firstinit)
 	{
@@ -1084,10 +1093,17 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 }
 
 // Call with 0,0 to turn this feature off.
+//virtual
 void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
 {
-	mKnownDrawWidth = width;
-	mKnownDrawHeight = height;
+	if(mKnownDrawWidth != width || mKnownDrawHeight != height)
+	{
+		mKnownDrawWidth = width;
+		mKnownDrawHeight = height;
+
+		mKnownDrawSizeChanged = TRUE ;
+		mFullyLoaded = FALSE ;
+	}
 	addTextureStats((F32)(width * height));
 }
 
@@ -1104,13 +1120,26 @@ void LLViewerFetchedTexture::processTextureStats()
 		mDesiredDiscardLevel = 	getMaxDiscardLevel() ;
 	}
 	else
-	{
-		mDesiredDiscardLevel = 0;
-		if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+	{	
+		if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
 		{
-			mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+			if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+			{
+				mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+			}
+			else
+			{
+				mDesiredDiscardLevel = 0;
+			}
 		}
-
+		else if(mKnownDrawSizeChanged)//known draw size is set
+		{			
+			mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, 
+					                             log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
+			mDesiredDiscardLevel = 	llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
+		}
+		mKnownDrawSizeChanged = FALSE ;
+		
 		if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
 		{
 			mFullyLoaded = TRUE ;
@@ -1121,8 +1150,6 @@ void LLViewerFetchedTexture::processTextureStats()
 //texture does not have any data, so we don't know the size of the image, treat it like 32 * 32.
 F32 LLViewerFetchedTexture::calcDecodePriorityForUnknownTexture(F32 pixel_priority)
 {
-	static const F64 log_2 = log(2.0);
-
 	F32 desired = (F32)(log(32.0/pixel_priority) / log_2);
 	S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired + 1;
 	ddiscard = llclamp(ddiscard, 1, 9);
@@ -1169,7 +1196,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 		// Don't decode anything we don't need
 		priority = -1.0f;
 	}
-	else if (mBoostLevel == LLViewerTexture::BOOST_UI && !have_all_data)
+	else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
 	{
 		priority = 1.f;
 	}
@@ -2124,19 +2151,20 @@ void LLViewerMediaTexture::updateClass()
 	for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
 	{
 		LLViewerMediaTexture* mediap = iter->second;	
-
-		//
-		//Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
-		//
-		if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap
-		{
-			media_map_t::iterator cur = iter++ ;
-			sMediaMap.erase(cur) ;
-		}
-		else
+		
+		if(mediap->getNumRefs() == 1) //one reference by sMediaMap
 		{
-			++iter ;
+			//
+			//Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
+			//
+			if(mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME)
+			{
+				media_map_t::iterator cur = iter++ ;
+				sMediaMap.erase(cur) ;
+				continue ;
+			}
 		}
+		++iter ;
 	}
 }
 
@@ -2189,11 +2217,22 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
 	mIsPlaying = FALSE ;
 
 	setMediaImpl() ;
+
+	LLViewerTexture* tex = gTextureList.findImage(mID) ;
+	if(tex) //this media is a parcel media for tex.
+	{
+		tex->setParcelMedia(TRUE) ;
+		mParcelTexture = tex ;
+	}
 }
 
 //virtual 
 LLViewerMediaTexture::~LLViewerMediaTexture() 
 {	
+	if(mParcelTexture.notNull())
+	{
+		mParcelTexture->setParcelMedia(FALSE) ;
+	}
 }
 
 void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
@@ -2246,10 +2285,19 @@ BOOL LLViewerMediaTexture::findFaces()
 	BOOL ret = TRUE ;
 
 	//for parcel media
-	LLViewerTexture* tex = gTextureList.findImage(mID) ;	
-	if(tex)
+	if(mParcelTexture.isNull())
+	{
+		LLViewerTexture* tex = gTextureList.findImage(mID) ;
+		if(tex)
+		{
+			tex->setParcelMedia(TRUE) ;
+			mParcelTexture = tex ;
+		}
+	}
+	
+	if(mParcelTexture.notNull())
 	{
-		const ll_face_list_t* face_list = tex->getFaceList() ;
+		const ll_face_list_t* face_list = mParcelTexture->getFaceList() ;
 		for(ll_face_list_t::const_iterator iter = face_list->begin(); iter != face_list->end(); ++iter)
 		{
 			mMediaFaceList.push_back(*iter) ;
@@ -2356,9 +2404,14 @@ void LLViewerMediaTexture::addFace(LLFace* facep)
 	if(facep->getTexture() && facep->getTexture() != this && facep->getTexture()->getID() == mID)
 	{
 		mTextureList.push_back(facep->getTexture()) ; //a parcel media.
+		if(mParcelTexture.isNull())
+		{			
+			mParcelTexture = facep->getTexture() ;
+			mParcelTexture->setParcelMedia(TRUE) ;
+		}
 		return ;
 	}
-
+	
 	llerrs << "The face does not have a valid texture before media texture." << llendl ;
 }
 
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 480e1c1cbcc2d38bd429210f6e0fea26a85063ca..ce8c47b87833a37437f0d251da441e667cdb0558 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -163,6 +163,7 @@ class LLViewerTexture : public LLTexture
 	
 	S32 getFullWidth() const { return mFullWidth; }
 	S32 getFullHeight() const { return mFullHeight; }	
+	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 
 	virtual void addFace(LLFace* facep) ;
 	virtual void removeFace(LLFace* facep) ; 
@@ -220,6 +221,9 @@ class LLViewerTexture : public LLTexture
 	BOOL getDontDiscard() const { return mDontDiscard; }
 	//-----------------	
 	
+	void setParcelMedia(BOOL has_media) {mHasParcelMedia = has_media;}
+	BOOL hasParcelMedia() const { return mHasParcelMedia ;}
+
 	/*virtual*/ void updateBindStatsForTester() ;
 protected:
 	void cleanup() ;
@@ -246,6 +250,8 @@ class LLViewerTexture : public LLTexture
 	LLPointer<LLImageGL> mGLTexturep ;
 	S8 mDontDiscard;			// Keep full res version of this image (for UI, etc)
 
+	BOOL mHasParcelMedia ;
+
 protected:
 	typedef enum 
 	{
@@ -357,7 +363,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	// Override the computation of discard levels if we know the exact output
 	// size of the image.  Used for UI textures to not decode, even if we have
 	// more data.
-	void setKnownDrawSize(S32 width, S32 height);
+	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 
 	void setIsMissingAsset();
 	/*virtual*/ BOOL isMissingAsset()	const		{ return mIsMissingAsset; }
@@ -406,6 +412,8 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	BOOL  mFullyLoaded;
 
 protected:		
+	std::string mLocalFileName;
+
 	S32 mOrigWidth;
 	S32 mOrigHeight;
 
@@ -413,8 +421,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	// Used for UI textures to not decode, even if we have more data.
 	S32 mKnownDrawWidth;
 	S32	mKnownDrawHeight;
-
-	std::string mLocalFileName;
+	BOOL mKnownDrawSizeChanged ;
 
 	S8  mDesiredDiscardLevel;			// The discard level we'd LIKE to have - if we have it and there's space	
 	S8  mMinDesiredDiscardLevel;	// The minimum discard level we'd like to have
@@ -545,6 +552,7 @@ class LLViewerMediaTexture : public LLViewerTexture
 	LLViewerMediaImpl* mMediaImplp ;	
 	BOOL mIsPlaying ;
 	U32  mUpdateVirtualSizeTime ;
+	LLPointer< LLViewerTexture > mParcelTexture ; //the texture replaces this media texure when it is a parcel media texture.
 
 public:
 	static void updateClass() ;
@@ -570,7 +578,7 @@ class LLViewerTextureManager
 	static LLTexturePipelineTester* sTesterp ;
 
 	//returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture.
-	static LLViewerFetchedTexture*    staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error = FALSE) ;
+	static LLViewerFetchedTexture*    staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ;
 
 	//
 	//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.