diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 33 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 129 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 8 | ||||
| -rw-r--r-- | indra/newview/lldynamictexture.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llfloatermemleak.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/lltexturecache.cpp | 30 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 24 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 5 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 10 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 14 | 
15 files changed, 259 insertions, 57 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 58abd4c091..fac4cfbef9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1841,6 +1841,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>DebugShowPrivateMem</key> +    <map> +      <key>Comment</key> +      <string>Show Private Mem Info</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DebugShowRenderInfo</key>      <map>        <key>Comment</key> @@ -5220,6 +5231,17 @@        <key>Value</key>        <real>48.0</real>      </map> +    <key>MaxHeapSize</key> +    <map> +      <key>Comment</key> +      <string>Maximum heap size (GB)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>1.6</real> +    </map>      <key>MaxSelectDistance</key>      <map>        <key>Comment</key> @@ -5341,6 +5363,17 @@      <key>Value</key>      <integer>1</integer>    </map> +  <key>MemeoyFailurePreventionEnabled</key> +  <map> +    <key>Comment</key> +    <string>If set, the viewer will quit to avoid crash when memory failure happens</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>    <key>MemoryLogFrequency</key>          <map>          <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a23f809b71..89251d2d37 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -619,7 +619,7 @@ LLAppViewer::~LLAppViewer()  }  bool LLAppViewer::init() -{ +{	  	//  	// Start of the application  	// @@ -647,6 +647,9 @@ bool LLAppViewer::init()  	if (!initConfiguration())  		return false; +	//set the max heap size. +	initMaxHeapSize() ; +  	// write Google Breakpad minidump files to our log directory  	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");  	logdir += gDirUtilp->getDirDelimiter(); @@ -996,9 +999,97 @@ bool LLAppViewer::init()  	LLAgentLanguage::init(); +	return true; +} +void LLAppViewer::initMaxHeapSize() +{ +	//set the max heap size. +	//here is some info regarding to the max heap size: +	//------------------------------------------------------------------------------------------ +	// OS       | setting | SL address bits | max manageable memory space | max heap size +	// Win 32   | default | 32-bit          | 2GB                         | < 1.7GB +	// Win 32   | /3G     | 32-bit          | 3GB                         | < 1.7GB or 2.7GB +	//Linux 32  | default | 32-bit          | 3GB                         | < 2.7GB +	//Linux 32  |HUGEMEM  | 32-bit          | 4GB                         | < 3.7GB +	//64-bit OS |default  | 32-bit          | 4GB                         | < 3.7GB +	//64-bit OS |default  | 64-bit          | N/A (> 4GB)                 | N/A (> 4GB) +	//------------------------------------------------------------------------------------------ +	//currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. + +	//F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ; +	F32 max_heap_size_gb = gSavedSettings.getF32("MaxHeapSize") ; +	BOOL enable_mem_failure_prevention = (BOOL)gSavedSettings.getBOOL("MemeoyFailurePreventionEnabled") ; + +	LLMemory::initMaxHeapSizeGB(max_heap_size_gb, enable_mem_failure_prevention) ; +} -	return true; +void LLAppViewer::checkMemory() +{ +	const static F32 MEMORY_CHECK_INTERVAL = 1.0f ; //second +	const static F32 MAX_QUIT_WAIT_TIME = 30.0f ; //seconds +	const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB +	//static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ; +	static void* last_reserved_address = NULL ; + +	if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32()) +	{ +		return ; +	} +	mMemCheckTimer.reset() ; + +	if(gGLManager.mDebugGPU) +	{ +		//update the availability of memory +		LLMemory::updateMemoryInfo() ; +	} + +	//check the virtual address space fragmentation +	if(!last_reserved_address) +	{ +		last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; +	} +	else +	{ +		last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; +		if(!last_reserved_address) //failed, try once more +		{ +			last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; +		} +	} + +	S32 is_low = !last_reserved_address || LLMemory::isMemoryPoolLow() ; + +	//if(is_low < 0) //to force quit +	//{ +	//	if(force_quit_timer > MAX_QUIT_WAIT_TIME) //just hit the limit for the first time +	//	{ +	//		//send out the notification to tell the viewer is about to quit in 30 seconds. +	//		LLNotification::Params params("ForceQuitDueToLowMemory"); +	//		LLNotifications::instance().add(params); + +	//		force_quit_timer = MAX_QUIT_WAIT_TIME - MEMORY_CHECK_INTERVAL ; +	//	} +	//	else +	//	{ +	//		force_quit_timer -= MEMORY_CHECK_INTERVAL ; +	//		if(force_quit_timer < 0.f) +	//		{ +	//			forceQuit() ; //quit +	//		} +	//	} +	//} +	//else +	//{ +	//	force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ; +	//} + +	LLPipeline::throttleNewMemoryAllocation(!is_low ? FALSE : TRUE) ;		 +	 +	if(is_low) +	{ +		LLMemory::logMemoryInfo() ; +	}  }  static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages"); @@ -1036,7 +1127,6 @@ bool LLAppViewer::mainLoop()  	LLVoiceClient::getInstance()->init(gServicePump);  	LLTimer frameTimer,idleTimer;  	LLTimer debugTime; -	LLFrameTimer memCheckTimer;  	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());  	joystick->setNeedsReset(true); @@ -1047,7 +1137,9 @@ bool LLAppViewer::mainLoop()      // point of posting.      LLSD newFrame; -	const F32 memory_check_interval = 1.0f ; //second +	//LLPrivateMemoryPoolTester::getInstance()->run(false) ; +	//LLPrivateMemoryPoolTester::getInstance()->run(true) ; +	//LLPrivateMemoryPoolTester::destroy() ;  	// Handle messages  	while (!LLApp::isExiting()) @@ -1058,18 +1150,8 @@ bool LLAppViewer::mainLoop()  		llclearcallstacks;  		//check memory availability information -		{ -			if(memory_check_interval < memCheckTimer.getElapsedTimeF32()) -			{ -				memCheckTimer.reset() ; - -				//update the availability of memory -				LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ; -			} -			llcallstacks << "Available physical mem(KB): " << mAvailPhysicalMemInKB << llcallstacksendl ; -			llcallstacks << "Available virtual mem(KB): " << mAvailVirtualMemInKB << llcallstacksendl ; -		} - +		checkMemory() ; +		  		try  		{  			pingMainloopTimeout("Main:MiscNativeWindowEvents"); @@ -1233,7 +1315,7 @@ bool LLAppViewer::mainLoop()  				idleTimer.reset();  				bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ;  				S32 total_work_pending = 0; -				S32 total_io_pending = 0;				 +				S32 total_io_pending = 0;	  				while(!is_slow)//do not unpause threads if the frame rates are very low.  				{  					S32 work_pending = 0; @@ -1300,15 +1382,7 @@ bool LLAppViewer::mainLoop()  		}  		catch(std::bad_alloc)  		{			 -			{ -				llinfos << "Availabe physical memory(KB) at the beginning of the frame: " << mAvailPhysicalMemInKB << llendl ; -				llinfos << "Availabe virtual memory(KB) at the beginning of the frame: " << mAvailVirtualMemInKB << llendl ; - -				LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ; - -				llinfos << "Current availabe physical memory(KB): " << mAvailPhysicalMemInKB << llendl ; -				llinfos << "Current availabe virtual memory(KB): " << mAvailVirtualMemInKB << llendl ; -			} +			LLMemory::logMemoryInfo(TRUE) ;  			//stop memory leaking simulation  			LLFloaterMemLeak* mem_leak_instance = @@ -1777,6 +1851,9 @@ bool LLAppViewer::cleanup()  	LLMainLoopRepeater::instance().stop(); +	//release all private memory pools. +	LLPrivateMemoryPoolManager::destroyClass() ; +  	ll_close_fail_log();  	MEM_TRACK_RELEASE diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index a18e6cbb02..eff4cab2d0 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -168,7 +168,7 @@ public:  	// mute/unmute the system's master audio  	virtual void setMasterSystemAudioMute(bool mute); -	virtual bool getMasterSystemAudioMute(); +	virtual bool getMasterSystemAudioMute();	  	// Metrics policy helper statics.  	static void metricsUpdateRegion(U64 region_handle); @@ -190,11 +190,12 @@ protected:  private: +	void initMaxHeapSize();  	bool initThreads(); // Initialize viewer threads, return false on failure.  	bool initConfiguration(); // Initialize settings from the command line/config file.  	void initUpdater(); // Initialize the updater service.  	bool initCache(); // Initialize local client cache. - +	void checkMemory() ;  	// We have switched locations of both Mac and Windows cache, make sure  	// files migrate and old cache is cleared out. @@ -268,8 +269,7 @@ private:  	std::set<struct apr_dso_handle_t*> mPlugins; -	U32 mAvailPhysicalMemInKB ; -	U32 mAvailVirtualMemInKB ; +	LLFrameTimer mMemCheckTimer;  	boost::scoped_ptr<LLUpdaterService> mUpdater; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index f781d5f3ff..fb9958ee9d 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -40,6 +40,7 @@  #include "llvertexbuffer.h"  #include "llviewerdisplay.h"  #include "llrender.h" +#include "pipeline.h"  // static  LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; @@ -201,7 +202,7 @@ void LLViewerDynamicTexture::postRender(BOOL success)  BOOL LLViewerDynamicTexture::updateAllInstances()  {  	sNumRenders = 0; -	if (gGLManager.mIsDisabled) +	if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled)  	{  		return TRUE;  	} diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp index 58931d112e..9edfe1e354 100644 --- a/indra/newview/llfloatermemleak.cpp +++ b/indra/newview/llfloatermemleak.cpp @@ -90,6 +90,11 @@ LLFloaterMemLeak::~LLFloaterMemLeak()  void LLFloaterMemLeak::release()  { +	if(mLeakedMem.empty()) +	{ +		return ; +	} +  	for(S32 i = 0 ; i < (S32)mLeakedMem.size() ; i++)  	{  		delete[] mLeakedMem[i] ; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index f54214b95c..14e9ed79d7 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -113,7 +113,7 @@ public:  	~LLTextureCacheWorker()  	{  		llassert_always(!haveWork()); -		delete[] mReadData; +		LLImageBase::deleteMemory(mReadData);  	}  	// override this interface @@ -215,7 +215,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  			mDataSize = 0;  			return true;  		} -		mReadData = new U8[mDataSize]; +		mReadData = (U8*)LLImageBase::allocateMemory(mDataSize);  		mBytesRead = -1;  		mBytesToRead = mDataSize;  		setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); @@ -233,7 +233,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  // 						<< " Bytes: " << mDataSize << " Offset: " << mOffset  // 						<< " / " << mDataSize << llendl;  				mDataSize = 0; // failed -				delete[] mReadData; +				LLImageBase::deleteMemory(mReadData);  				mReadData = NULL;  			}  			return true; @@ -248,7 +248,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  	{  		mDataSize = local_size;  	} -	mReadData = new U8[mDataSize]; +	mReadData = (U8*)LLImageBase::allocateMemory(mDataSize);  	S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());	 @@ -258,7 +258,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  // 				<< " Bytes: " << mDataSize << " Offset: " << mOffset  // 				<< " / " << mDataSize << llendl;  		mDataSize = 0; -		delete[] mReadData; +		LLImageBase::deleteMemory(mReadData);  		mReadData = NULL;  	}  	else @@ -377,7 +377,7 @@ bool LLTextureCacheRemoteWorker::doRead()  			mDataSize = local_size;  		}  		// Allocate read buffer -		mReadData = new U8[mDataSize]; +		mReadData = (U8*)LLImageBase::allocateMemory(mDataSize);  		S32 bytes_read = LLAPRFile::readEx(local_filename,   											 mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());  		if (bytes_read != mDataSize) @@ -386,7 +386,7 @@ bool LLTextureCacheRemoteWorker::doRead()   					<< " Bytes: " << mDataSize << " Offset: " << mOffset   					<< " / " << mDataSize << llendl;  			mDataSize = 0; -			delete[] mReadData; +			LLImageBase::deleteMemory(mReadData);  			mReadData = NULL;  		}  		else @@ -429,7 +429,7 @@ bool LLTextureCacheRemoteWorker::doRead()  		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;  		size = llmin(size, mDataSize);  		// Allocate the read buffer -		mReadData = new U8[size]; +		mReadData = (U8*)LLImageBase::allocateMemory(size);  		S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName,   											 mReadData, offset, size, mCache->getLocalAPRFilePool());  		if (bytes_read != size) @@ -437,7 +437,7 @@ bool LLTextureCacheRemoteWorker::doRead()  			llwarns << "LLTextureCacheWorker: "  << mID  					<< " incorrect number of bytes read from header: " << bytes_read  					<< " / " << size << llendl; -			delete[] mReadData; +			LLImageBase::deleteMemory(mReadData);  			mReadData = NULL;  			mDataSize = -1; // failed  			done = true; @@ -467,7 +467,7 @@ bool LLTextureCacheRemoteWorker::doRead()  			S32 data_offset, file_size, file_offset;  			// Reserve the whole data buffer first -			U8* data = new U8[mDataSize]; +			U8* data = (U8*)LLImageBase::allocateMemory(mDataSize);  			// Set the data file pointers taking the read offset into account. 2 cases:  			if (mOffset < TEXTURE_CACHE_ENTRY_SIZE) @@ -480,7 +480,7 @@ bool LLTextureCacheRemoteWorker::doRead()  				// Copy the raw data we've been holding from the header cache into the new sized buffer  				llassert_always(mReadData);  				memcpy(data, mReadData, data_offset); -				delete[] mReadData; +				LLImageBase::deleteMemory(mReadData);  				mReadData = NULL;  			}  			else @@ -506,7 +506,7 @@ bool LLTextureCacheRemoteWorker::doRead()  				llwarns << "LLTextureCacheWorker: "  << mID  						<< " incorrect number of bytes read from body: " << bytes_read  						<< " / " << file_size << llendl; -				delete[] mReadData; +				LLImageBase::deleteMemory(mReadData);  				mReadData = NULL;  				mDataSize = -1; // failed  				done = true; @@ -598,11 +598,11 @@ bool LLTextureCacheRemoteWorker::doWrite()  		{  			// We need to write a full record in the header cache so, if the amount of data is smaller  			// than a record, we need to transfer the data to a buffer padded with 0 and write that -			U8* padBuffer = new U8[TEXTURE_CACHE_ENTRY_SIZE]; +			U8* padBuffer = (U8*)LLImageBase::allocateMemory(TEXTURE_CACHE_ENTRY_SIZE);  			memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE);		// Init with zeros  			memcpy(padBuffer, mWriteData, mDataSize);			// Copy the write buffer  			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool()); -			delete [] padBuffer; +			LLImageBase::deleteMemory(padBuffer);  		}  		else  		{ @@ -698,7 +698,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)  			}  			else  			{ -				delete[] mReadData; +				LLImageBase::deleteMemory(mReadData);  				mReadData = NULL;  			}  		} diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 18c3a3b87d..484d5ea61a 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -817,7 +817,7 @@ void LLTextureFetchWorker::setImagePriority(F32 priority)  void LLTextureFetchWorker::resetFormattedData()  { -	delete[] mBuffer; +	LLImageBase::deleteMemory(mBuffer);  	mBuffer = NULL;  	mBufferSize = 0;  	if (mFormattedImage.notNull()) @@ -888,7 +888,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mSentRequest = UNSENT;  		mDecoded  = FALSE;  		mWritten  = FALSE; -		delete[] mBuffer; +		LLImageBase::deleteMemory(mBuffer);  		mBuffer = NULL;  		mBufferSize = 0;  		mHaveAllData = FALSE; @@ -1284,7 +1284,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			llassert_always(mBufferSize == cur_size + mRequestedSize);  			if(!mBufferSize)//no data received.  			{ -				delete[] mBuffer;  +				LLImageBase::deleteMemory(mBuffer);   				mBuffer = NULL;  				//abort. @@ -1312,7 +1312,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded.  			} -			U8* buffer = new U8[mBufferSize]; +			U8* buffer = (U8*)LLImageBase::allocateMemory(mBufferSize);  			if (cur_size > 0)  			{  				memcpy(buffer, mFormattedImage->getData(), cur_size); @@ -1321,7 +1321,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			// NOTE: setData releases current data and owns new data (buffer)  			mFormattedImage->setData(buffer, mBufferSize);  			// delete temp data -			delete[] mBuffer; // Note: not 'buffer' (assigned in setData()) +			LLImageBase::deleteMemory(mBuffer); // Note: not 'buffer' (assigned in setData())  			mBuffer = NULL;  			mBufferSize = 0;  			mLoadedDiscard = mRequestedDiscard; @@ -1618,7 +1618,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()  			if (buffer_size > cur_size)  			{  				/// We have new data -				U8* buffer = new U8[buffer_size]; +				U8* buffer = (U8*)LLImageBase::allocateMemory(buffer_size);  				S32 offset = 0;  				if (cur_size > 0 && mFirstPacket > 0)  				{ @@ -1670,7 +1670,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  		if (data_size > 0)  		{  			// *TODO: set the formatted image data here directly to avoid the copy -			mBuffer = new U8[data_size]; +			mBuffer = (U8*)LLImageBase::allocateMemory(data_size);  			buffer->readAfter(channels.in(), NULL, mBuffer, data_size);  			mBufferSize += data_size;  			if (data_size < mRequestedSize && mRequestedDiscard == 0) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 41b7c13826..b9d81a76ff 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -203,6 +203,7 @@ void display_stats()  		gMemoryAllocated = LLMemory::getCurrentRSS();  		U32 memory = (U32)(gMemoryAllocated / (1024*1024));  		llinfos << llformat("MEMORY: %d MB", memory) << llendl; +		LLMemory::logMemoryInfo() ;  		gRecentMemoryTime.reset();  	}  } @@ -690,7 +691,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  				glh::matrix4f mod = glh_get_current_modelview();  				glViewport(0,0,512,512);  				LLVOAvatar::updateFreezeCounter() ; -				LLVOAvatar::updateImpostors(); + +				if(!LLPipeline::sMemAllocationThrottled) +				{		 +					LLVOAvatar::updateImpostors(); +				}  				glh_set_current_projection(proj);  				glh_set_current_modelview(mod); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index cd16b15e3e..23d6ca1ae2 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -3080,9 +3080,16 @@ void LLViewerLODTexture::processTextureStats()  	{  		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ;  	} +	else if(LLPipeline::sMemAllocationThrottled)//release memory of large textures by decrease their resolutions. +	{ +		if(scaleDown()) +		{ +			mDesiredDiscardLevel = mCachedRawDiscardLevel ; +		} +	}  } -void LLViewerLODTexture::scaleDown() +bool LLViewerLODTexture::scaleDown()  {  	if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())  	{		 @@ -3093,7 +3100,10 @@ void LLViewerLODTexture::scaleDown()  		{  			tester->setStablizingTime() ;  		} + +		return true ;  	} +	return false ;  }  //----------------------------------------------------------------------------------------------  //end of LLViewerLODTexture diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b5636bbdc7..07b91c2071 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -595,7 +595,7 @@ public:  private:  	void init(bool firstinit) ; -	void scaleDown() ;		 +	bool scaleDown() ;		  private:  	F32 mDiscardVirtualSize;		// Virtual size used to calculate desired discard	 diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0028ced6c8..dfdf429455 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -561,6 +561,17 @@ public:  			addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));  			ypos += y_inc;  		} + +		if (gSavedSettings.getBOOL("DebugShowPrivateMem")) +		{ +			LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ; +			addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024)); +			ypos += y_inc; + +			addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024)); +			ypos += y_inc; +		} +  		// only display these messages if we are actually rendering beacons at this moment  		if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))  		{ @@ -3978,6 +3989,19 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	{  		return FALSE;  	} +	//check if there is enough memory for the snapshot image +	if(LLPipeline::sMemAllocationThrottled) +	{ +		return FALSE ; //snapshot taking is disabled due to memory restriction. +	} +	if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K +	{ +		if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3)) +		{ +			llwarns << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << llendl ; +			return FALSE ; //there is no enough memory for taking this snapshot. +		} +	}  	// PRE SNAPSHOT  	gDisplaySwapBuffers = FALSE; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 13e537fae5..53564ec0f8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -100,6 +100,7 @@  #include "llspatialpartition.h"  #include "llmutelist.h"  #include "lltoolpie.h" +#include "llnotifications.h"  #ifdef _DEBUG @@ -281,6 +282,7 @@ BOOL	LLPipeline::sRenderAttachedLights = TRUE;  BOOL	LLPipeline::sRenderAttachedParticles = TRUE;  BOOL	LLPipeline::sRenderDeferred = FALSE;  BOOL    LLPipeline::sAllowRebuildPriorityGroup = FALSE ; +BOOL    LLPipeline::sMemAllocationThrottled = FALSE;  S32		LLPipeline::sVisibleLightCount = 0;  F32		LLPipeline::sMinRenderSize = 0.f; @@ -513,6 +515,24 @@ void LLPipeline::destroyGL()  static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); +//static +void LLPipeline::throttleNewMemoryAllocation(BOOL disable) +{ +	if(sMemAllocationThrottled != disable) +	{ +		sMemAllocationThrottled = disable ; + +		if(sMemAllocationThrottled) +		{ +			//send out notification +			LLNotification::Params params("LowMemory"); +			LLNotifications::instance().add(params); + +			//release some memory. +		} +	} +} +  void LLPipeline::resizeScreenTexture()  {  	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e99b0d71e3..4a7cc77bde 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -334,6 +334,8 @@ public:  	static void updateRenderDeferred(); +	static void throttleNewMemoryAllocation(BOOL disable); +  private:  	void unloadShaders();  	void addToQuickLookup( LLDrawPool* new_poolp ); @@ -479,8 +481,9 @@ public:  	static BOOL				sRenderAttachedParticles;  	static BOOL				sRenderDeferred;  	static BOOL             sAllowRebuildPriorityGroup; +	static BOOL             sMemAllocationThrottled;  	static S32				sVisibleLightCount; -	static F32				sMinRenderSize; +	static F32				sMinRenderSize;	  	//screen texture  	U32 					mScreenWidth; diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 606ff69599..6963b5bb45 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2000,6 +2000,16 @@                 function="ToggleControl"                 parameter="DebugShowMemory" />              </menu_item_check> +	     <menu_item_check +               label="Show Private Mem Info" +               name="Show Private Mem Info"> +              <menu_item_check.on_check +               function="CheckControl" +               parameter="DebugShowPrivateMem" /> +              <menu_item_check.on_click +               function="ToggleControl" +               parameter="DebugShowPrivateMem" /> +            </menu_item_check>              <menu_item_separator/> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f008042a81..fcb4123b2e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6680,6 +6680,20 @@ Mute everyone?      Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars.    </notification> +   <notification +   icon="alertmodal.tga" +   name="LowMemory" +   type="alertmodal"> +    Your memory pool is low. Some functions of SL are disabled to avoid crash. Please close other applications. Restart SL if this persists. +  </notification> + +  <notification +     icon="alertmodal.tga" +     name="ForceQuitDueToLowMemory" +     type="alertmodal"> +    SL will quit in 30 seconds due to out of memory. +  </notification> +    <notification    name="PopupAttempt"    icon="Popup_Caution"  | 
