diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index e0cfa07614a718f3c9a52a30b03da56f13018a84..0463d5364bd6af6490e4751bb1995315a75b35dc 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -2252,7 +2252,7 @@ LLSD LLModel::Decomposition::asLLSD() const
 		ret["Positions"] = p;
 	}
 
-	llassert(!mBaseHull.empty());
+	//llassert(!mBaseHull.empty());
 
 	if (!mBaseHull.empty())
 	{
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 866cc39eec7f7a86ac841bd72665a7371143db1d..aa608ea67cff423332971442c0b86de50c8f24a8 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1121,7 +1121,7 @@ LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* pre
 							  std::deque<std::string>& jointsFromNodes )
 : mJointList( jointMap )
 , mJointsFromNode( jointsFromNodes )
-, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE)
+, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mNumOfFetchingTextures(0)
 {
 	mJointMap["mPelvis"] = "mPelvis";
 	mJointMap["mTorso"] = "mTorso";
@@ -2266,7 +2266,8 @@ void LLModelLoader::loadTextures()
 					iter->second[i].mMaterial[j].mDiffuseMap = 
 						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW);
 					iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);
-					iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage();
+					iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(0, F32_MAX);
+					mNumOfFetchingTextures++ ;
 				}
 			}
 		}
@@ -4140,6 +4141,14 @@ void LLModelPreview::updateStatusMessages()
 		}
 	}
 	
+	if(upload_ok && mModelLoader)
+	{
+		if(!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
+		{
+			upload_ok = false ;
+		}
+	}
+
 	const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
 	if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox)
 	{
@@ -5278,6 +5287,14 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture
 {
 	LLModelPreview* preview = (LLModelPreview*) userdata;
 	preview->refresh();
+
+	if(final && preview->mModelLoader)
+	{
+		if(preview->mModelLoader->mNumOfFetchingTextures > 0)
+		{
+			preview->mModelLoader->mNumOfFetchingTextures-- ;
+		}
+	}
 }
 
 void LLModelPreview::onLODParamCommit(bool enforce_tri_limit)
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index a328bfb4dd50414742f470f8f9e24038df85a8d6..dcc2fc889883aedcbc4dc5015f8c898015de7fe3 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -132,6 +132,9 @@ class LLModelLoader : public LLThread
 	JointTransformMap& mJointList;	
 	std::deque<std::string>& mJointsFromNode;
 
+	S32 mNumOfFetchingTextures ; //updated in the main thread
+	bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
+
 private:
 	static std::list<LLModelLoader*> sActiveLoaderList;
 	static bool isAlive(LLModelLoader* loader) ;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 4673289094526d71e6731d74fd8fc8a3013b5420..f8ffb16adbd884a878d3e32dc4a5319e0592d2e7 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1556,16 +1556,12 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 				std::stringstream texture_str;
 				if (texture != NULL && include_textures && mUploadTextures)
 				{
-					// Get binary rep of texture, if needed.
-					LLTextureUploadData data(texture, material.mDiffuseMapLabel);
-					if (!data.mTexture->isRawImageValid())
-					{
-						data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
+					if(texture->hasSavedRawImage())
+					{											
+						LLPointer<LLImageJ2C> upload_file =
+							LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
+						texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
 					}
-						
-					LLPointer<LLImageJ2C> upload_file =
-						LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
-					texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
 				}
 
 				if (texture != NULL &&
@@ -2868,9 +2864,12 @@ void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data)
 			data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
 		}
 
-		LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
+		if(data.mTexture->hasSavedRawImage())
+		{
+			LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getSavedRawImage());
 		
-		ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());
+			ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());
+		}
 
 		data.mAssetData = ostr.str();
 
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index af06421bf9db7c1d4686d739fc8df6d9879cc2c6..4da0f80a00281beff887a3fd191d8ebf6cb14942 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1168,6 +1168,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
 	mSavedRawDiscardLevel = -1 ;
 	mDesiredSavedRawDiscardLevel = -1 ;
 	mLastReferencedSavedRawImageTime = 0.0f ;
+	mKeptSavedRawImageTime = 0.f ;
 	mLastCallBackActiveTime = 0.f;
 }
 
@@ -2696,8 +2697,16 @@ void LLViewerFetchedTexture::saveRawImage()
 	mLastReferencedSavedRawImageTime = sCurrentTime ;
 }
 
-void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard) 
+void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time) 
 { 
+	mKeptSavedRawImageTime = kept_time ;
+	mLastReferencedSavedRawImageTime = sCurrentTime ;
+
+	if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard)
+	{
+		return ; //raw imge is ready.
+	}
+
 	if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard)
 	{
 		mForceToSaveRawImage = TRUE ;
@@ -2713,11 +2722,16 @@ void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard)
 
 			mRawImage = NULL ;
 			mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
-		}
+		}		
 	}
 }
 void LLViewerFetchedTexture::destroySavedRawImage()
 {
+	if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime)
+	{
+		return ; //keep the saved raw image.
+	}
+
 	mForceToSaveRawImage  = FALSE ;
 	mSaveRawImage = FALSE ;
 
@@ -2729,6 +2743,7 @@ void LLViewerFetchedTexture::destroySavedRawImage()
 	mSavedRawDiscardLevel = -1 ;
 	mDesiredSavedRawDiscardLevel = -1 ;
 	mLastReferencedSavedRawImageTime = 0.0f ;
+	mKeptSavedRawImageTime = 0.f ;
 }
 
 LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() 
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index d512f8ec3abc4f03a34a20aa4fbc8e4e5f28baf7..c5b8c8923ad52bf6b4eb16b363778221ee106e07 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -465,7 +465,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S32         getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
 	BOOL        isCachedRawImageReady() const {return mCachedRawImageReady ;}
 	BOOL        isRawImageValid()const { return mIsRawImageValid ; }	
-	void        forceToSaveRawImage(S32 desired_discard = 0) ;
+	void        forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
 	/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
 	void        destroySavedRawImage() ;
 	LLImageRaw* getSavedRawImage() ;
@@ -550,6 +550,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S32 mSavedRawDiscardLevel;
 	S32 mDesiredSavedRawDiscardLevel;
 	F32 mLastReferencedSavedRawImageTime ;
+	F32 mKeptSavedRawImageTime ;
 
 	//a small version of the copy of the raw image (<= 64 * 64)
 	LLPointer<LLImageRaw> mCachedRawImage;