diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 59b6115fab78c9da9ff4f4ef5735ac2bf0dea3ed..c213e0492a7b8aa2e011558d6acc66f90f821192 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -574,6 +574,17 @@
       <key>Value</key>
       <integer>2</integer>
     </map>
+    <key>AvatarUseBakedTextureTimeout</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifes whether to send your baked textures for avatar appearance even before textures are fully ressed in case of timeout</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AvatarSex</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index fd392d949a6525536ccede755970e4584e28e17f..847462a6c3e4ca60da93d96e965a73bda42cd9ef 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -160,8 +160,7 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
 {
 	if (gAgent.isGodlike())
 	{
-		LLFloaterAvatarTextures* self = (LLFloaterAvatarTextures*)data;
-		LLVOAvatar* avatarp = find_avatar(self->mID);
+		const LLVOAvatarSelf* avatarp = gAgentAvatarp;
 		if (!avatarp) return;
 		for (S32 i = 0; i < avatarp->getNumTEs(); i++)
 		{
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 4be03596f84f07d3be2217390f4e194b13ceaaa8..8c733ab558485d95bc8f692bb6a21d009f7fa56d 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -37,6 +37,7 @@
 #include "llagent.h"
 #include "llimagej2c.h"
 #include "llimagetga.h"
+#include "llnotificationsutil.h"
 #include "llvfile.h"
 #include "llvfs.h"
 #include "llviewerstats.h"
@@ -49,6 +50,7 @@
 #include "llui.h"
 #include "llagentwearables.h"
 #include "llwearable.h"
+#include "llviewercontrol.h"
 #include "llviewervisualparam.h"
 
 //#include "../tools/imdebug/imdebug.h"
@@ -60,10 +62,12 @@ using namespace LLVOAvatarDefines;
 //-----------------------------------------------------------------------------
 LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
 									 LLTexLayerSet* layerset,
-									 const LLUUID& id) : 
+									 const LLUUID& id,
+									 BOOL highest_lod) : 
 	mAvatar(avatar),
 	mTexLayerSet(layerset),
 	mID(id),
+	mHighestLOD(highest_lod),
 	mStartTime(LLFrameTimer::getTotalTime())		// Record starting time
 { 
 }
@@ -80,12 +84,14 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,
 										 S32 width, S32 height) :
 	// ORDER_LAST => must render these after the hints are created.
 	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
-	mNeedsUpdate( TRUE ),
-	mNeedsUpload( FALSE ),
-	mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates
+	mNeedsUpdate(TRUE),
+	mNeedsUpload(FALSE),
+	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
+	mNeedsLowResUpload(TRUE),
 	mTexLayerSet(owner)
 {
 	LLTexLayerSetBuffer::sGLByteCount += getSize();
+	mNeedsUploadTimer.start();
 }
 
 LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
@@ -125,7 +131,6 @@ void LLTexLayerSetBuffer::dumpTotalByteCount()
 void LLTexLayerSetBuffer::requestUpdate()
 {
 	mNeedsUpdate = TRUE;
-
 	// If we're in the middle of uploading a baked texture, we don't care about it any more.
 	// When it's downloaded, ignore it.
 	mUploadID.setNull();
@@ -133,20 +138,23 @@ void LLTexLayerSetBuffer::requestUpdate()
 
 void LLTexLayerSetBuffer::requestUpload()
 {
+	// New upload request
 	if (!mNeedsUpload)
 	{
-		mNeedsUpload = TRUE;
-		mUploadPending = TRUE;
+		mNeedsUploadTimer.start();
 	}
+
+	mNeedsUpload = TRUE;
+	mNeedsLowResUpload = TRUE;
+	mUploadPending = TRUE;
 }
 
 void LLTexLayerSetBuffer::cancelUpload()
 {
-	if (mNeedsUpload)
-	{
-		mNeedsUpload = FALSE;
-	}
+	mNeedsUpload = FALSE;
+	mNeedsLowResUpload = FALSE;
 	mUploadPending = FALSE;
+	mNeedsUploadTimer.pause();
 }
 
 void LLTexLayerSetBuffer::pushProjection() const
@@ -174,7 +182,8 @@ BOOL LLTexLayerSetBuffer::needsRender()
 {
 	llassert(mTexLayerSet->getAvatar() == gAgentAvatarp);
 	if (!isAgentAvatarValid()) return FALSE;
-	BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgentQueryManager.hasNoPendingQueries();
+
+	const BOOL upload_now = isReadyToUpload();
 	BOOL needs_update = (mNeedsUpdate || upload_now) && !gAgentAvatarp->mAppearanceAnimating;
 	if (needs_update)
 	{
@@ -191,6 +200,7 @@ BOOL LLTexLayerSetBuffer::needsRender()
 			needs_update &= mTexLayerSet->isLocalTextureDataAvailable();
 		}
 	}
+
 	return needs_update;
 }
 
@@ -217,7 +227,7 @@ BOOL LLTexLayerSetBuffer::render()
 
 	// do we need to upload, and do we have sufficient data to create an uploadable composite?
 	// When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
-	BOOL upload_now = (gAgentQueryManager.hasNoPendingQueries() && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal());
+	const BOOL upload_now = isReadyToUpload();
 	BOOL success = TRUE;
 
 
@@ -226,11 +236,11 @@ BOOL LLTexLayerSetBuffer::render()
 	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
 	gGL.flush();
 
-	if( upload_now )
+	if(upload_now)
 	{
 		if (!success)
 		{
-			llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl;
+			llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
 			mUploadPending = FALSE;
 		}
 		else
@@ -244,6 +254,8 @@ BOOL LLTexLayerSetBuffer::render()
 			{
 				mUploadPending = FALSE;
 				mNeedsUpload = FALSE;
+				mNeedsLowResUpload = FALSE;
+				mNeedsUploadTimer.pause();
 				mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE);
 			}
 		}
@@ -265,6 +277,25 @@ bool LLTexLayerSetBuffer::isInitialized(void) const
 	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
 }
 
+BOOL LLTexLayerSetBuffer::isReadyToUpload() const
+{
+	if (!mNeedsUpload) return FALSE; // Don't need to upload if we haven't requested one.
+	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
+	
+	// If we requested an upload and have the final LOD ready, then upload.
+	const BOOL can_highest_lod = mTexLayerSet->isLocalTextureDataFinal();
+	if (can_highest_lod) return TRUE;
+
+	if (gSavedSettings.getBOOL("AvatarUseBakedTextureTimeout"))
+	{
+		// If we hit our timeout and have textures available at even lower resolution, then upload.
+		const BOOL is_upload_textures_timeout = isUploadTimeout();
+		const BOOL can_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
+		if (can_lower_lod && is_upload_textures_timeout && mNeedsLowResUpload) return TRUE; 
+	}
+	return FALSE;
+}
+
 BOOL LLTexLayerSetBuffer::updateImmediate()
 {
 	mNeedsUpdate = TRUE;
@@ -288,7 +319,7 @@ void LLTexLayerSetBuffer::readBackAndUpload()
 	glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
 	stop_glerror();
 
-	llinfos << "Baked " << mTexLayerSet->getBodyRegion() << llendl;
+	llinfos << "Baked " << mTexLayerSet->getBodyRegionName() << llendl;
 	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
 
 	// We won't need our caches since we're baked now.  (Techically, we won't 
@@ -355,9 +386,12 @@ void LLTexLayerSetBuffer::readBackAndUpload()
 			
 			if( valid )
 			{
+				const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
 				// baked_upload_data is owned by the responder and deleted after the request completes
-				LLBakedUploadData* baked_upload_data =
-					new LLBakedUploadData(gAgentAvatarp, this->mTexLayerSet, asset_id);
+				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
+																			 this->mTexLayerSet, 
+																			 asset_id,
+																			 highest_lod);
 				mUploadID = asset_id;
 				
 				// upload the image
@@ -384,8 +418,26 @@ void LLTexLayerSetBuffer::readBackAndUpload()
 												  TRUE,		// is_priority
 												  TRUE);	// store_local
 				}
+
+				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+				{
+					std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+					LLSD args;
+					args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
+					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
+					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
+					args["RESOLUTION"] = lod_str;
+					LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args);
+					llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;
+				}
 		
-				mNeedsUpload = FALSE;
+				if (highest_lod)
+				{
+					mNeedsUpload = FALSE;
+					mNeedsUploadTimer.pause();
+				}
+				else
+					mNeedsLowResUpload = FALSE;
 			}
 			else
 			{
@@ -414,12 +466,11 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
 {
 	LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
 
-	if (0 == result &&
+	if ((result == 0) &&
 		isAgentAvatarValid() &&
 		!gAgentAvatarp->isDead() &&
-		baked_upload_data->mAvatar == gAgentAvatarp && // Sanity check: only the user's avatar should be uploading textures.
-		baked_upload_data->mTexLayerSet->hasComposite()
-		)
+		(baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
+		(baked_upload_data->mTexLayerSet->hasComposite()))
 	{
 		LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
 			
@@ -438,10 +489,9 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
 		{
 			// This is the upload we're currently waiting for.
 			layerset_buffer->mUploadID.setNull();
-			layerset_buffer->mUploadPending = FALSE;
-
 			if (result >= 0)
 			{
+				layerset_buffer->mUploadPending = FALSE;
 				LLVOAvatarDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet);
 				// Update baked texture info with the new UUID
 				U64 now = LLFrameTimer::getTotalTime();		// Record starting time
@@ -758,7 +808,7 @@ BOOL LLTexLayerSet::isBodyRegion(const std::string& region) const
 	return mInfo->mBodyRegion == region; 
 }
 
-const std::string LLTexLayerSet::getBodyRegion() const 
+const std::string LLTexLayerSet::getBodyRegionName() const 
 { 
 	return mInfo->mBodyRegion; 
 }
@@ -788,7 +838,7 @@ void LLTexLayerSet::cancelUpload()
 
 void LLTexLayerSet::createComposite()
 {
-	if( !mComposite )
+	if(!mComposite)
 	{
 		S32 width = mInfo->mWidth;
 		S32 height = mInfo->mHeight;
@@ -823,7 +873,15 @@ void LLTexLayerSet::updateComposite()
 
 LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
 {
-	createComposite();
+	if (!mComposite)
+	{
+		createComposite();
+	}
+	return mComposite;
+}
+
+const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
+{
 	return mComposite;
 }
 
@@ -2169,4 +2227,24 @@ BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLIma
 	return success;
 }
 
+BOOL LLTexLayerSetBuffer::isUploadTimeout() const
+{
+	//const F32 BAKED_TEXTURES_TIMEOUT_THRESHOLD__SECONDS = 20.f;
+	const F32 UPLOAD_TEXTURES_TIMEOUT_THRESHOLD__SECONDS = 5.f; // SERAPH Reduced timeout for testing.
 
+	return (mNeedsUploadTimer.getElapsedTimeF32() >= UPLOAD_TEXTURES_TIMEOUT_THRESHOLD__SECONDS);
+}
+
+const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
+{
+	if (!isAgentAvatarValid()) return "";
+
+	const BOOL is_high_res = !mNeedsUpload;
+	const BOOL is_low_res = !mNeedsLowResUpload;
+	const U32 upload_time = mNeedsUploadTimer.getElapsedTimeF32();
+	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
+	std::string text = llformat("[ HiRes:%d LoRes:%d Timer:%d ] %s",
+								is_high_res, is_low_res, upload_time, 
+								local_texture_info.c_str());
+	return text;
+}
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index ae280dd0633d6f4348c1f58ada7f82c19a4733c8..f2d86032fb74edb3fc3f29b394a391b101e5a27f 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -253,6 +253,7 @@ class LLTexLayerSet
 
 	BOOL					isBodyRegion(const std::string& region) const;
 	LLTexLayerSetBuffer*	getComposite();
+	const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
 	void					requestUpdate();
 	void					requestUpload();
 	void					cancelUpload();
@@ -272,7 +273,7 @@ class LLTexLayerSet
 	void					cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
 	
 	LLVOAvatarSelf*		    getAvatar()	const { return mAvatar; }
-	const std::string		getBodyRegion() const;
+	const std::string		getBodyRegionName() const;
 	BOOL					hasComposite() const { return (mComposite.notNull()); }
 	LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
 	void					setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
@@ -344,22 +345,33 @@ class LLTexLayerSetBuffer : public LLViewerDynamicTexture
 													S32 result, LLExtStat ext_status);
 	static void				dumpTotalByteCount();
 
+	const std::string		dumpTextureInfo() const;
+
 	virtual void restoreGLTexture();
 	virtual void destroyGLTexture();
 
-private:
+protected:
 	void					pushProjection() const;
 	void					popProjection() const;
-
+	BOOL					isReadyToUpload() const;
+	
 private:
 	LLTexLayerSet* const    mTexLayerSet;
 
-	BOOL					mNeedsUpdate;
-	BOOL					mNeedsUpload;
-	BOOL					mUploadPending;
-	LLUUID					mUploadID; // Identifys the current upload process (null if none).  Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
+	BOOL					mNeedsUpdate; // Whether we need to update our baked textures
+	BOOL					mNeedsUpload; // Whether we need to send our baked textures to the server
+	BOOL					mNeedsLowResUpload; // Whether we have sent a lowres version of our baked textures to the server
+	BOOL					mUploadPending; // Whether we have received back the new baked textures
+	LLUUID					mUploadID; // Identifies the current upload process (null if none).  Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
 
 	static S32				sGLByteCount;
+	
+	// Low res upload methods
+protected:
+	BOOL					isUploadTimeout() const;
+private:
+	LLFrameTimer    		mNeedsUploadTimer; // Tracks time since upload was requested
+
 };
 
 //
@@ -404,13 +416,18 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 class LLBakedUploadData
 {
 public:
-	LLBakedUploadData(const LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, const LLUUID& id);
+	LLBakedUploadData(const LLVOAvatarSelf* avatar, 
+					  LLTexLayerSet* layerset, 
+					  const LLUUID& id,
+					  BOOL highest_lod);
 	~LLBakedUploadData() {}
 
 	const LLUUID				mID;
 	const LLVOAvatarSelf*		mAvatar;	 // just backlink, don't LLPointer 
 	LLTexLayerSet*				mTexLayerSet;
    	const U64					mStartTime;		// Used to measure time baked texture upload requires
+	BOOL						mHighestLOD;
+
 };
 
 
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index efdddd947b1cc7a889a1ab534180db9f9ac421c9..a1ab051021222c2bd94609cc7473860109161f1d 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1286,8 +1286,8 @@ void LLTextureCtrl::draw()
 				LLFontGL::DROP_SHADOW);
 		}
 
-		// Show more detailed information if this agent is god.
-		if (gAgent.isGodlike())
+		// Optionally show more detailed information.
+		if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
 		{
 			LLFontGL* font = LLFontGL::getFontSansSerif();
 			std::string tdesc;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 43913f3632636b49c22c072d6ed6fcdade4ecbe8..e04568d4ed35a49e7e3fd2c44e953b1c97c587d0 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -54,6 +54,11 @@
 #include "llviewertexture.h"
 #include "llviewertexturelist.h"
 #include "llvovolume.h"
+
+// For avatar texture view
+#include "llvoavatarself.h"
+#include "lltexlayer.h"
+
 extern F32 texmem_lower_bound_scale;
 
 LLTextureView *gTextureView = NULL;
@@ -375,6 +380,84 @@ LLRect LLTextureBar::getRequiredRect()
 
 ////////////////////////////////////////////////////////////////////////////
 
+class LLAvatarTexBar : public LLView
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLView::Params>
+	{
+		Mandatory<LLTextureView*>	texture_view;
+		Params()
+		:	texture_view("texture_view")
+		{
+			S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
+			rect(LLRect(0,0,100,line_height * 4));
+		}
+	};
+
+	LLAvatarTexBar(const Params& p)
+	:	LLView(p),
+		mTextureView(p.texture_view)
+	{}
+
+	virtual void draw();	
+	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	virtual LLRect getRequiredRect();	// Return the height of this object, given the set options.
+
+private:
+	LLTextureView* mTextureView;
+};
+
+void LLAvatarTexBar::draw()
+{	
+	if (!gSavedSettings.getBOOL("DebugAvatarRezTime")) return;
+
+	LLVOAvatarSelf* avatarp = gAgentAvatarp;
+	if (!avatarp) return;
+
+	const S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
+	const S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f);
+	//----------------------------------------------------------------------------
+	LLGLSUIDefault gls_ui;
+	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
+	LLColor4 color;
+	
+	U32 line_num = 6;
+	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
+		if (!layerset) continue;
+		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		if (!layerset_buffer) continue;
+		std::string text = layerset_buffer->dumpTextureInfo();
+		LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*line_num,
+												 text_color, LLFontGL::LEFT, LLFontGL::TOP);
+		line_num++;
+	}
+	/*
+	std::string text = "Baked Textures:";
+	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*line_num,
+											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
+	*/
+
+}
+
+BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	return FALSE;
+}
+
+LLRect LLAvatarTexBar::getRequiredRect()
+{
+	LLRect rect;
+	rect.mTop = 8;
+	return rect;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
 class LLGLTexMemBar : public LLView
 {
 public:
@@ -412,13 +495,17 @@ void LLGLTexMemBar::draw()
 	F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
 	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
 	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
-	S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f);
+	S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 5.0f);
 	//----------------------------------------------------------------------------
 	LLGLSUIDefault gls_ui;
 	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
 	LLColor4 color;
 	
-	std::string text;
+	std::string text = "";
+
+	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
+											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
+
 	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
 					total_mem,
 					max_total_mem,
@@ -640,6 +727,7 @@ LLTextureView::LLTextureView(const LLTextureView::Params& p)
 	
 	setDisplayChildren(TRUE);
 	mGLTexMemBar = 0;
+	mAvatarTexBar = 0;
 }
 
 LLTextureView::~LLTextureView()
@@ -647,6 +735,9 @@ LLTextureView::~LLTextureView()
 	// Children all cleaned up by default view destructor.
 	delete mGLTexMemBar;
 	mGLTexMemBar = 0;
+	
+	delete mAvatarTexBar;
+	mAvatarTexBar = 0;
 }
 
 typedef std::pair<F32,LLViewerFetchedTexture*> decode_pair_t;
@@ -684,6 +775,13 @@ void LLTextureView::draw()
 			mGLTexMemBar = 0;
 		}
 
+		if (mAvatarTexBar)
+		{
+			removeChild(mAvatarTexBar);
+			mAvatarTexBar->die();
+			mAvatarTexBar = 0;
+		}
+
 		typedef std::multiset<decode_pair_t, compare_decode_pair > display_list_t;
 		display_list_t display_image_list;
 	
@@ -851,7 +949,14 @@ void LLTextureView::draw()
 		tmbp.texture_view(this);
 		mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp);
 		addChild(mGLTexMemBar);
-	
+
+		LLAvatarTexBar::Params atbp;
+		atbp.name("gl avatartex bar");
+		atbp.texture_view(this);
+		mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp);
+		addChild(mAvatarTexBar);
+
+
 		reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
 
 		/*
diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h
index 435a55df8357a35dfa21fe95952fcc7224cfae45..6072cd3f11051631bd17ae6a29612dd9144b325b 100644
--- a/indra/newview/lltextureview.h
+++ b/indra/newview/lltextureview.h
@@ -43,6 +43,7 @@ class LLTextureView : public LLContainerView
 {
 	friend class LLTextureBar;
 	friend class LLGLTexMemBar;
+	friend class LLAvatarTexBar;
 protected:
 	LLTextureView(const Params&);
 	friend class LLUICtrlFactory;
@@ -73,7 +74,7 @@ class LLTextureView : public LLContainerView
 	U32 mNumTextureBars;
 
 	LLGLTexMemBar* mGLTexMemBar;
-	
+	LLAvatarTexBar* mAvatarTexBar;
 public:
 	static std::set<LLViewerFetchedTexture*> sDebugImages;
 };
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a72d7f9227225012525d6d66b511005a209c4d9f..04b4b4f017fa619a675f5f6214bf0cf1574993b1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5940,10 +5940,9 @@ void LLVOAvatar::updateRuthTimer(bool loading)
 		mRuthDebugTimer.reset();
 	}
 	
-	const F32 LOADING_TIMEOUT = 120.f;
-	if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT)
+	const F32 LOADING_TIMEOUT__SECONDS = 120.f;
+	if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS)
 	{
-		
 		llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' "
 				<< "( Params loaded : " << !visualParamWeightsAreDefault() << " ) "
 				<< "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) "
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index df47e9ba1d3769122e4b009968d09beb4ef01c2c..70a27cb2aac093beb90e16a13526cb13a11bcc9a 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -920,6 +920,8 @@ class LLVOAvatar :
 	//--------------------------------------------------------------------
 	// Avatar Rez Metrics
 	//--------------------------------------------------------------------
+public:
+	F32				debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); }
 protected:
 	LLFrameTimer	mRuthDebugTimer; // For tracking how long it takes for av to rez
 	LLFrameTimer	mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index a8e2f446c2133c601a91640c8a97d5fac0d8b16d..0c563458e77c09ef5f2fccab78b97ea858da10ea 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1372,7 +1372,7 @@ void LLVOAvatarSelf::requestLayerSetUploads()
 void LLVOAvatarSelf::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i)
 {
 	ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
-	bool  layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
+	const BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
 	if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet)
 	{
 		mBakedTextureDatas[i].mTexLayerSet->requestUpload();
@@ -1389,8 +1389,8 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		BOOL upload_pending = (mBakedTextureDatas[i].mTexLayerSet && mBakedTextureDatas[i].mTexLayerSet->getComposite()->uploadPending());
-		if (upload_pending)
+		LLTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet;
+		if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending())
 		{
 			return true;
 		}
@@ -1404,7 +1404,7 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_r
 	{
 		return;
 	}
-	// llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegion() << llendl;
+	// llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << llendl;
 
 	layerset->requestUpdate();
 	layerset->invalidateMorphMasks();
@@ -1829,6 +1829,47 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini
 	mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32();
 }
 
+std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const
+{
+	std::string text="";
+
+	text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset));
+
+	/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
+	   return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
+	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const EBakedTextureIndex baked_index = baked_iter->first;
+		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+		{
+			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+			text += llformat("[%d] '%s' ",baked_index, baked_dict->mName.c_str());
+			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+				 local_tex_iter != baked_dict->mLocalTextures.end();
+				 ++local_tex_iter)
+			{
+				const ETextureIndex tex_index = *local_tex_iter;
+				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+				if (wearable_count > 0)
+				{
+					text += LLWearableType::getTypeName(wearable_type) + ":";
+					for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+					{
+						const U32 discard_level = getLocalDiscardLevel(tex_index, wearable_index);
+						std::string discard_str = llformat("%d ",discard_level);
+						text += llformat("%d ",discard_level);
+					}
+				}
+			}
+			break;
+		}
+	}
+	return text;
+}
+
 const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const
 {
 	if (canGrabBakedTexture(baked_index))
@@ -2055,6 +2096,18 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
 	{
 		llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
 	}
+
+	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLTexLayerSet *layerset = debugGetLayerSet(baked_index);
+		if (!layerset) continue;
+		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		if (!layerset_buffer) continue;
+		llinfos << layerset_buffer->dumpTextureInfo() << llendl;
+	}
 }
 
 //-----------------------------------------------------------------------------
@@ -2153,7 +2206,6 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
 
 	// Don't know if this is needed
 	updateMeshTextures();
-
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 189c1ac80805cab0cb0553c7815428baa2791817..ad92807a72816439093ebe8f84b368a11c10daad 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -218,8 +218,6 @@ class LLVOAvatarSelf :
 	static void			processRebakeAvatarTextures(LLMessageSystem* msg, void**);
 protected:
 	/*virtual*/ void	removeMissingBakedTextures();
-private:
-	LLFrameTimer    	mBakeTimeoutTimer;
 
 	//--------------------------------------------------------------------
 	// Layers
@@ -356,6 +354,9 @@ class LLVOAvatarSelf :
 	void outputRezDiagnostics() const;
 	void debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished);
 	static void		debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+
+	const LLTexLayerSet*  debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }
+	std::string		debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const;
 private:
 	LLFrameTimer    mDebugSelfLoadTimer;
 	F32				mDebugTimeWearablesLoaded;
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 0bf71844bfa6a37818659107dbc2f713ce4bdb79..404b87ec1c99cb275276f2419b4dc7a289f5c8a8 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6190,6 +6190,14 @@ Avatar '[NAME]' left appearance mode.
 Avatar '[NAME]' left as fully loaded.
   </notification>
 
+  <notification
+   icon="notifytip.tga"
+   name="AvatarRezSelfBakeNotification"
+   type="notifytip">
+( [EXISTENCE] seconds alive )
+You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="ConfirmLeaveCall"