From 01d68a9f1572fba971ace6944a91a85e7c379d1e Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Mon, 5 Dec 2011 16:28:13 -0700
Subject: call LLViewerTexture::isMemoryForTextureLow() less often and only for
 ATI cards.

---
 indra/newview/llviewertexture.cpp | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index f4bbc2b067..addf1147f2 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -420,8 +420,17 @@ F32 texmem_middle_bound_scale = 0.925f;
 //static 
 bool LLViewerTexture::isMemoryForTextureLow()
 {
-	const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
-	const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
+	const F32 WAIT_TIME = 1.0f ; //second
+	static LLFrameTimer timer ;
+
+	if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
+	{
+		return false;
+	}
+	timer.reset() ;
+
+	const S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
+	const S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB	
 
 	bool low_mem = false ;
 	if (gGLManager.mHasATIMemInfo)
@@ -433,6 +442,15 @@ bool LLViewerTexture::isMemoryForTextureLow()
 		{
 			low_mem = true ;
 		}
+
+		if(!low_mem) //check main memory, only works for windows.
+		{
+			LLMemory::updateMemoryInfo() ;
+			if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
+			{
+				low_mem = true ;
+			}
+		}
 	}
 #if 0  //ignore nVidia cards
 	else if (gGLManager.mHasNVXMemInfo)
@@ -445,16 +463,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
 			low_mem = true ;
 		}
 	}
-#endif
-
-	if(!low_mem) //check main memory, only works for windows.
-	{
-		LLMemory::updateMemoryInfo() ;
-		if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
-		{
-			low_mem = true ;
-		}
-	}
+#endif	
 
 	return low_mem ;
 }
-- 
cgit v1.2.3


From 78233d1bf9930575ee7250257ac68603f41f568a Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 5 Dec 2011 17:55:40 -0600
Subject: SH-2652 WIP -- Add timers to relevant areas, pause render pipeline
 while occlusion queries from previous frame are still pending and perform
 texture decode work.

---
 indra/llcommon/llqueuedthread.cpp    |  4 ++--
 indra/llcommon/llqueuedthread.h      |  4 ++--
 indra/llcommon/llworkerthread.cpp    |  2 +-
 indra/llcommon/llworkerthread.h      |  2 +-
 indra/llimage/llimageworker.cpp      |  2 +-
 indra/llimage/llimageworker.h        |  2 +-
 indra/llmessage/llcurl.cpp           |  2 +-
 indra/llmessage/llcurl.h             |  2 +-
 indra/newview/llappviewer.cpp        |  8 +++++---
 indra/newview/llspatialpartition.cpp | 26 ++++++++++++++++++++++++++
 indra/newview/llspatialpartition.h   |  2 ++
 indra/newview/lltexturecache.cpp     |  2 +-
 indra/newview/lltexturecache.h       |  2 +-
 indra/newview/lltexturefetch.cpp     |  2 +-
 indra/newview/lltexturefetch.h       |  2 +-
 indra/newview/llviewertexture.cpp    | 14 +++++++++++++-
 16 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 5dee7a3541..1738c16dea 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -109,7 +109,7 @@ void LLQueuedThread::shutdown()
 
 // MAIN THREAD
 // virtual
-S32 LLQueuedThread::update(U32 max_time_ms)
+S32 LLQueuedThread::update(F32 max_time_ms)
 {
 	if (!mStarted)
 	{
@@ -122,7 +122,7 @@ S32 LLQueuedThread::update(U32 max_time_ms)
 	return updateQueue(max_time_ms);
 }
 
-S32 LLQueuedThread::updateQueue(U32 max_time_ms)
+S32 LLQueuedThread::updateQueue(F32 max_time_ms)
 {
 	F64 max_time = (F64)max_time_ms * .001;
 	LLTimer timer;
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index 499d13a792..d3704b0fe2 100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
@@ -173,8 +173,8 @@ protected:
 public:
 	bool waitForResult(handle_t handle, bool auto_complete = true);
 
-	virtual S32 update(U32 max_time_ms);
-	S32 updateQueue(U32 max_time_ms);
+	virtual S32 update(F32 max_time_ms);
+	S32 updateQueue(F32 max_time_ms);
 	
 	void waitOnPending();
 	void printQueueStats();
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 4988bdf570..3d05a30ac2 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -81,7 +81,7 @@ void LLWorkerThread::clearDeleteList()
 }
 
 // virtual
-S32 LLWorkerThread::update(U32 max_time_ms)
+S32 LLWorkerThread::update(F32 max_time_ms)
 {
 	S32 res = LLQueuedThread::update(max_time_ms);
 	// Delete scheduled workers
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 78a4781d15..be46394d6e 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -86,7 +86,7 @@ public:
 	LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false);
 	~LLWorkerThread();
 
-	/*virtual*/ S32 update(U32 max_time_ms);
+	/*virtual*/ S32 update(F32 max_time_ms);
 	
 	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
 	
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 28dc3bd313..ad2eb0f69c 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -46,7 +46,7 @@ LLImageDecodeThread::~LLImageDecodeThread()
 
 // MAIN THREAD
 // virtual
-S32 LLImageDecodeThread::update(U32 max_time_ms)
+S32 LLImageDecodeThread::update(F32 max_time_ms)
 {
 	LLMutexLock lock(mCreationMutex);
 	for (creation_list_t::iterator iter = mCreationList.begin();
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index c684222fa5..1bfb0ddfd3 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -78,7 +78,7 @@ public:
 	handle_t decodeImage(LLImageFormatted* image,
 						 U32 priority, S32 discard, BOOL needs_aux,
 						 Responder* responder);
-	S32 update(U32 max_time_ms);
+	S32 update(F32 max_time_ms);
 
 	// Used by unit tests to check the consistency of the thread instance
 	S32 tut_size();
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 7ca25d07fc..ce0632668c 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -841,7 +841,7 @@ LLCurlThread::~LLCurlThread()
 {
 }
 
-S32 LLCurlThread::update(U32 max_time_ms)
+S32 LLCurlThread::update(F32 max_time_ms)
 {	
 	return LLQueuedThread::update(max_time_ms);
 }
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index a275db3e53..2c95279438 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -344,7 +344,7 @@ public:
 	LLCurlThread(bool threaded = true) ;
 	virtual ~LLCurlThread() ;
 
-	S32 update(U32 max_time_ms);
+	S32 update(F32 max_time_ms);
 
 	void addMulti(LLCurl::Multi* multi) ;
 	void killMulti(LLCurl::Multi* multi) ;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e80475f096..9455bf9875 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1345,17 +1345,19 @@ bool LLAppViewer::mainLoop()
 				{
 					S32 work_pending = 0;
 					S32 io_pending = 0;
+					F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+
 					{
 						LLFastTimer ftm(FTM_TEXTURE_CACHE);
- 						work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
+ 						work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
 					}
 					{
 						LLFastTimer ftm(FTM_DECODE);
-	 					work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+	 					work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
 					}
 					{
 						LLFastTimer ftm(FTM_DECODE);
-	 					work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+	 					work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
 					}
 
 					{
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 3e16ccf3da..fb107a302a 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -28,6 +28,10 @@
 
 #include "llspatialpartition.h"
 
+#include "llappviewer.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
 #include "llviewerwindow.h"
 #include "llviewerobjectlist.h"
 #include "llvovolume.h"
@@ -1221,6 +1225,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
 	for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
 	{
 		mOcclusionQuery[i] = 0;
+		mOcclusionIssued[i] = 0;
 		mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
 		mVisible[i] = 0;
 	}
@@ -1543,6 +1548,8 @@ BOOL LLSpatialGroup::rebound()
 }
 
 static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait");
+
 void LLSpatialGroup::checkOcclusion()
 {
 	if (LLPipeline::sUseOcclusion > 1)
@@ -1560,6 +1567,22 @@ void LLSpatialGroup::checkOcclusion()
 			if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
 			{
 				glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+
+				if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+				{ //query was issued last frame, wait until it's available
+					S32 max_loop = 1024;
+					LLFastTimer t(FTM_OCCLUSION_WAIT);
+					while (!available && max_loop-- > 0)
+					{
+						F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+						//do some usefu work while we wait
+						LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+						LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+						LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+						
+						glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+					}
+				}
 			}
 			else
 			{
@@ -1679,6 +1702,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 					{
 						LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
 						
+						//store which frame this query was issued on
+						mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
+
 						{
 							LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY);
 							glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index f0c8a372ee..899547ae4d 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -396,6 +396,8 @@ protected:
 
 	U32 mState;
 	U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
+	U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
+
 	S32 mLODHash;
 	static S32 sLODSeed;
 
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e7a176f4f9..8632890bbb 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -760,7 +760,7 @@ LLTextureCache::~LLTextureCache()
 //////////////////////////////////////////////////////////////////////////////
 
 //virtual
-S32 LLTextureCache::update(U32 max_time_ms)
+S32 LLTextureCache::update(F32 max_time_ms)
 {
 	static LLFrameTimer timer ;
 	static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds.
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 64e3a2658c..dd0cc9b4bd 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -101,7 +101,7 @@ public:
 	LLTextureCache(bool threaded);
 	~LLTextureCache();
 
-	/*virtual*/ S32 update(U32 max_time_ms);	
+	/*virtual*/ S32 update(F32 max_time_ms);	
 	
 	void purgeCache(ELLPath location);
 	void setReadOnly(BOOL read_only) ;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 56dfb61c4f..f18aa8b4e6 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2204,7 +2204,7 @@ void LLTextureFetch::commonUpdate()
 
 // MAIN THREAD
 //virtual
-S32 LLTextureFetch::update(U32 max_time_ms)
+S32 LLTextureFetch::update(F32 max_time_ms)
 {
 	static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS");
 
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index d101da1f4b..35df7d816f 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -55,7 +55,7 @@ public:
 
 	class TFRequest;
 	
-	/*virtual*/ S32 update(U32 max_time_ms);	
+	/*virtual*/ S32 update(F32 max_time_ms);	
 	void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down.
 	void shutDownImageDecodeThread() ;  //called in the main thread after the ImageDecodeThread shuts down.
 
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index b0f5361a79..1863992a22 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -417,9 +417,13 @@ const S32 min_non_tex_system_mem = (128<<20); // 128 MB
 F32 texmem_lower_bound_scale = 0.85f;
 F32 texmem_middle_bound_scale = 0.925f;
 
+static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check");
+
 //static 
 bool LLViewerTexture::isMemoryForTextureLow()
 {
+	LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK);
+
 	const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
 	const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
 
@@ -459,6 +463,9 @@ bool LLViewerTexture::isMemoryForTextureLow()
 	return low_mem ;
 }
 
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_MEDIA("Media");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_TEST("Test");
+
 //static
 void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
 {
@@ -467,9 +474,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 	LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
 	if (tester)
 	{
+		LLFastTimer t(FTM_TEXTURE_UPDATE_TEST);
 		tester->update() ;
 	}
-	LLViewerMediaTexture::updateClass() ;
+
+	{
+		LLFastTimer t(FTM_TEXTURE_UPDATE_MEDIA);
+		LLViewerMediaTexture::updateClass() ;
+	}
 
 	sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
 	sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
-- 
cgit v1.2.3


From 1a93abb9013d6960f1ff9eb491480f547c780ff0 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 5 Dec 2011 18:55:01 -0600
Subject: SH-2652 Bump fast timer location.

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

diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 2e1dc95483..126d0f75e8 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -423,7 +423,6 @@ static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check");
 bool LLViewerTexture::isMemoryForTextureLow()
 {
 	const F32 WAIT_TIME = 1.0f ; //second
-	LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK);
 	static LLFrameTimer timer ;
 
 	if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
@@ -432,6 +431,8 @@ bool LLViewerTexture::isMemoryForTextureLow()
 	}
 	timer.reset() ;
 
+	LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK);
+
 	const S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
 	const S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB	
 
-- 
cgit v1.2.3


From 22e46e4be76a448a27c59fedfeb84081d6624df8 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 6 Dec 2011 12:57:57 -0600
Subject: Fix for RenderResolutionDivisor no longer working correctly.

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

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 657cdc0e07..00acc3e511 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6333,17 +6333,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 	}
 
-	U32 res_mod = RenderResolutionDivisor;
-
 	LLVector2 tc1(0,0);
 	LLVector2 tc2((F32) mScreen.getWidth()*2,
 				  (F32) mScreen.getHeight()*2);
 
-	if (res_mod > 1)
-	{
-		tc2 /= (F32) res_mod;
-	}
-
 	LLFastTimer ftm(FTM_RENDER_BLOOM);
 	gGL.color4f(1,1,1,1);
 	LLGLDepthTest depth(GL_FALSE);
@@ -6807,7 +6800,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 				mFXAABuffer.bindTexture(0, channel);
 				gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
 			}
-						
+			
+			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
 			F32 scale_x = (F32) width/mFXAABuffer.getWidth();
 			F32 scale_y = (F32) height/mFXAABuffer.getHeight();
 			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
@@ -6827,11 +6826,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 	}
 	else
 	{
-		if (res_mod > 1)
-		{
-			tc2 /= (F32) res_mod;
-		}
-
 		U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
 		LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
 		buff->allocateBuffer(3,0,TRUE);
-- 
cgit v1.2.3


From 1a18184f50a3c98573ceb06d6ff3ca7bd42f6fc3 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 6 Dec 2011 16:45:30 -0700
Subject: fix for SH-2526: Second Life client quickly allocates all available
 RAM and crashes

---
 indra/llaudio/llaudioengine.cpp | 23 +++++++++++++++++++----
 indra/llaudio/llaudioengine.h   |  1 +
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 5e540ad8c5..5fa28cb902 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1264,6 +1264,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
 	mSyncSlave(false),
 	mQueueSounds(false),
 	mPlayedOnce(false),
+	mCorrupted(false),
 	mType(type),
 	mChannelp(NULL),
 	mCurrentDatap(NULL),
@@ -1296,16 +1297,25 @@ void LLAudioSource::setChannel(LLAudioChannel *channelp)
 
 void LLAudioSource::update()
 {
+	if(mCorrupted)
+	{
+		return ; //no need to update
+	}
+
 	if (!getCurrentBuffer())
 	{
 		if (getCurrentData())
 		{
 			// Hack - try and load the sound.  Will do this as a callback
 			// on decode later.
-			if (getCurrentData()->load())
+			if (getCurrentData()->load() && getCurrentData()->getBuffer())
 			{
 				play(getCurrentData()->getID());
-			}			
+			}
+			else
+			{
+				mCorrupted = true ;
+			}
 		}
 	}
 }
@@ -1421,6 +1431,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
 
 bool LLAudioSource::isDone() const
 {
+	if(mCorrupted)
+	{
+		return true ;
+	}
+
 	const F32 MAX_AGE = 60.f;
 	const F32 MAX_UNPLAYED_AGE = 15.f;
 	const F32 MAX_MUTED_AGE = 11.f;
@@ -1736,7 +1751,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
 	}
 }
 
-
+//return false when the audio file is corrupted.
 bool LLAudioData::load()
 {
 	// For now, just assume we're going to use one buffer per audiodata.
@@ -1752,7 +1767,7 @@ bool LLAudioData::load()
 	{
 		// No free buffers, abort.
 		llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
-		return false;
+		return true;
 	}
 
 	std::string uuid_str;
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index 30d2490635..a47ee7ca7c 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -334,6 +334,7 @@ protected:
 	bool			mSyncSlave;
 	bool			mQueueSounds;
 	bool			mPlayedOnce;
+	bool            mCorrupted;
 	S32             mType;
 	LLVector3d		mPositionGlobal;
 	LLVector3		mVelocity;
-- 
cgit v1.2.3