diff options
Diffstat (limited to 'indra')
54 files changed, 2064 insertions, 674 deletions
| diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 6775b005f4..e6b838c5b2 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -292,11 +292,16 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)  	++sRawImageCount;  } -LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components) +LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)  	: LLImageBase()  {  	mMemType = LLMemType::MTYPE_IMAGERAW; -	if(allocateDataSize(width, height, components)) + +	if(no_copy) +	{ +		setDataAndSize(data, width, height, components); +	} +	else if(allocateDataSize(width, height, components))  	{  		memcpy(getData(), data, width*height*components);  	} diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 46e6d1a901..99023351c2 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -189,7 +189,7 @@ protected:  public:  	LLImageRaw();  	LLImageRaw(U16 width, U16 height, S8 components); -	LLImageRaw(U8 *data, U16 width, U16 height, S8 components); +	LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);  	// Construct using createFromFile (used by tools)  	//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 452aad25cb..452aad25cb 100644..100755 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index cf88de12b4..0c0a844b73 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1179,7 +1179,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  			llassert(mDims == comp_dims); // Safety check; the caller has ensured this  		}  		bool use_shorts = (mComps[c].get_bit_depth(true) <= 16); -		mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts); +		mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts,0,0);  		if (res.which() == 0) // No DWT levels used  		{  			mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts); @@ -1223,7 +1223,7 @@ separation between consecutive rows in the real buffer. */  	{  		for (c = 0; c < mNumComponents; c++)  		{ -			mEngines[c].pull(mLines[c],true); +			mEngines[c].pull(mLines[c]);  		}  		if ((mNumComponents >= 3) && mUseYCC)  		{ diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 9ab0b9e4a7..fb1f6535ba 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -32,6 +32,7 @@  //  // KDU core header files  // +#define KDU_NO_THREADS  #include "kdu_elementary.h"  #include "kdu_messaging.h"  #include "kdu_params.h" diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 9d923fc367..dbdf88b2d9 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -28,6 +28,7 @@  #define LL_LLKDUMEM_H  // Support classes for reading and writing from memory buffers in KDU +#define KDU_NO_THREADS  #include "kdu_image.h"  #include "kdu_elementary.h"  #include "kdu_messaging.h" diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index beee99a522..b675153b2e 100644..100755 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -127,7 +127,6 @@ kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; }  void kdu_resolution::get_dims(kdu_dims& ) { }  int kdu_resolution::which() { return 0; }  int kdu_resolution::get_valid_band_indices(int &) { return 1; } -kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }  kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { }  kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }  kdu_params::~kdu_params() { } @@ -153,7 +152,6 @@ void kdu_codestream::destroy() { }  void kdu_codestream::collect_timing_stats(int ) { }  void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { }  void kdu_codestream::get_valid_tiles(kdu_dims& ) { } -void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { }  void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { }  void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { }  void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { } @@ -175,7 +173,7 @@ kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return N  bool kdu_codestream_comment::put_text(const char*) { return false; }  void kdu_customize_warnings(kdu_message*) { }  void kdu_customize_errors(kdu_message*) { } -void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { } +  kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, bool, kdu_roi_image*, bool, int, kdu_thread_env*, kdu_thread_queue*, bool ) { kdu_long a = 0; return a; }  siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { }  void siz_params::finalize(bool ) { } @@ -184,6 +182,21 @@ int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0;  bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; }  bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; } +#ifdef LL_LINUX +// Linux use the old pre KDU v7.0.0 +// *TODO: Supress this legacy stubbs once Linux migrates to v7.0.0 +kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { } +void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { } +void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { } +#else +kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { } +void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { } +void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); +void (*kdu_convert_ycc_to_rgb_irrev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); +void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int); +void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int); +#endif +  // -------------------------------------------------------------------------------------------  // TUT  // ------------------------------------------------------------------------------------------- diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 97f2792686..fbc3cc6de2 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -87,6 +87,9 @@ namespace LLAvatarNameCache      /// Time when unrefreshed cached names were checked last      static F64 sLastExpireCheck; +	/// Time-to-live for a temp cache entry. +	const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; +  	//-----------------------------------------------------------------------  	// Internal methods  	//----------------------------------------------------------------------- @@ -274,7 +277,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)      {          // there is no existing cache entry, so make a temporary name from legacy          LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent " -                                << agent_id << LL_ENDL; +								<< agent_id << LL_ENDL;          gCacheName->get(agent_id, false,  // legacy compatibility                          boost::bind(&LLAvatarNameCache::legacyNameCallback,                                      _1, _2, _3)); @@ -287,13 +290,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)          // Clear this agent from the pending list          LLAvatarNameCache::sPendingQueue.erase(agent_id); -        const LLAvatarName& av_name = existing->second; +        LLAvatarName& av_name = existing->second;          LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "                                   << agent_id                                    << "user '" << av_name.mUsername << "' "                                   << "display '" << av_name.mDisplayName << "' "                                   << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"                                   << LL_ENDL; +		av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.      }  } @@ -402,10 +406,12 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,  							 << LL_ENDL;  	buildLegacyName(full_name, &av_name); -	// Don't add to cache, the data already exists in the legacy name system -	// cache and we don't want or need duplicate storage, because keeping the -	// two copies in sync is complex. -	processName(agent_id, av_name, false); +	// Add to cache, because if we don't we'll keep rerequesting the +	// same record forever.  buildLegacyName should always guarantee +	// that these records expire reasonably soon +	// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due +	// to something temporary we will eventually request and get the right data. +	processName(agent_id, av_name, true);  }  void LLAvatarNameCache::requestNamesViaLegacy() @@ -583,7 +589,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,  	av_name->mDisplayName = full_name;  	av_name->mIsDisplayNameDefault = true;  	av_name->mIsTemporaryName = true; -	av_name->mExpires = F64_MAX; // not used because these are not cached +	av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;  	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "  							 << full_name  							 << LL_ENDL; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 5ea9b58300..b4ac984d57 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -935,8 +935,8 @@ bool LLCurlThread::CurlRequest::processRequest()  		if(!completed)  		{ -		setPriority(LLQueuedThread::PRIORITY_LOW) ; -	} +			setPriority(LLQueuedThread::PRIORITY_LOW) ; +		}  	}  	return completed ; @@ -946,7 +946,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)  {  	if(mMulti->isDead())  	{ -	mCurlThread->deleteMulti(mMulti) ; +		mCurlThread->deleteMulti(mMulti) ;  	}  	else  	{ @@ -990,6 +990,7 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)  		return ;  	} +  	multi->markDead() ;  } @@ -1095,7 +1096,9 @@ void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)  {  	getByteRange(url, headers_t(), 0, -1, responder);  } -	 + +// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or +// the remainder of the file if not.  bool LLCurlRequest::getByteRange(const std::string& url,  								 const headers_t& headers,  								 S32 offset, S32 length, @@ -1113,6 +1116,11 @@ bool LLCurlRequest::getByteRange(const std::string& url,  		std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1);  		easy->slist_append(range.c_str());  	} +	else if (offset > 0) +	{ +		std::string range = llformat("Range: bytes=%d-", offset); +		easy->slist_append(range.c_str()); +	}  	easy->setHeaders();  	bool res = addEasy(easy);  	return res; @@ -1238,6 +1246,208 @@ S32 LLCurlRequest::getQueued()  	return queued;  } +LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) :  +	LLCurlRequest(),  +	mConcurrency(concurrency), +	mInQueue(0), +	mMutex(NULL), +	mHandleCounter(1), +	mTotalIssuedRequests(0), +	mTotalReceivedBits(0) +{ +	mGlobalTimer.reset(); +} + +LLCurlTextureRequest::~LLCurlTextureRequest() +{ +	mRequestMap.clear(); + +	for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter) +	{ +		delete *iter; +	} +	mCachedRequests.clear(); +} + +//return 0: success +// > 0: cached handle +U32 LLCurlTextureRequest::getByteRange(const std::string& url, +								 const headers_t& headers, +								 S32 offset, S32 length, U32 pri, +								 LLCurl::ResponderPtr responder, F32 delay_time) +{ +	U32 ret_val = 0; +	bool success = false;	 + +	if(mInQueue < mConcurrency && delay_time < 0.f) +	{ +		success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);		 +	} + +	LLMutexLock lock(&mMutex); + +	if(success) +	{ +		mInQueue++; +		mTotalIssuedRequests++; +	} +	else +	{ +		request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder); +		if(delay_time > 0.f) +		{ +			request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time; +		} + +		mCachedRequests.insert(request); +		mRequestMap[mHandleCounter] = request; +		ret_val = mHandleCounter; +		mHandleCounter++; + +		if(!mHandleCounter) +		{ +			mHandleCounter = 1; +		} +	} + +	return ret_val; +} + +void LLCurlTextureRequest::completeRequest(S32 received_bytes) +{ +	LLMutexLock lock(&mMutex); + +	llassert_always(mInQueue > 0); + +	mInQueue--; +	mTotalReceivedBits += received_bytes * 8; +} + +void LLCurlTextureRequest::nextRequests() +{ +	if(mCachedRequests.empty() || mInQueue >= mConcurrency) +	{ +		return; +	} + +	F32 cur_time = mGlobalTimer.getElapsedTimeF32(); + +	req_queue_t::iterator iter;	 +	{ +		LLMutexLock lock(&mMutex); +		iter = mCachedRequests.begin(); +	} +	while(1) +	{ +		request_t* request = *iter; +		if(request->mStartTime < cur_time) +		{ +			if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder)) +			{ +				break; +			} + +			LLMutexLock lock(&mMutex); +			++iter; +			mInQueue++; +			mTotalIssuedRequests++; +			mCachedRequests.erase(request); +			mRequestMap.erase(request->mHandle); +			delete request; + +			if(iter == mCachedRequests.end() || mInQueue >= mConcurrency) +			{ +				break; +			} +		} +		else +		{ +			LLMutexLock lock(&mMutex); +			++iter; +			if(iter == mCachedRequests.end() || mInQueue >= mConcurrency) +			{ +				break; +			} +		} +	} + +	return; +} + +void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri) +{ +	if(!handle) +	{ +		return; +	} + +	LLMutexLock lock(&mMutex); + +	std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle); +	if(iter != mRequestMap.end()) +	{ +		request_t* req = iter->second; +		 +		if(req->mPriority != pri) +		{ +			mCachedRequests.erase(req); +			req->mPriority = pri; +			mCachedRequests.insert(req); +		} +	} +} + +void LLCurlTextureRequest::removeRequest(U32 handle) +{ +	if(!handle) +	{ +		return; +	} + +	LLMutexLock lock(&mMutex); + +	std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle); +	if(iter != mRequestMap.end()) +	{ +		request_t* req = iter->second; +		mRequestMap.erase(iter); +		mCachedRequests.erase(req); +		delete req; +	} +} + +bool LLCurlTextureRequest::isWaiting(U32 handle) +{ +	if(!handle) +	{ +		return false; +	} + +	LLMutexLock lock(&mMutex); +	return mRequestMap.find(handle) != mRequestMap.end(); +} + +U32 LLCurlTextureRequest::getTotalReceivedBits() +{ +	LLMutexLock lock(&mMutex); + +	U32 bits = mTotalReceivedBits; +	mTotalReceivedBits = 0; +	return bits; +} + +U32 LLCurlTextureRequest::getTotalIssuedRequests() +{ +	LLMutexLock lock(&mMutex); +	return mTotalIssuedRequests; +} + +S32 LLCurlTextureRequest::getNumRequests() +{ +	LLMutexLock lock(&mMutex); +	return mInQueue; +} +  ////////////////////////////////////////////////////////////////////////////  // For generating one easy request  // associated with a single multi request diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index d6a7714d4c..20ebd86c06 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -414,6 +414,71 @@ private:  	BOOL mProcessing;  }; +//for texture fetch only +class LLCurlTextureRequest : public LLCurlRequest +{ +public: +	LLCurlTextureRequest(S32 concurrency); +	~LLCurlTextureRequest(); + +	U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f); +	void nextRequests(); +	void completeRequest(S32 received_bytes); + +	void updatePriority(U32 handle, U32 pri); +	void removeRequest(U32 handle); + +	U32 getTotalReceivedBits(); +	U32 getTotalIssuedRequests(); +	S32 getNumRequests(); +	bool isWaiting(U32 handle); +	 +private: +	LLMutex mMutex; +	S32 mConcurrency; +	S32 mInQueue; //request currently in queue. +	U32 mHandleCounter; +	U32 mTotalIssuedRequests; +	U32 mTotalReceivedBits; + +	typedef struct _request_t +	{ +		_request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) : +				mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f) +				{} + +		U32  mHandle; +		std::string mUrl; +		LLCurlRequest::headers_t mHeaders; +		S32 mOffset; +		S32 mLength; +		LLCurl::ResponderPtr mResponder; +		U32 mPriority; +		F32 mStartTime; //start time to issue this request +	} request_t; + +	struct request_compare +	{ +		bool operator()(const request_t* lhs, const request_t* rhs) const +		{ +			if(lhs->mPriority != rhs->mPriority) +			{ +				return lhs->mPriority > rhs->mPriority; // higher priority in front of queue (set) +			} +			else +			{ +				return (U32)lhs < (U32)rhs; +			} +		} +	}; + +	typedef std::set<request_t*, request_compare> req_queue_t; +	req_queue_t mCachedRequests; +	std::map<S32, request_t*> mRequestMap; + +	LLFrameTimer mGlobalTimer; +}; +  class LLCurlEasyRequest  {  public: diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 30532247ac..6dee192783 100644..100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -149,7 +149,8 @@ bool LLPrimitive::cleanupVolumeManager()  LLPrimitive::LLPrimitive()  :	mTextureList(),  	mNumTEs(0), -	mMiscFlags(0) +	mMiscFlags(0), +	mNumBumpmapTEs(0)  {  	mPrimitiveCode = 0; @@ -237,7 +238,10 @@ void  LLPrimitive::setAllTETextures(const LLUUID &tex_id)  //===============================================================  void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)  { -	mTextureList.copyTexture(index, te); +	if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) +	{ +		mNumBumpmapTEs++; +	}  }  S32  LLPrimitive::setTETexture(const U8 index, const LLUUID &id) @@ -316,6 +320,7 @@ S32  LLPrimitive::setTERotation(const U8 index, const F32 r)  //===============================================================  S32  LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)  { +	updateNumBumpmap(index, bump);  	return mTextureList.setBumpShinyFullbright(index, bump);  } @@ -326,11 +331,13 @@ S32  LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media)  S32  LLPrimitive::setTEBumpmap(const U8 index, const U8 bump)  { +	updateNumBumpmap(index, bump);  	return mTextureList.setBumpMap(index, bump);  }  S32  LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny)  { +	updateNumBumpmap(index, bump_shiny);  	return mTextureList.setBumpShiny(index, bump_shiny);  } @@ -1445,6 +1452,26 @@ void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)  	mTextureList.take(other_list);  } +void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump) +{ +	LLTextureEntry* te = getTE(index); +	if(!te) +	{ +		return; +	} + +	U8 old_bump = te->getBumpmap();	 +	if(old_bump > 0) +	{ +		mNumBumpmapTEs--; +	} +	if((bump & TEM_BUMP_MASK) > 0) +	{ +		mNumBumpmapTEs++; +	} + +	return; +}  //============================================================================  // Moved from llselectmgr.cpp diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 998016f8f6..8dcaa8c740 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -421,7 +421,8 @@ public:  	inline BOOL	isAvatar() const;  	inline BOOL	isSittingAvatar() const;  	inline BOOL	isSittingAvatarOnGround() const; - +	inline bool hasBumpmap() const  { return mNumBumpmapTEs > 0;} +	  	void setFlags(U32 flags) { mMiscFlags = flags; }  	void addFlags(U32 flags) { mMiscFlags |= flags; }  	void removeFlags(U32 flags) { mMiscFlags &= ~flags; } @@ -435,6 +436,9 @@ public:  	inline static BOOL isPrimitive(const LLPCode pcode);  	inline static BOOL isApp(const LLPCode pcode); +private: +	void updateNumBumpmap(const U8 index, const U8 bump); +  protected:  	LLPCode				mPrimitiveCode;		// Primitive code  	LLVector3			mVelocity;			// how fast are we moving? @@ -444,6 +448,7 @@ protected:  	LLPrimTextureList	mTextureList;		// list of texture GUIDs, scales, offsets  	U8					mMaterial;			// Material code  	U8					mNumTEs;			// # of faces on the primitve	 +	U8                  mNumBumpmapTEs;     // number of bumpmap TEs.  	U32 				mMiscFlags;			// home for misc bools  public: diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 659d3ca409..f999940176 100644..100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -476,7 +476,7 @@ bool LLImageGL::checkSize(S32 width, S32 height)  	return check_power_of_two(width) && check_power_of_two(height);  } -void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) +void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level)  {  	if (width != mWidth || height != mHeight || ncomponents != mComponents)  	{ @@ -509,6 +509,11 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)  				width >>= 1;  				height >>= 1;  			} + +			if(discard_level > 0) +			{ +				mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level); +			}  		}  		else  		{ @@ -858,14 +863,13 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)  		llassert(mCurrentDiscardLevel >= 0);  		discard_level = mCurrentDiscardLevel;  	} -	discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - +	  	// Actual image width/height = raw image width/height * 2^discard_level  	S32 w = raw_image->getWidth() << discard_level;  	S32 h = raw_image->getHeight() << discard_level;  	// setSize may call destroyGLTexture if the size does not match -	setSize(w, h, raw_image->getComponents()); +	setSize(w, h, raw_image->getComponents(), discard_level);  	if( !mHasExplicitFormat )  	{ @@ -1262,8 +1266,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S  		llassert(mCurrentDiscardLevel >= 0);  		discard_level = mCurrentDiscardLevel;  	} -	discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - +	  	// Actual image width/height = raw image width/height * 2^discard_level  	S32 raw_w = imageraw->getWidth() ;  	S32 raw_h = imageraw->getHeight() ; @@ -1271,7 +1274,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S  	S32 h = raw_h << discard_level;  	// setSize may call destroyGLTexture if the size does not match -	setSize(w, h, imageraw->getComponents()); +	setSize(w, h, imageraw->getComponents(), discard_level);  	if( !mHasExplicitFormat )  	{ diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index e118c28c1b..cf3c484c79 100644..100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -100,7 +100,7 @@ protected:  public:  	virtual void dump();	// debugging info to llinfos -	void setSize(S32 width, S32 height, S32 ncomponents); +	void setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);  	void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}  	void setAllowCompression(bool allow) { mAllowCompression = allow; } diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index e08ccb0b78..e08ccb0b78 100644..100755 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 65170a2140..65170a2140 100644..100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 64122bbb6c..64122bbb6c 100644..100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5e50bd6e01..47b1222f3c 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3270,6 +3270,17 @@          <key>Value</key>          <integer>0</integer>      </map> +    <key>FastCacheFetchEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enable texture fast cache fetching if set</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <string>1</string> +    </map>  	<key>FeatureManagerHTTPTable</key>        <map>          <key>Comment</key> @@ -10789,6 +10800,83 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TextureFetchSource</key> +    <map> +      <key>Comment</key> +      <string>Debug use: Source to fetch textures</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>TextureFetchUpdateHighPriority</key> +    <map> +      <key>Comment</key> +      <string>Number of high priority textures to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>32</integer> +    </map> +    <key>TextureFetchUpdateMaxMediumPriority</key> +    <map> +      <key>Comment</key> +      <string>Maximum number of medium priority textures to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>256</integer> +    </map> +    <key>TextureFetchUpdateMinMediumPriority</key> +    <map> +      <key>Comment</key> +      <string>Minimum number of medium priority textures to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>32</integer> +    </map> +    <key>TextureFetchUpdatePriorityThreshold</key> +    <map> +      <key>Comment</key> +      <string>Threshold under which textures will be considered too low priority and skipped for update</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>0.0</integer> +    </map> +    <key>TextureFetchUpdateSkipLowPriority</key> +    <map> +      <key>Comment</key> +      <string>Flag indicating if we want to skip textures with too low of a priority</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>TextureFetchUpdatePriorities</key> +    <map> +      <key>Comment</key> +      <string>Number of priority texture to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>32</integer> +    </map>      <key>TextureLoadFullRes</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e441f21f90..e441f21f90 100644..100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 5932be21c6..5932be21c6 100644..100755 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6d67e098a6..6d67e098a6 100644..100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index efa24796e5..6a4f6e4a02 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4338,6 +4338,10 @@ void LLAppViewer::idle()      {  		return;      } +	if (gTeleportDisplay) +    { +		return; +    }  	gViewerWindow->updateUI(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 373b1930f5..2060d13ca8 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2169,6 +2169,12 @@ BOOL LLFace::hasMedia() const  const F32 LEAST_IMPORTANCE = 0.05f ;  const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; +void LLFace::resetVirtualSize() +{ +	setVirtualSize(0.f); +	mImportanceToCamera = 0.f; +} +  F32 LLFace::getTextureVirtualSize()  {  	F32 radius; @@ -2234,8 +2240,17 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)  	LLVector4a t;  	t.load3(camera->getOrigin().mV);  	lookAt.setSub(center, t); +	  	F32 dist = lookAt.getLength3().getF32(); -	dist = llmax(dist-size.getLength3().getF32(), 0.f); +	dist = llmax(dist-size.getLength3().getF32(), 0.001f); +	//ramp down distance for nearby objects +	if (dist < 16.f) +	{ +		dist /= 16.f; +		dist *= dist; +		dist *= 16.f; +	} +  	lookAt.normalize3fast() ;	  	//get area of circle around node diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 76ea5c853a..3d8d29ce29 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -206,6 +206,7 @@ public:  	F32         getTextureVirtualSize() ;  	F32         getImportanceToCamera()const {return mImportanceToCamera ;} +	void        resetVirtualSize();  	void        setHasMedia(bool has_media)  { mHasMedia = has_media ;}  	BOOL        hasMedia() const ; diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp index 2b34b72055..9157389187 100644 --- a/indra/newview/llfloatertexturefetchdebugger.cpp +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -59,12 +59,15 @@ LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)  	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));  	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this));  }  //----------------------------------------------  BOOL LLFloaterTextureFetchDebugger::postBuild(void)   {	  	mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); +	mStartStatus = (S32)LLTextureFetchDebugger::IDLE;  	//set states for buttons  	mButtonStateMap["start_btn"] = true; @@ -76,8 +79,10 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)  	mButtonStateMap["decode_btn"] = false;  	mButtonStateMap["gl_btn"] = false; -	mButtonStateMap["refetchviscache_btn"] = true; -	mButtonStateMap["refetchvishttp_btn"] = true; +	mButtonStateMap["refetchviscache_btn"] = false; +	mButtonStateMap["refetchvishttp_btn"] = false; +	mButtonStateMap["refetchallcache_btn"] = false; +	mButtonStateMap["refetchallhttp_btn"] = false;  	updateButtons(); @@ -89,7 +94,7 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)  LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()  {  	//stop everything -	mDebugger->stopDebug(); +	mDebugger->setStopDebug();  }  void LLFloaterTextureFetchDebugger::updateButtons() @@ -118,47 +123,81 @@ void LLFloaterTextureFetchDebugger::disableButtons()  	childDisable("gl_btn");  	childDisable("refetchviscache_btn");  	childDisable("refetchvishttp_btn"); +	childDisable("refetchallcache_btn"); +	childDisable("refetchallhttp_btn"); +} +void LLFloaterTextureFetchDebugger::setStartStatus(S32 status) +{ +	llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ; +	mStartStatus = status; +} +	 +bool LLFloaterTextureFetchDebugger::idleStart() +{ +	if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE) +	{ +		mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus); +		mStartStatus = (S32)LLTextureFetchDebugger::IDLE; +		return true; +	} + +	return false;  }  void LLFloaterTextureFetchDebugger::idle()  {	 -	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); -	 -	if(mDebugger->update()) +	if(idleStart()) +	{ +		return; +	} + +	const F32 max_time = 0.005f; //5ms +	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();	 +	if(mDebugger->update(max_time))  	{  		switch(state)  		{  		case LLTextureFetchDebugger::IDLE:  			break; -		case LLTextureFetchDebugger::READ_CACHE: -			mButtonStateMap["cachewrite_btn"] = true; -			mButtonStateMap["decode_btn"] = true; -			updateButtons(); +		case LLTextureFetchDebugger::START_DEBUG: +			mButtonStateMap["cacheread_btn"] = true; +			mButtonStateMap["http_btn"] = true; +			mButtonStateMap["refetchviscache_btn"] = true; +			mButtonStateMap["refetchvishttp_btn"] = true; +			mButtonStateMap["refetchallcache_btn"] = true; +			mButtonStateMap["refetchallhttp_btn"] = true;  			break; -		case LLTextureFetchDebugger::WRITE_CACHE: -			updateButtons(); +		case LLTextureFetchDebugger::READ_CACHE:			 +			mButtonStateMap["decode_btn"] = true;			 +			break; +		case LLTextureFetchDebugger::WRITE_CACHE:			  			break;  		case LLTextureFetchDebugger::DECODING: -			mButtonStateMap["gl_btn"] = true; -			updateButtons(); +			mButtonStateMap["gl_btn"] = true;			  			break;  		case LLTextureFetchDebugger::HTTP_FETCHING:  			mButtonStateMap["cacheread_btn"] = true;  			mButtonStateMap["cachewrite_btn"] = true; -			mButtonStateMap["decode_btn"] = true; -			updateButtons(); +			mButtonStateMap["decode_btn"] = true;			  			break; -		case LLTextureFetchDebugger::GL_TEX: -			updateButtons(); +		case LLTextureFetchDebugger::GL_TEX:			  			break; -		case LLTextureFetchDebugger::REFETCH_VIS_CACHE: -			updateButtons(); -		case LLTextureFetchDebugger::REFETCH_VIS_HTTP: -			updateButtons(); +		case LLTextureFetchDebugger::REFETCH_VIS_CACHE:			 +			break; +		case LLTextureFetchDebugger::REFETCH_VIS_HTTP:			 +			break; +		case LLTextureFetchDebugger::REFETCH_ALL_CACHE:			 +			break; +		case LLTextureFetchDebugger::REFETCH_ALL_HTTP:  			break;  		default:  			break;  		} + +		if(state != LLTextureFetchDebugger::IDLE) +		{ +			updateButtons(); +		}  	}  } @@ -172,11 +211,10 @@ void LLFloaterTextureFetchDebugger::onClickStart()  {  	disableButtons(); -	mDebugger->startDebug(); +	setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);	  	mButtonStateMap["start_btn"] = false; -	mButtonStateMap["cacheread_btn"] = true; -	mButtonStateMap["http_btn"] = true; +  	updateButtons();  } @@ -185,7 +223,9 @@ void LLFloaterTextureFetchDebugger::onClickClose()  	setVisible(FALSE);  	//stop everything -	mDebugger->stopDebug(); +	mDebugger->setStopDebug(); + +	delete this;  }  void LLFloaterTextureFetchDebugger::onClickClear() @@ -203,7 +243,7 @@ void LLFloaterTextureFetchDebugger::onClickClear()  	updateButtons();  	//stop everything -	mDebugger->stopDebug(); +	mDebugger->setStopDebug();  	mDebugger->clearHistory();  } @@ -211,49 +251,63 @@ void LLFloaterTextureFetchDebugger::onClickCacheRead()  {  	disableButtons(); -	mDebugger->debugCacheRead(); +	setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);  }  void LLFloaterTextureFetchDebugger::onClickCacheWrite()  {  	disableButtons(); -	mDebugger->debugCacheWrite(); +	setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);  }  void LLFloaterTextureFetchDebugger::onClickHTTPLoad()  {  	disableButtons(); -	mDebugger->debugHTTP(); +	setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);  }  void LLFloaterTextureFetchDebugger::onClickDecode()  {  	disableButtons(); -	mDebugger->debugDecoder(); +	setStartStatus((S32)LLTextureFetchDebugger::DECODING);  }  void LLFloaterTextureFetchDebugger::onClickGLTexture()  {  	disableButtons(); -	mDebugger->debugGLTextureCreation(); +	setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);	  }  void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()  {  	disableButtons(); -	mDebugger->debugRefetchVisibleFromCache(); +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);  }  void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()  {  	disableButtons(); -	mDebugger->debugRefetchVisibleFromHTTP(); +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);	 +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllCache() +{ +	disableButtons(); + +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP() +{ +	disableButtons(); + +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);	  }  void LLFloaterTextureFetchDebugger::draw() @@ -368,8 +422,22 @@ void LLFloaterTextureFetchDebugger::draw()  	else  	{  		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); +	} + +	//total time on refetching all textures from cache +	if(mDebugger->getRefetchAllCacheTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime())); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));  	}  	//total time on refetching visible textures from http @@ -382,8 +450,22 @@ void LLFloaterTextureFetchDebugger::draw()  	else  	{  		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); +	} + +	//total time on refetching all textures from http +	if(mDebugger->getRefetchAllHTTPTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime())); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));  	}  	LLFloater::draw(); diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h index 33012c6a3d..096ad88e07 100644 --- a/indra/newview/llfloatertexturefetchdebugger.h +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -53,6 +53,8 @@ public:  	void onClickRefetchVisCache();  	void onClickRefetchVisHTTP(); +	void onClickRefetchAllCache(); +	void onClickRefetchAllHTTP();  public:  	void idle() ; @@ -63,9 +65,12 @@ private:  	void updateButtons();  	void disableButtons(); +	void setStartStatus(S32 status); +	bool idleStart();  private:	  	LLTextureFetchDebugger* mDebugger;  	std::map<std::string, bool> mButtonStateMap; +	S32 mStartStatus;  };  #endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 6e23d7c701..6e23d7c701 100644..100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ee7a234bbe..56f27c158d 100644..100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -361,6 +361,15 @@ bool idle_startup()  	if ( STATE_FIRST == LLStartUp::getStartupState() )  	{ +		static bool first_call = true; +		if (first_call) +		{ +			// Other phases get handled when startup state changes, +			// need to capture the initial state as well. +			LLStartUp::getPhases().startPhase(LLStartUp::getStartupStateString()); +			first_call = false; +		} +  		gViewerWindow->showCursor();   		gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT); @@ -2708,9 +2717,10 @@ void LLStartUp::setStartupState( EStartupState state )  		getStartupStateString() << " to " <<    		startupStateToString(state) << LL_ENDL; -	sPhases->stopPhase(getStartupStateString()); +	getPhases().stopPhase(getStartupStateString());  	gStartupState = state; -	sPhases->startPhase(getStartupStateString()); +	getPhases().startPhase(getStartupStateString()); +  	postStartupState();  } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 3754aaf966..3754aaf966 100644..100755 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 8632890bbb..a61e2d5c86 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -50,6 +50,8 @@  const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024;  const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit  const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) +const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level +const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;  class LLTextureCacheWorker : public LLWorkerClass  { @@ -283,9 +285,12 @@ public:  	LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,  						 U8* data, S32 datasize, S32 offset,  						 S32 imagesize, // for writes +						 LLPointer<LLImageRaw> raw, S32 discardlevel,  						 LLTextureCache::Responder* responder)   			: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), -			mState(INIT) +			mState(INIT), +			mRawImage(raw), +			mRawDiscardLevel(discardlevel)  	{  	} @@ -303,6 +308,8 @@ private:  	};  	e_state mState; +	LLPointer<LLImageRaw> mRawImage; +	S32 mRawDiscardLevel;  }; @@ -559,6 +566,11 @@ bool LLTextureCacheRemoteWorker::doWrite()  		if(idx < 0)  		{  			idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry. +			if(idx >= 0) +			{ +				//write to the fast cache. +				llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); +			}  		}  		else  		{ @@ -658,6 +670,7 @@ bool LLTextureCacheRemoteWorker::doWrite()  		// Nothing else to do at that point...  		done = true;  	} +	mRawImage = NULL;  	// Clean up and exit  	return done; @@ -744,10 +757,14 @@ LLTextureCache::LLTextureCache(bool threaded)  	  mWorkersMutex(NULL),  	  mHeaderMutex(NULL),  	  mListMutex(NULL), +	  mFastCacheMutex(NULL),  	  mHeaderAPRFile(NULL),  	  mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.  	  mTexturesSizeTotal(0), -	  mDoPurge(FALSE) +	  mDoPurge(FALSE), +	  mFastCachep(NULL), +	  mFastCachePoolp(NULL), +	  mFastCachePadBuffer(NULL)  {  } @@ -755,6 +772,9 @@ LLTextureCache::~LLTextureCache()  {  	clearDeleteList() ;  	writeUpdatedEntries() ; +	delete mFastCachep; +	delete mFastCachePoolp; +	FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer);  }  ////////////////////////////////////////////////////////////////////////////// @@ -879,15 +899,15 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)  //////////////////////////////////////////////////////////////////////////////  //static -const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB -F32 LLTextureCache::sHeaderCacheVersion = 1.4f; -U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; +F32 LLTextureCache::sHeaderCacheVersion = 1.7f; +U32 LLTextureCache::sCacheMaxEntries = 1024 * 1024; //~1 million textures.  S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit  const char* entries_filename = "texture.entries";  const char* cache_filename = "texture.cache";  const char* old_textures_dirname = "textures";  //change the location of the texture cache to prevent from being deleted by old version viewers.  const char* textures_dirname = "texturecache"; +const char* fast_cache_filename = "FastCache.cache";  void LLTextureCache::setDirNames(ELLPath location)  { @@ -896,6 +916,7 @@ void LLTextureCache::setDirNames(ELLPath location)  	mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, entries_filename);  	mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename);  	mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname); +	mFastCacheFileName =  gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename);  }  void LLTextureCache::purgeCache(ELLPath location) @@ -938,8 +959,8 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache  {  	llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. -	S64 header_size = (max_size * 2) / 10; -	S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; +	S64 header_size = (max_size / 100) * 36; //0.36 * max_size +	S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);  	sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries));  	header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE;  	max_size -= header_size; @@ -981,6 +1002,7 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache  	purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it  	llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. +	openFastCache(true);  	return max_size; // unused cache space  } @@ -1751,7 +1773,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri  	LLMutexLock lock(&mWorkersMutex);  	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,  																  NULL, size, offset, -																  0, responder); +																  0, NULL, 0, responder);  	handle_t handle = worker->read();  	mReaders[handle] = worker;  	return handle; @@ -1789,6 +1811,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)  LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,  													  U8* data, S32 datasize, S32 imagesize, +													  LLPointer<LLImageRaw> rawimage, S32 discardlevel,  													  WriteResponder* responder)  {  	if (mReadOnly) @@ -1807,12 +1830,159 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio  	LLMutexLock lock(&mWorkersMutex);  	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,  																  data, datasize, 0, -																  imagesize, responder); +																  imagesize, rawimage, discardlevel, responder);  	handle_t handle = worker->write();  	mWriters[handle] = worker;  	return handle;  } +//called in the main thread +LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& discardlevel) +{ +	U32 offset; +	{ +		LLMutexLock lock(&mHeaderMutex); +		id_map_t::const_iterator iter = mHeaderIDMap.find(id); +		if(iter == mHeaderIDMap.end()) +		{ +			return NULL; //not in the cache +		} + +		offset = iter->second; +	} +	offset *= TEXTURE_FAST_CACHE_ENTRY_SIZE; + +	U8* data; +	S32 head[4]; +	{ +		LLMutexLock lock(&mFastCacheMutex); + +		openFastCache(); + +		mFastCachep->seek(APR_SET, offset);		 +	 +		llassert_always(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) == TEXTURE_FAST_CACHE_ENTRY_OVERHEAD); +		 +		S32 image_size = head[0] * head[1] * head[2]; +		if(!image_size) //invalid +		{ +			closeFastCache(); +			return NULL; +		} +		discardlevel = head[3]; +		 +		data =  (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size); +		llassert_always(mFastCachep->read(data, image_size) == image_size); +		closeFastCache(); +	} +	LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true); + +	return raw; +} + +//return the fast cache location +bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel) +{ +	//rescale image if needed +	S32 w, h, c; +	w = raw->getWidth(); +	h = raw->getHeight(); +	c = raw->getComponents(); +	S32 i = 0 ; +	 +	while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) +	{ +		++i ; +	} +		 +	if(i) +	{ +		w >>= i; +		h >>= i; +		if(w * h *c > 0) //valid +		{ +			LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents()); +			newraw->scale(w, h) ; +			raw = newraw; + +			discardlevel += i ; +		} +	} +	 +	//copy data +	memcpy(mFastCachePadBuffer, &w, sizeof(S32)); +	memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32)); +	memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32)); +	memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32)); +	if(w * h * c > 0) //valid +	{ +		memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c); +	} +	S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE; + +	{ +		LLMutexLock lock(&mFastCacheMutex); + +		openFastCache(); + +		mFastCachep->seek(APR_SET, offset);	 +		llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE); + +		closeFastCache(true); +	} + +	return true; +} + +void LLTextureCache::openFastCache(bool first_time) +{ +	if(!mFastCachep) +	{ +		if(first_time) +		{ +			if(!mFastCachePadBuffer) +			{ +				mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE); +			} +			mFastCachePoolp = new LLVolatileAPRPool(); +			if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp)) +			{ +				mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;				 +			} +			else +			{ +				mFastCachep = new LLAPRFile(mFastCacheFileName, APR_CREATE|APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; +			} +		} +		else +		{ +			mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; +		} + +		mFastCacheTimer.reset(); +	} +	return; +} +	 +void LLTextureCache::closeFastCache(bool forced) +{	 +	static const F32 timeout = 10.f ; //seconds + +	if(!mFastCachep) +	{ +		return ; +	} + +	if(!forced && mFastCacheTimer.getElapsedTimeF32() < timeout) +	{ +		return ; +	} + +	delete mFastCachep; +	mFastCachep = NULL; +	return; +} +	  bool LLTextureCache::writeComplete(handle_t handle, bool abort)  {  	lockWorkers(); diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index dd0cc9b4bd..e3fc957fd2 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -36,6 +36,7 @@  class LLImageFormatted;  class LLTextureCacheWorker; +class LLImageRaw;  class LLTextureCache : public LLWorkerThread  { @@ -113,8 +114,9 @@ public:  	handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,  						   ReadResponder* responder);  	bool readComplete(handle_t handle, bool abort); -	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, +	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,  						  WriteResponder* responder); +	LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);  	bool writeComplete(handle_t handle, bool abort = false);  	void prioritizeWrite(handle_t handle); @@ -171,12 +173,18 @@ private:  	void lockHeaders() { mHeaderMutex.lock(); }  	void unlockHeaders() { mHeaderMutex.unlock(); } +	void openFastCache(bool first_time = false); +	void closeFastCache(bool forced = false); +	bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel);	 +  private:  	// Internal  	LLMutex mWorkersMutex;  	LLMutex mHeaderMutex;  	LLMutex mListMutex; +	LLMutex mFastCacheMutex;  	LLAPRFile* mHeaderAPRFile; +	LLVolatileAPRPool* mFastCachePoolp;  	typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;  	handle_map_t mReaders; @@ -193,12 +201,17 @@ private:  	// HEADERS (Include first mip)  	std::string mHeaderEntriesFileName;  	std::string mHeaderDataFileName; +	std::string mFastCacheFileName;  	EntriesInfo mHeaderEntriesInfo;  	std::set<S32> mFreeList; // deleted entries  	std::set<LLUUID> mLRU; -	typedef std::map<LLUUID,S32> id_map_t; +	typedef std::map<LLUUID, S32> id_map_t;  	id_map_t mHeaderIDMap; +	LLAPRFile*   mFastCachep; +	LLFrameTimer mFastCacheTimer; +	U8*          mFastCachePadBuffer; +  	// BODIES (TEXTURES minus headers)  	std::string mTexturesDirName;  	typedef std::map<LLUUID,S32> size_map_t; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 7e6dfbc9d9..b148b8b76d 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -151,7 +151,7 @@ public:  	/*virtual*/ bool doWork(S32 param); // Called from LLWorkerThread::processRequest()  	/*virtual*/ void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)  	/*virtual*/ bool deleteOK(); // called from update() (WORK THREAD) - +	  	~LLTextureFetchWorker();  	// void relese() { --mActiveCount; } @@ -196,6 +196,8 @@ private:  	bool processSimulatorPackets();  	bool writeToCacheComplete(); +	void removeFromHTTPQueue(); +  	void lockWorkMutex() { mWorkMutex.lock(); }  	void unlockWorkMutex() { mWorkMutex.unlock(); } @@ -275,6 +277,8 @@ private:  	S32 mRetryAttempt;  	S32 mActiveCount;  	U32 mGetStatus; +	U32 mHTTPHandle; +	F32 mDelay;  	std::string mGetReason;  	// Work Data @@ -328,6 +332,7 @@ public:  			mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow);  		} +		S32 data_size = 0;  		lldebugs << "HTTP COMPLETE: " << mID << llendl;  		LLTextureFetchWorker* worker = mFetcher->getWorker(mID);  		if (worker) @@ -349,7 +354,7 @@ public:  // 				llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl;  			} -			S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success); +			data_size = worker->callbackHttpGet(channels, buffer, partial, success);  			if(log_texture_traffic && data_size > 0)  			{ @@ -359,9 +364,7 @@ public:  					gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ;  				}  			} - -			mFetcher->removeFromHTTPQueue(mID, data_size); - +		  			if (worker->mMetricsStartTime)  			{  				LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, @@ -376,9 +379,10 @@ public:  		}  		else  		{ -			mFetcher->removeFromHTTPQueue(mID); - 			llwarns << "Worker not found: " << mID << llendl; +			llwarns << "Worker not found: " << mID << llendl;  		} + +		mFetcher->getCurlRequest().completeRequest(data_size);  	}  	virtual bool followRedir() @@ -692,10 +696,12 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mLastPacket(-1),  	  mTotalPackets(0),  	  mImageCodec(IMG_CODEC_INVALID), -	  mMetricsStartTime(0) +	  mMetricsStartTime(0), +	  mHTTPHandle(0), +	  mDelay(-1.f)  {  	mCanUseNET = mUrl.empty() ; - +	  	calcWorkPriority();  	mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;  // 	llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl; @@ -726,7 +732,19 @@ LLTextureFetchWorker::~LLTextureFetchWorker()  	mFormattedImage = NULL;  	clearPackets();  	unlockWorkMutex(); -	mFetcher->removeFromHTTPQueue(mID); +	 +	removeFromHTTPQueue(); +} + +void LLTextureFetchWorker::removeFromHTTPQueue() +{ +	if(mHTTPHandle > 0) +	{ +		llassert_always(mState == WAIT_HTTP_REQ); + +		mFetcher->getCurlRequest().removeRequest(mHTTPHandle); +		mHTTPHandle = 0; +	}  }  void LLTextureFetchWorker::clearPackets() @@ -824,6 +842,7 @@ void LLTextureFetchWorker::setImagePriority(F32 priority)  		mImagePriority = priority;  		calcWorkPriority();  		U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS); +		mFetcher->getCurlRequest().updatePriority(mHTTPHandle, mWorkPriority);  		setPriority(work_priority);  	}  } @@ -851,8 +870,6 @@ void LLTextureFetchWorker::startWork(S32 param)  // Called from LLWorkerThread::processRequest()  bool LLTextureFetchWorker::doWork(S32 param)  { -	static const F32 FETCHING_TIMEOUT = 120.f;//seconds -  	LLMutexLock lock(&mWorkMutex);  	if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) @@ -912,6 +929,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mCacheWriteHandle = LLTextureCache::nullHandle();  		mState = LOAD_FROM_TEXTURE_CACHE;  		mInCache = FALSE; +		mDelay = -1.f;  		mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE  		LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)  							 << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; @@ -927,7 +945,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			S32 size = mDesiredSize - offset;  			if (size <= 0)  			{ -				mState = CACHE_POST; +				mState = CACHE_POST; //have enough data, will fall to decode  				return false;  			}  			mFileSize = 0; @@ -944,7 +962,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  																		  offset, size, responder);  				mCacheReadTimer.reset();  			} -			else if (mUrl.empty()) +			else if (mUrl.empty() && mFetcher->canLoadFromCache())  			{  				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it @@ -953,7 +971,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  																		  offset, size, responder);  				mCacheReadTimer.reset();  			} -			else if(mCanUseHTTP) +			else if(!mUrl.empty() && mCanUseHTTP)  			{  				if (!(mUrl.compare(0, 7, "http://") == 0))  				{ @@ -981,6 +999,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			else  			{ +				// +				//This should never happen +				//  				return false;  			}  		} @@ -1020,6 +1041,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;  				mState = LOAD_FROM_NETWORK;  			} +			  			// fall through  			LLTextureFetch::sCacheHitRate.addValue(0.f);  		} @@ -1060,7 +1082,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		if (mCanUseHTTP && !mUrl.empty())  		{ -			mState = LLTextureFetchWorker::SEND_HTTP_REQ; +			mState = SEND_HTTP_REQ;  			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  			if(mWriteToCacheState != NOT_WRITE)  			{ @@ -1156,17 +1178,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if(mCanUseHTTP)  		{ -			//NOTE: -			//control the number of the http requests issued for: -			//1, not openning too many file descriptors at the same time; -			//2, control the traffic of http so udp gets bandwidth. -			// -			static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ; -			if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE) -			{ -				return false ; //wait. -			} -  			mFetcher->removeFromNetworkQueue(this, false);  			S32 cur_size = 0; @@ -1179,6 +1190,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  					{  						// We already have all the data, just decode it  						mLoadedDiscard = mFormattedImage->getDiscardLevel(); +						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						mState = DECODE_IMAGE;  						return false;  					} @@ -1209,7 +1221,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  				mState = WAIT_HTTP_REQ;	 -				mFetcher->addToHTTPQueue(mID);  				if (! mMetricsStartTime)  				{  					mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); @@ -1221,8 +1232,16 @@ bool LLTextureFetchWorker::doWork(S32 param)  				// Will call callbackHttpGet when curl request completes  				std::vector<std::string> headers;  				headers.push_back("Accept: image/x-j2c"); -				res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, -															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true)); +				// If we try to fetch the whole file, we set the size to 0 so that we generate the correct curl range request +				// Note: it looks a bit hacky but we need to limit this (size==0) to mean "whole file" to HTTP only as it messes up UDP fetching +				if ((offset+mRequestedSize) == MAX_IMAGE_DATA_SIZE) +				{ +					mRequestedSize = 0; +				} +				mHTTPHandle = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, mWorkPriority, +															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true), mDelay); +				mDelay = -1.f; //reset +				res = true;  			}  			if (!res)  			{ @@ -1257,6 +1276,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  					{  						mState = INIT ;  						mCanUseHTTP = false ; +						mUrl.clear();  						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						return false ;  					} @@ -1269,12 +1289,15 @@ bool LLTextureFetchWorker::doWork(S32 param)  					++mHTTPFailCount;  					max_attempts = mHTTPFailCount+1; // Keep retrying  					LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; +					mDelay = 2.0f; //delay 2 second to re-issue the http request  				}  				else  				{  					const S32 HTTP_MAX_RETRY_COUNT = 3;  					max_attempts = HTTP_MAX_RETRY_COUNT + 1;  					++mHTTPFailCount; +					mDelay = 2.0f; //delay 2 second to re-issue the http request +  					llinfos << "HTTP GET failed for: " << mUrl  							<< " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"  							<< " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl; @@ -1282,10 +1305,12 @@ bool LLTextureFetchWorker::doWork(S32 param)  				if (mHTTPFailCount >= max_attempts)  				{ +					mUrl.clear();  					if (cur_size > 0)  					{  						// Use available data  						mLoadedDiscard = mFormattedImage->getDiscardLevel(); +						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						mState = DECODE_IMAGE;  						return false;   					} @@ -1298,11 +1323,20 @@ bool LLTextureFetchWorker::doWork(S32 param)  				}  				else  				{ +					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  					mState = SEND_HTTP_REQ;  					return false; // retry  				}  			} +			// Clear the url since we're done with the fetch +			// Note: mUrl is used to check is fetching is required so failure to clear it will force an http fetch +			// next time the texture is requested, even if the data have already been fetched. +			if(mWriteToCacheState != NOT_WRITE) +			{ +				mUrl.clear(); +			} +  			llassert_always(mBufferSize == cur_size + mRequestedSize);  			if(!mBufferSize)//no data received.  			{ @@ -1357,13 +1391,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		else  		{ -			if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32()) -			{ -				//timeout, abort. -				mState = DONE; -				return true; -			} - +			// +			//No need to timeout, the responder should be triggered automatically. +			//  			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  			return false;  		} @@ -1495,7 +1525,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);  		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,  																  mFormattedImage->getData(), datasize, -																  mFileSize, responder); +																  mFileSize, mRawImage, mDecodedDiscard, responder);  		// fall through  	} @@ -1683,7 +1713,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  	S32 data_size = 0 ;  	LLMutexLock lock(&mWorkMutex); - +	mHTTPHandle = 0;  	if (mState != WAIT_HTTP_REQ)  	{  		llwarns << "callbackHttpGet for unrequested fetch worker: " << mID @@ -1707,7 +1737,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  			mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);  			buffer->readAfter(channels.in(), NULL, mBuffer, data_size);  			mBufferSize += data_size; -			if (data_size < mRequestedSize && mRequestedDiscard == 0) +			if (mRequestedSize == 0)  			{  				mHaveAllData = TRUE;  			} @@ -1733,6 +1763,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  	{  		mRequestedSize = -1; // error  	} +	  	mLoaded = TRUE;  	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); @@ -1856,11 +1887,11 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mTextureCache(cache),  	  mImageDecodeThread(imagedecodethread),  	  mTextureBandwidth(0), -	  mHTTPTextureBits(0), -	  mTotalHTTPRequests(0),  	  mCurlGetRequest(NULL),  	  mQAMode(qa_mode),  	  mFetchDebugger(NULL), +	  mFetchSource(LLTextureFetch::FROM_ALL), +	  mOriginFetchSource(LLTextureFetch::FROM_ALL),  	  mFetcherLocked(FALSE)  {  	mCurlPOSTRequestCount = 0; @@ -1871,6 +1902,13 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	if(LLTextureFetchDebugger::isEnabled())  	{  		mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; +		mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource"); +		if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE) +		{ +			mFetchSource = LLTextureFetch::FROM_ALL; +			gSavedSettings.setS32("TextureFetchSource", 0); +		} +		mOriginFetchSource = mFetchSource;  	}  } @@ -1940,6 +1978,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  	}  	else  	{ +		// If the requester knows nothing about the file, we fetch the smallest +		// amount of data at the lowest resolution (highest discard level) possible.  		desired_size = TEXTURE_CACHE_ENTRY_SIZE;  		desired_discard = MAX_DISCARD_LEVEL;  	} @@ -2018,45 +2058,22 @@ void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool c  	}  } -// protected -void LLTextureFetch::addToHTTPQueue(const LLUUID& id) -{ -	LLMutexLock lock(&mNetworkQueueMutex); -	mHTTPTextureQueue.insert(id); -	mTotalHTTPRequests++; -} - -void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size) -{ -	LLMutexLock lock(&mNetworkQueueMutex); -	mHTTPTextureQueue.erase(id); -	mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits	 -} -  void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)  {  	lockQueue() ;  	LLTextureFetchWorker* worker = getWorkerAfterLock(id); -	if (worker) -	{		 -		size_t erased_1 = mRequestMap.erase(worker->mID); -		unlockQueue() ; - -		llassert_always(erased_1 > 0) ; - -		removeFromNetworkQueue(worker, cancel); -		llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; +	unlockQueue() ; -		worker->scheduleDelete();	 -	} -	else -	{ -		unlockQueue() ; -	} +	removeRequest(worker, cancel);  }  void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)  { +	if(!worker) +	{ +		return; +	} +  	lockQueue() ;  	size_t erased_1 = mRequestMap.erase(worker->mID);  	unlockQueue() ; @@ -2065,9 +2082,28 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)  	removeFromNetworkQueue(worker, cancel);  	llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; +	worker->removeFromHTTPQueue();  	worker->scheduleDelete();	  } +void LLTextureFetch::deleteAllRequests() +{ +	while(1) +	{ +		lockQueue(); +		if(mRequestMap.empty()) +		{ +			unlockQueue() ; +			break; +		} + +		LLTextureFetchWorker* worker = mRequestMap.begin()->second; +		unlockQueue() ; + +		removeRequest(worker, true); +	} +} +  S32 LLTextureFetch::getNumRequests()   {   	lockQueue() ; @@ -2077,24 +2113,6 @@ S32 LLTextureFetch::getNumRequests()  	return size ;  } -S32 LLTextureFetch::getNumHTTPRequests()  -{  -	mNetworkQueueMutex.lock() ; -	S32 size = (S32)mHTTPTextureQueue.size();  -	mNetworkQueueMutex.unlock() ; - -	return size ; -} - -U32 LLTextureFetch::getTotalNumHTTPRequests() -{ -	mNetworkQueueMutex.lock() ; -	U32 size = mTotalHTTPRequests ; -	mNetworkQueueMutex.unlock() ; - -	return size ; -} -  // call lockQueue() first!  LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)  { @@ -2180,7 +2198,7 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)  	{  		worker->lockWorkMutex();  		worker->setImagePriority(priority); -		worker->unlockWorkMutex(); +		worker->unlockWorkMutex();		  		res = true;  	}  	return res; @@ -2262,15 +2280,7 @@ S32 LLTextureFetch::update(F32 max_time_ms)  {  	static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS"); -	{ -		mNetworkQueueMutex.lock() ; -		mMaxBandwidth = band_width ; - -		gTextureList.sTextureBits += mHTTPTextureBits ; -		mHTTPTextureBits = 0 ; - -		mNetworkQueueMutex.unlock() ; -	} +	mMaxBandwidth = band_width ;  	S32 res = LLWorkerThread::update(max_time_ms); @@ -2281,13 +2291,28 @@ S32 LLTextureFetch::update(F32 max_time_ms)  		// won't work so don't bother trying  		if (LLStartUp::getStartupState() > STATE_AGENT_SEND)  		{ -			sendRequestListToSimulators(); +			sendRequestListToSimulators();			  		}  	}  	if (!mThreaded)  	{  		commonUpdate(); +		 +		if(mCurlGetRequest) +		{ +			mCurlGetRequest->nextRequests(); +		} +	} + +	if(mCurlGetRequest) +	{ +		gTextureList.sTextureBits += mCurlGetRequest->getTotalReceivedBits(); +	} + +	if(mFetchDebugger) +	{ +		mFetchDebugger->tryToStopDebug(); //check if need to stop debugger.  	}  	return res; @@ -2317,7 +2342,7 @@ void LLTextureFetch::shutDownImageDecodeThread()  void LLTextureFetch::startThread()  {  	// Construct mCurlGetRequest from Worker Thread -	mCurlGetRequest = new LLCurlRequest(); +	mCurlGetRequest = new LLCurlTextureRequest(8);  	if(mFetchDebugger)  	{ @@ -2342,6 +2367,8 @@ void LLTextureFetch::threadedUpdate()  {  	llassert_always(mCurlGetRequest); +	mCurlGetRequest->nextRequests(); +  	// Limit update frequency  	const F32 PROCESS_TIME = 0.05f;   	static LLFrameTimer process_timer; @@ -3154,6 +3181,7 @@ public:  			llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl;  		}  		mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success); +		mDebugger->getCurlGetRequest()->completeRequest(0);  	}  	virtual bool followRedir()  	{ @@ -3176,7 +3204,8 @@ LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextur  LLTextureFetchDebugger::~LLTextureFetchDebugger()  {  	mFetchingHistory.clear(); -	stopDebug(); +	mStopDebug = TRUE; +	tryToStopDebug();  }  void LLTextureFetchDebugger::init() @@ -3191,6 +3220,8 @@ void LLTextureFetchDebugger::init()  	mTotalFetchingTime = 0.f;  	mRefetchVisCacheTime = -1.f;  	mRefetchVisHTTPTime = -1.f; +	mRefetchAllCacheTime = -1.f; +	mRefetchAllHTTPTime = -1.f;  	mNumFetchedTextures = 0;  	mNumCacheHits = 0; @@ -3204,10 +3235,56 @@ void LLTextureFetchDebugger::init()  	mRenderedDecodedData = 0;  	mFetchedPixels = 0;  	mRenderedPixels = 0; -	mRefetchedData = 0; -	mRefetchedPixels = 0; +	mRefetchedVisData = 0; +	mRefetchedVisPixels = 0; +	mRefetchedAllData = 0; +	mRefetchedAllPixels = 0;  	mFreezeHistory = FALSE; +	mStopDebug = FALSE; +	mClearHistory = FALSE; +} + +void LLTextureFetchDebugger::startWork(e_debug_state state) +{ +	switch(state) +	{ +		case IDLE: +			break; +		case START_DEBUG: +			startDebug(); +			break; +		case READ_CACHE:			 +			debugCacheRead(); +			break; +		case WRITE_CACHE: +			debugCacheWrite(); +			break; +		case DECODING: +			debugDecoder(); +			break; +		case HTTP_FETCHING: +			debugHTTP(); +			break; +		case GL_TEX: +			debugGLTextureCreation(); +			break; +		case REFETCH_VIS_CACHE: +			debugRefetchVisibleFromCache(); +			break; +		case REFETCH_VIS_HTTP: +			debugRefetchVisibleFromHTTP(); +			break; +		case REFETCH_ALL_CACHE: +			debugRefetchAllFromCache(); +			break; +		case REFETCH_ALL_HTTP: +			debugRefetchAllFromHTTP(); +			break; +		default: +			break; +	} +	return;  }  void LLTextureFetchDebugger::startDebug() @@ -3215,10 +3292,18 @@ void LLTextureFetchDebugger::startDebug()  	//lock the fetcher  	mFetcher->lockFetcher(true);  	mFreezeHistory = TRUE; +	mFetcher->resetLoadSource();  	//clear the current fetching queue  	gTextureList.clearFetchingRequests(); +	mState = START_DEBUG; +} + +bool LLTextureFetchDebugger::processStartDebug(F32 max_time) +{ +	mTimer.reset(); +  	//wait for all works to be done  	while(1)  	{ @@ -3230,6 +3315,11 @@ void LLTextureFetchDebugger::startDebug()  		{  			break;  		} + +		if(mTimer.getElapsedTimeF32() > max_time) +		{ +			return false; +		}  	}  	//collect statistics @@ -3268,10 +3358,17 @@ void LLTextureFetchDebugger::startDebug()  	}  	mNumFetchedTextures = fetched_textures.size(); + +	return true;  } -void LLTextureFetchDebugger::stopDebug() +void LLTextureFetchDebugger::tryToStopDebug()  { +	if(!mStopDebug) +	{ +		return; +	} +  	//clear the current debug work  	S32 size = mFetchingHistory.size();  	switch(mState) @@ -3300,37 +3397,71 @@ void LLTextureFetchDebugger::stopDebug()  		break;  	case GL_TEX:  		break; +	case REFETCH_VIS_CACHE: +		break; +	case REFETCH_VIS_HTTP: +		break; +	case REFETCH_ALL_CACHE: +		mRefetchList.clear(); +		break; +	case REFETCH_ALL_HTTP: +		mRefetchList.clear(); +		break;  	default:  		break;  	} -	while(1) +	if(update(0.005f))  	{ -		if(update()) +		//unlock the fetcher +		mFetcher->lockFetcher(false); +		mFetcher->resetLoadSource(); +		mFreezeHistory = FALSE;		 +		mStopDebug = FALSE; + +		if(mClearHistory)  		{ -			break; +			mFetchingHistory.clear(); +			init();	 +			mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset  		}  	} - -	//unlock the fetcher -	mFetcher->lockFetcher(false); -	mFreezeHistory = FALSE; -	mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset  }  //called in the main thread and when the fetching queue is empty  void LLTextureFetchDebugger::clearHistory()  { -	mFetchingHistory.clear(); -	init(); +	mClearHistory = TRUE;	  }  void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)  { +	if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull()) +	{ +		return; +	} +  	if(mFreezeHistory)  	{ -		mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); -		mRefetchedData += worker->mFormattedImage->getDataSize(); +		if(mState == REFETCH_VIS_CACHE || mState == REFETCH_VIS_HTTP) +		{ +			mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); +			mRefetchedVisData += worker->mFormattedImage->getDataSize(); +		} +		else +		{ +			mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); +			mRefetchedAllData += worker->mFormattedImage->getDataSize(); + +			LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID); +			if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) +			{ +				if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) +				{ +					mRefetchList[tex].erase(mRefetchList[tex].begin()); +				} +			} +		}  		return;  	} @@ -3342,9 +3473,8 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)  	mDecodedData += worker->mRawImage->getDataSize();  	mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); -	mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); -	//mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(), -		//worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); +	mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,  +		worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));  }  void LLTextureFetchDebugger::lockCache() @@ -3361,6 +3491,7 @@ void LLTextureFetchDebugger::debugCacheRead()  	llassert_always(mState == IDLE);  	mTimer.reset();  	mState = READ_CACHE; +	mCacheReadTime = -1.f;  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3396,6 +3527,7 @@ void LLTextureFetchDebugger::debugCacheWrite()  	llassert_always(mState == IDLE);  	mTimer.reset();  	mState = WRITE_CACHE; +	mCacheWriteTime = -1.f;  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3405,7 +3537,7 @@ void LLTextureFetchDebugger::debugCacheWrite()  			mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,   				mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,  				mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,  -				new LLDebuggerCacheWriteResponder(this, i));					 +				NULL, 0, new LLDebuggerCacheWriteResponder(this, i));					  		}  	}  } @@ -3424,6 +3556,7 @@ void LLTextureFetchDebugger::debugDecoder()  	llassert_always(mState == IDLE);  	mTimer.reset();  	mState = DECODING; +	mDecodingTime = -1.f;  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3459,6 +3592,7 @@ void LLTextureFetchDebugger::debugHTTP()  	mTimer.reset();  	mState = HTTP_FETCHING; +	mHTTPTime = -1.f;  	S32 size = mFetchingHistory.size();  	for (S32 i = 0 ; i < size ; i++) @@ -3475,14 +3609,28 @@ void LLTextureFetchDebugger::debugHTTP()  S32 LLTextureFetchDebugger::fillCurlQueue()  { -	if (mNbCurlRequests == 24) -		return mNbCurlRequests; -	 +	if(mStopDebug) //stop +	{ +		mNbCurlCompleted = mFetchingHistory.size(); +		return 0; +	}  	S32 size = mFetchingHistory.size(); + +	if (mNbCurlRequests == size) //all issued +	{ +		return 0; +	}	 +	 +	S32 counter = 8; +	mNbCurlRequests = 0;  	for (S32 i = 0 ; i < size ; i++)  	{		 +		mNbCurlRequests++; +  		if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) +		{  			continue; +		}  		std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str();  		S32 requestedSize = mFetchingHistory[i].mRequestedSize;  		// We request the whole file if the size was not set. @@ -3491,16 +3639,11 @@ S32 LLTextureFetchDebugger::fillCurlQueue()  		requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);  		std::vector<std::string> headers;  		headers.push_back("Accept: image/x-j2c"); -		bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i)); -		if (res) -		{ -			mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; -			mNbCurlRequests++; -			// Hack -			if (mNbCurlRequests == 24) -				break; -		} -		else  +		mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, 0x10000, new LLDebuggerHTTPResponder(this, i)); +		 +		mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; +		counter--; +		if(counter < 1)  		{  			break;  		} @@ -3513,7 +3656,7 @@ void LLTextureFetchDebugger::debugGLTextureCreation()  {  	llassert_always(mState == IDLE);  	mState = GL_TEX; -	std::vector<LLViewerFetchedTexture*> tex_list; +	mTempTexList.clear();  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3524,28 +3667,54 @@ void LLTextureFetchDebugger::debugGLTextureCreation()  			if(tex && !tex->isForSculptOnly())  			{  				tex->destroyGLTexture() ; -				tex_list.push_back(tex); +				mTempTexList.push_back(tex);  			}  		}  	} +	 +	mGLCreationTime = -1.f; +	mTempIndex = 0; +	mHistoryListIndex = 0; +	 +	return; +} +bool LLTextureFetchDebugger::processGLCreation(F32 max_time) +{  	mTimer.reset(); -	S32 j = 0 ; -	S32 size1 = tex_list.size(); -	for(S32 i = 0 ; i < size && j < size1; i++) + +	bool done = true; +	S32 size = mFetchingHistory.size(); +	S32 size1 = mTempTexList.size(); +	for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)  	{ -		if(mFetchingHistory[i].mRawImage.notNull()) +		if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())  		{ -			if(mFetchingHistory[i].mID == tex_list[j]->getID()) +			if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())  			{ -				tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel()); -				j++; +				mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,  +					mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel()); +				mTempIndex++;  			}  		} + +		if(mTimer.getElapsedTimeF32() > max_time) +		{ +			done = false; +			break; +		}  	} -	mGLCreationTime = mTimer.getElapsedTimeF32() ; -	return; +	if(mGLCreationTime < 0.f) +	{ +		mGLCreationTime = mTimer.getElapsedTimeF32() ; +	} +	else +	{ +		mGLCreationTime += mTimer.getElapsedTimeF32() ; +	} + +	return done;  }  //clear fetching results of all textures. @@ -3562,15 +3731,62 @@ void LLTextureFetchDebugger::clearTextures()  	}  } +void LLTextureFetchDebugger::makeRefetchList() +{ +	mRefetchList.clear(); +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size; i++) +	{		 +		LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID); +		if(tex && tex->isJustBound()) //visible +		{ +			continue; //the texture fetch pipeline will take care of visible textures. +		} + +		mRefetchList[tex].push_back(i); 		 +	} +} + +void LLTextureFetchDebugger::scanRefetchList() +{ +	if(mStopDebug) +	{ +		return; +	} +	if(!mRefetchNonVis) +	{ +		return; +	} + +	for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin(); +		iter != mRefetchList.end(); ) +	{ +		if(iter->second.empty()) +		{ +			gTextureList.setDebugFetching(iter->first, -1); +			mRefetchList.erase(iter++);		// This is the correct method to "erase and move on" in an std::map +		} +		else +		{ +			gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel); +			++iter; +		} +	} +} +  void LLTextureFetchDebugger::debugRefetchVisibleFromCache()  {  	llassert_always(mState == IDLE);  	mState = REFETCH_VIS_CACHE;  	clearTextures(); - +	mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); +	  	mTimer.reset();  	mFetcher->lockFetcher(false); +	mRefetchVisCacheTime = -1.f; +	mRefetchedVisData = 0; +	mRefetchedVisPixels = 0;  }  void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() @@ -3578,17 +3794,60 @@ void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()  	llassert_always(mState == IDLE);  	mState = REFETCH_VIS_HTTP; -	clearCache();  	clearTextures(); +	mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +	mRefetchVisHTTPTime = -1.f; +	mRefetchedVisData = 0; +	mRefetchedVisPixels = 0; +} + +void LLTextureFetchDebugger::debugRefetchAllFromCache() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_ALL_CACHE; + +	clearTextures(); +	makeRefetchList(); +	mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +	mRefetchAllCacheTime = -1.f; +	mRefetchedAllData = 0; +	mRefetchedAllPixels = 0; +	mRefetchNonVis = FALSE; +} + +void LLTextureFetchDebugger::debugRefetchAllFromHTTP() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_ALL_HTTP; + +	clearTextures(); +	makeRefetchList(); +	mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);  	mTimer.reset();  	mFetcher->lockFetcher(false); +	mRefetchAllHTTPTime = -1.f; +	mRefetchedAllData = 0; +	mRefetchedAllPixels = 0; +	mRefetchNonVis = TRUE;  } -bool LLTextureFetchDebugger::update() +bool LLTextureFetchDebugger::update(F32 max_time)  {  	switch(mState)  	{ +	case START_DEBUG: +		if(processStartDebug(max_time)) +		{ +			mState = IDLE; +		} +		break;  	case READ_CACHE:  		if(!mTextureCache->update(1))  		{ @@ -3615,6 +3874,7 @@ bool LLTextureFetchDebugger::update()  		break;  	case HTTP_FETCHING:  		mCurlGetRequest->process(); +		mCurlGetRequest->nextRequests();  		LLCurl::getCurlThread()->update(1);  		if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())  		{ @@ -3623,22 +3883,59 @@ bool LLTextureFetchDebugger::update()  		}  		break;  	case GL_TEX: -		mState = IDLE; +		if(processGLCreation(max_time)) +		{ +			mState = IDLE; +			mTempTexList.clear(); +		}  		break;  	case REFETCH_VIS_CACHE:  		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)  		{ -			mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ;  			mState = IDLE;  			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource();  		}  		break;  	case REFETCH_VIS_HTTP:  		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)  		{ -			mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource(); +		} +		break; +	case REFETCH_ALL_CACHE: +		scanRefetchList(); +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			if(!mRefetchNonVis) +			{ +				mRefetchNonVis = TRUE; //start to fetch non-vis +				scanRefetchList(); +				break; +			} + +			mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE;  +			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource(); +			mRefetchList.clear(); +			mRefetchNonVis = FALSE; +		} +		break; +	case REFETCH_ALL_HTTP: +		scanRefetchList(); +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ;  			mState = IDLE;  			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource(); +			mRefetchList.clear(); +			mRefetchNonVis = FALSE;  		}  		break;  	default: @@ -3679,7 +3976,6 @@ void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& ch  										  const LLIOPipe::buffer_ptr_t& buffer,   										  bool partial, bool success)  { -	mNbCurlRequests--;  	if (success)  	{  		mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; @@ -3693,7 +3989,7 @@ void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& ch  			U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);  			buffer->readAfter(channels.in(), NULL, d_buffer, data_size); -			llassert_always(mFetchingHistory[id].mFormattedImage.isNull()); +			mFetchingHistory[id].mFormattedImage = NULL;  			{  				// For now, create formatted image based on extension  				std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str(); @@ -3715,6 +4011,7 @@ void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& ch  		{  			// Fetch will have to be redone  			mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE; +			mNbCurlRequests--;	  		}  		else //skip  		{ diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 107e1623b0..f5072a79f1 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -65,6 +65,7 @@ public:  	bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,  					   S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);  	void deleteRequest(const LLUUID& id, bool cancel); +	void deleteAllRequests();  	bool getRequestFinished(const LLUUID& id, S32& discard_level,  							LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux);  	bool updateRequestPriority(const LLUUID& id, F32 priority); @@ -81,8 +82,6 @@ public:  					  U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);  	void dump();  	S32 getNumRequests() ; -	S32 getNumHTTPRequests() ; -	U32 getTotalNumHTTPRequests() ;  	// Public for access by callbacks      S32 getPending(); @@ -101,7 +100,7 @@ public:  							LLViewerAssetStats * main_stats);  	void commandDataBreak(); -	LLCurlRequest & getCurlRequest()	{ return *mCurlGetRequest; } +	LLCurlTextureRequest & getCurlRequest()	{ return *mCurlGetRequest; }  	bool isQAMode() const				{ return mQAMode; } @@ -113,7 +112,6 @@ protected:  	void addToNetworkQueue(LLTextureFetchWorker* worker);  	void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);  	void addToHTTPQueue(const LLUUID& id); -	void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);  	void removeRequest(LLTextureFetchWorker* worker, bool cancel);  	// Overrides from the LLThread tree @@ -172,8 +170,8 @@ private:  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread; -	LLCurlRequest* mCurlGetRequest; -	 +	LLCurlTextureRequest* mCurlGetRequest; +  	// Map of all requests by UUID  	typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;  	map_t mRequestMap; @@ -188,11 +186,6 @@ private:  	F32 mMaxBandwidth;  	LLTextureInfo mTextureInfo; -	U32 mHTTPTextureBits; - -	//debug use -	U32 mTotalHTTPRequests ; -  	// Out-of-band cross-thread command queue.  This command queue  	// is logically tied to LLQueuedThread's list of  	// QueuedRequest instances and so must be covered by the @@ -216,18 +209,34 @@ public:  	// reporting due to either startup or a problem POSTing data.  	static volatile bool svMetricsDataBreak; +public: +	//debug use +	enum e_tex_source +	{ +		FROM_ALL = 0, +		FROM_HTTP_ONLY, +		INVALID_SOURCE +	};  private:  	//debug use  	LLTextureFetchDebugger* mFetchDebugger;  	bool mFetcherLocked; +	 +	e_tex_source mFetchSource; +	e_tex_source mOriginFetchSource;  public:  	//debug use  	LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;}  	void lockFetcher(bool lock) { mFetcherLocked = lock;} + +	void setLoadSource(e_tex_source source) {mFetchSource = source;} +	void resetLoadSource() {mFetchSource = mOriginFetchSource;} +	bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;}  };  //debug use +class LLViewerFetchedTexture;  class LLTextureFetchDebugger  {  	friend class LLTextureFetch; @@ -239,6 +248,7 @@ public:  	enum e_debug_state  	{  		IDLE = 0, +		START_DEBUG,  		READ_CACHE,  		WRITE_CACHE,  		DECODING, @@ -301,13 +311,15 @@ private:  	F32 mTotalFetchingTime;  	F32 mRefetchVisCacheTime;  	F32 mRefetchVisHTTPTime; +	F32 mRefetchAllCacheTime; +	F32 mRefetchAllHTTPTime;  	LLTimer mTimer;  	LLTextureFetch* mFetcher;  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread; -	LLCurlRequest* mCurlGetRequest; +	LLCurlTextureRequest* mCurlGetRequest;  	S32 mNumFetchedTextures;  	S32 mNumCacheHits; @@ -321,34 +333,39 @@ private:  	U32 mRenderedDecodedData;  	U32 mFetchedPixels;  	U32 mRenderedPixels; -	U32 mRefetchedData; -	U32 mRefetchedPixels; +	U32 mRefetchedVisData; +	U32 mRefetchedVisPixels; +	U32 mRefetchedAllData; +	U32 mRefetchedAllPixels;  	BOOL mFreezeHistory; +	BOOL mStopDebug; +	BOOL mClearHistory; +	BOOL mRefetchNonVis;  	std::string mHTTPUrl;  	S32 mNbCurlRequests;  	S32 mNbCurlCompleted; +	std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; +	std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList; +	S32 mTempIndex; +	S32 mHistoryListIndex; +  public: -	bool update(); //called in the main thread once per frame +	bool update(F32 max_time); //called in the main thread once per frame  	//fetching history  	void clearHistory();  	void addHistoryEntry(LLTextureFetchWorker* worker); -	void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;} -	 -	void startDebug(); -	void stopDebug(); //stop everything -	void debugCacheRead(); -	void debugCacheWrite();	 -	void debugHTTP(); -	void debugDecoder(); -	void debugGLTextureCreation(); -	void debugRefetchVisibleFromCache(); -	void debugRefetchVisibleFromHTTP(); +	void setCurlGetRequest(LLCurlTextureRequest* request) { mCurlGetRequest = request;} +	LLCurlTextureRequest* getCurlGetRequest() { return mCurlGetRequest;} +	void startWork(e_debug_state state); +	void setStopDebug() {mStopDebug = TRUE;} +	void tryToStopDebug(); //stop everything +	  	void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,  						   S32 imagesize, BOOL islocal);  	void callbackCacheWrite(S32 id, bool success); @@ -372,8 +389,10 @@ public:  	U32  getRenderedDecodedData()        {return mRenderedDecodedData;}  	U32  getFetchedPixels()              {return mFetchedPixels;}  	U32  getRenderedPixels()             {return mRenderedPixels;} -	U32  getRefetchedData()              {return mRefetchedData;} -	U32  getRefetchedPixels()            {return mRefetchedPixels;} +	U32  getRefetchedVisData()              {return mRefetchedVisData;} +	U32  getRefetchedVisPixels()            {return mRefetchedVisPixels;} +	U32  getRefetchedAllData()              {return mRefetchedAllData;} +	U32  getRefetchedAllPixels()            {return mRefetchedAllPixels;}  	F32  getCacheReadTime()     {return mCacheReadTime;}  	F32  getCacheWriteTime()    {return mCacheWriteTime;} @@ -383,11 +402,15 @@ public:  	F32  getTotalFetchingTime() {return mTotalFetchingTime;}  	F32  getRefetchVisCacheTime() {return mRefetchVisCacheTime;}  	F32  getRefetchVisHTTPTime()  {return mRefetchVisHTTPTime;} +	F32  getRefetchAllCacheTime() {return mRefetchAllCacheTime;} +	F32  getRefetchAllHTTPTime()  {return mRefetchAllHTTPTime;}  private:  	void init();  	void clearTextures();//clear fetching results of all textures.  	void clearCache(); +	void makeRefetchList(); +	void scanRefetchList();  	void lockFetcher();  	void unlockFetcher(); @@ -400,6 +423,20 @@ private:  	S32 fillCurlQueue(); +	void startDebug(); +	void debugCacheRead(); +	void debugCacheWrite();	 +	void debugHTTP(); +	void debugDecoder(); +	void debugGLTextureCreation(); +	void debugRefetchVisibleFromCache(); +	void debugRefetchVisibleFromHTTP(); +	void debugRefetchAllFromCache(); +	void debugRefetchAllFromHTTP(); + +	bool processStartDebug(F32 max_time); +	bool processGLCreation(F32 max_time); +  private:  	static bool sDebuggerEnabled;  public: diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 52d085dd2c..c60b4155a0 100644..100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -514,7 +514,7 @@ void LLGLTexMemBar::draw()  	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);  	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);  	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); -	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; +	U32 total_http_requests = LLAppViewer::getTextureFetch()->getCurlRequest().getTotalIssuedRequests() ;  	//----------------------------------------------------------------------------  	LLGLSUIDefault gls_ui;  	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -552,7 +552,7 @@ void LLGLTexMemBar::draw()  					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),  					LLLFSThread::sLocal->getPending(),  					LLImageRaw::sRawImageCount, -					LLAppViewer::getTextureFetch()->getNumHTTPRequests(), +					LLAppViewer::getTextureFetch()->getCurlRequest().getNumRequests(),  					LLAppViewer::getImageDecodeThread()->getPending(),   					gTextureList.mCreateTextureList.size()); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 4c59fd0371..4c59fd0371 100644..100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 8319752230..8319752230 100644..100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b47a41c44c..b47a41c44c 100644..100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index f029ae5302..f029ae5302 100644..100755 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index dd5dae1dc1..dd5dae1dc1 100644..100755 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 28f4ec72f3..0be016e5bb 100644..100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -945,15 +945,8 @@ LLSD LLViewerStats::PhaseMap::dumpPhases()  	for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)  	{  		const std::string& phase_name = iter->first; -		result[phase_name]["completed"] = !(iter->second.getStarted()); +		result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted()));  		result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); -#if 0 // global stats for each phase seem like overkill here -		phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name); -		if (stats_iter != sPhaseStats.end()) -		{ -			result[phase_name]["stats"] = stats_iter->second.getData(); -		} -#endif  	}  	return result;  } diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 750d963f69..750d963f69 100644..100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 7f638a24bf..b82fd092f8 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -62,6 +62,7 @@  #include "llmediaentry.h"  #include "llvovolume.h"  #include "llviewermedia.h" +#include "lltexturecache.h"  ///////////////////////////////////////////////////////////////////////////////  // statics @@ -409,7 +410,11 @@ void LLViewerTextureManager::cleanup()  void LLViewerTexture::initClass()  {  	LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; -	sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); +	 +	if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) +	{ +		sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); +	}  }  // static @@ -1236,7 +1241,7 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mIsMissingAsset = FALSE;  	mLoadedCallbackDesiredDiscardLevel = S8_MAX; -	mPauseLoadedCallBacks = TRUE ; +	mPauseLoadedCallBacks = FALSE ;  	mNeedsCreateTexture = FALSE; @@ -1253,6 +1258,7 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mRequestDeltaTime = 0.f;  	mForSculpt = FALSE ;  	mIsFetched = FALSE ; +	mInFastCacheList = FALSE;  	mCachedRawImage = NULL ;  	mCachedRawDiscardLevel = -1 ; @@ -1266,6 +1272,8 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mLastReferencedSavedRawImageTime = 0.0f ;  	mKeptSavedRawImageTime = 0.f ;  	mLastCallBackActiveTime = 0.f; + +	mInDebug = FALSE;  }  LLViewerFetchedTexture::~LLViewerFetchedTexture() @@ -1310,14 +1318,47 @@ void LLViewerFetchedTexture::cleanup()  	mSavedRawDiscardLevel = -1;  } +//access the fast cache +void LLViewerFetchedTexture::loadFromFastCache() +{ +	if(!mInFastCacheList) +	{ +		return; //no need to access the fast cache. +	} +	mInFastCacheList = FALSE; + +	mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel) ; +	if(mRawImage.notNull()) +	{ +		mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; +		mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; +		setTexelsPerImage(); + +		if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) +		{  +			//discard all oversized textures. +			destroyRawImage(); +			setIsMissingAsset(); +			mRawDiscardLevel = INVALID_DISCARD_LEVEL ; +		} +		else +		{ +			mRequestedDiscardLevel = mDesiredDiscardLevel + 1; +			mIsRawImageValid = TRUE;			 +			addToCreateTexture() ; +		} +	} +} +  void LLViewerFetchedTexture::setForSculpt()  {  	static const S32 MAX_INTERVAL = 8 ; //frames  	mForSculpt = TRUE ; -	if(isForSculptOnly() && !getBoundRecently()) +	if(isForSculptOnly() && hasGLTexture() && !getBoundRecently())  	{  		destroyGLTexture() ; //sculpt image does not need gl texture. +		mTextureState = ACTIVE;  	}  	checkCachedRawSculptImage() ;  	setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; @@ -1735,7 +1776,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()  		S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;  		ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);  		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; -		setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far. +		setAdditionalDecodePriority(0.1f) ;//boost the textures without any data so far.  	}  	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))  	{ @@ -1836,8 +1877,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority()  void LLViewerFetchedTexture::setDecodePriority(F32 priority)  { -	llassert(!mInImageList);  -      	mDecodePriority = priority;  	if(mDecodePriority < F_ALMOST_ZERO) @@ -1898,6 +1937,20 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()  	return current_discard ;  } +bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) +{ +	if(debug_level < 0) +	{ +		mInDebug = FALSE; +		return false; +	} +	mInDebug = TRUE; + +	mDesiredDiscardLevel = debug_level;	 + +	return true; +} +  bool LLViewerFetchedTexture::updateFetch()  {  	static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); @@ -1935,6 +1988,10 @@ bool LLViewerFetchedTexture::updateFetch()  	{  		return false; // process any raw image data in callbacks before replacing  	} +	if(mInFastCacheList) +	{ +		return false; +	}  	S32 current_discard = getCurrentDiscardLevelForFetching() ;  	S32 desired_discard = getDesiredDiscardLevel(); @@ -2052,6 +2109,10 @@ bool LLViewerFetchedTexture::updateFetch()  	{  		make_request = false;  	} +	else if(mDesiredDiscardLevel > getMaxDiscardLevel()) +	{ +		make_request = false; +	}  	else if (mNeedsCreateTexture || mIsMissingAsset)  	{  		make_request = false; @@ -2060,6 +2121,11 @@ bool LLViewerFetchedTexture::updateFetch()  	{  		make_request = false;  	} +	else if(mCachedRawImage.notNull() && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) +	{ +		make_request = false; +		switchToCachedImage() ; //use the cached raw data first +	}  	//else if (!isJustBound() && mCachedRawImageReady)  	//{  	//	make_request = false; @@ -2152,7 +2218,10 @@ bool LLViewerFetchedTexture::updateFetch()  void LLViewerFetchedTexture::clearFetchedResults()  { -	llassert_always(!mNeedsCreateTexture && !mIsFetching); +	if(mNeedsCreateTexture || mIsFetching) +	{ +		return ; +	}  	cleanup();  	destroyGLTexture(); @@ -2167,11 +2236,13 @@ void LLViewerFetchedTexture::forceToDeleteRequest()  {  	if (mHasFetcher)  	{ -		LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);  		mHasFetcher = FALSE;  		mIsFetching = FALSE ; -		resetTextureStats();  	} +		 +	resetTextureStats(); + +	mDesiredDiscardLevel = getMaxDiscardLevel() + 1;  }  void LLViewerFetchedTexture::setIsMissingAsset() @@ -2214,10 +2285,18 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call  		mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ;  	} -	if(mPauseLoadedCallBacks && !pause) +	if(mPauseLoadedCallBacks) +	{ +		if(!pause) +		{ +			unpauseLoadedCallbacks(src_callback_list) ; +		} +	} +	else if(pause)  	{ -		unpauseLoadedCallbacks(src_callback_list) ; +		pauseLoadedCallbacks(src_callback_list) ;  	} +  	LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);  	mLoadedCallbackList.push_back(entryp);	 diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f1105c3705..2ea9a07e9a 100644..100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -436,6 +436,8 @@ public:  	void setMinDiscardLevel(S32 discard) 	{ mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }  	bool updateFetch(); +	bool setDebugFetching(S32 debug_level); +	bool isInDebug() {return mInDebug;}  	void clearFetchedResults(); //clear all fetched results, for debug use. @@ -498,6 +500,9 @@ public:  	void        setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}  	void        forceToDeleteRequest(); +	void        loadFromFastCache(); +	void        setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } +	bool        isInFastCacheList() { return mInFastCacheList; }  protected:  	/*virtual*/ void switchToCachedImage();  	S32 getCurrentDiscardLevelForFetching() ; @@ -516,6 +521,8 @@ private:  private:  	BOOL  mFullyLoaded; +	BOOL  mInDebug; +	BOOL  mInFastCacheList;  protected:		  	std::string mLocalFileName; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9a6c0569a9..e4669cde34 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,7 +58,7 @@  #include "pipeline.h"  #include "llappviewer.h"  #include "llxuiparser.h" -#include "llagent.h" +#include "llviewerdisplay.h"  //////////////////////////////////////////////////////////////////////////// @@ -276,6 +276,7 @@ void LLViewerTextureList::shutdown()  	// Flush all of the references  	mLoadingStreamList.clear();  	mCreateTextureList.clear(); +	mFastCacheList.clear();  	mUUIDMap.clear(); @@ -453,6 +454,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  												   LLGLenum primary_format,  												   LLHost request_from_host)  { +	static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled"); +  	LLPointer<LLViewerFetchedTexture> imagep ;  	switch(texture_type)  	{ @@ -490,6 +493,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  		imagep->forceActive() ;  	} +	if(fast_cache_fetching_enabled) +	{ +		mFastCacheList.insert(imagep); +		imagep->setInFastCacheList(true); +	}  	return imagep ;  } @@ -503,6 +511,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)  void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)  { +	assert_main_thread();  	llassert_always(mInitialized) ;  	llassert(image);  	if (image->isInImageList()) @@ -519,6 +528,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)  void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  { +	assert_main_thread();  	llassert_always(mInitialized) ;  	llassert(image);  	if (!image->isInImageList()) @@ -593,16 +603,24 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize");  static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks");  static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch"); +static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");  static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create");  static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");  void LLViewerTextureList::updateImages(F32 max_time)  { -	if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) +	static BOOL cleared = FALSE; +	if(gTeleportDisplay)  	{ -		clearFetchingRequests(); +		if(!cleared) +		{ +			clearFetchingRequests(); +			gPipeline.clearRebuildGroups(); +			cleared = TRUE; +		}  		return;  	} +	cleared = FALSE;  	LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); @@ -613,6 +631,11 @@ void LLViewerTextureList::updateImages(F32 max_time)  	LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));  	LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); +	{ +		//loading from fast cache  +		LLFastTimer t(FTM_FAST_CACHE_IMAGE_FETCH); +		max_time -= updateImagesLoadingFastCache(max_time); +	}  	{  		LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES); @@ -673,14 +696,13 @@ void LLViewerTextureList::clearFetchingRequests()  		return;  	} +	LLAppViewer::getTextureFetch()->deleteAllRequests(); +  	for (image_priority_list_t::iterator iter = mImageList.begin();  		 iter != mImageList.end(); ++iter)  	{ -		LLViewerFetchedTexture* image = *iter; -		if(image->hasFetcher()) -		{ -			image->forceToDeleteRequest() ; -		} +		LLViewerFetchedTexture* imagep = *iter; +		imagep->forceToDeleteRequest() ;  	}  } @@ -688,10 +710,11 @@ void LLViewerTextureList::updateImagesDecodePriorities()  {  	// Update the decode priority for N images each frame  	{ -		const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second -		S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); +        static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32 +		const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); +		S32 update_counter = llmin(max_update_count, mUUIDMap.size());  		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); -		while(update_counter > 0 && !mUUIDMap.empty()) +		while ((update_counter-- > 0) && !mUUIDMap.empty())  		{  			if (iter == mUUIDMap.end())  			{ @@ -699,7 +722,13 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			}  			mLastUpdateUUID = iter->first;  			LLPointer<LLViewerFetchedTexture> imagep = iter->second; -			++iter; // safe to incrament now +			++iter; // safe to increment now + +			if(imagep->isInDebug()) +			{ +				update_counter--; +				continue; //is in debug, ignore. +			}  			//  			// Flush formatted images using a lazy flush @@ -754,7 +783,16 @@ void LLViewerTextureList::updateImagesDecodePriorities()  					imagep->setInactive() ;										  				}  			} -			 + +			if (!imagep->isInImageList()) +			{ +				continue; +			} +			if(imagep->isInFastCacheList()) +			{ +				continue; //wait for loading from the fast cache. +			} +  			imagep->processTextureStats();  			F32 old_priority = imagep->getDecodePriority();  			F32 old_priority_test = llmax(old_priority, 0.0f); @@ -764,15 +802,35 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			if ((decode_priority_test < old_priority_test * .8f) ||  				(decode_priority_test > old_priority_test * 1.25f))  			{ -				removeImageFromList(imagep); +				mImageList.erase(imagep) ;  				imagep->setDecodePriority(decode_priority); -				addImageToList(imagep); +				mImageList.insert(imagep);  			} -			update_counter--;  		}  	}  } +void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) +{ +	if(!tex->setDebugFetching(debug_level)) +	{ +		return; +	} + +	const F32 DEBUG_PRIORITY = 100000.f; +	F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f); +	F32 decode_priority_test = DEBUG_PRIORITY; +	 +	// Ignore < 20% difference +	if ((decode_priority_test < old_priority_test * .8f) || +		(decode_priority_test > old_priority_test * 1.25f)) +	{ +		removeImageFromList(tex); +		tex->setDecodePriority(decode_priority_test); +		addImageToList(tex); +	} +} +  /*   static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host)   { @@ -827,6 +885,36 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)  	return create_timer.getElapsedTimeF32();  } +F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) +{ +	if (gGLManager.mIsDisabled) return 0.0f; +	if(mFastCacheList.empty()) +	{ +		return 0.f; +	} +	 +	// +	// loading texture raw data from the fast cache directly. +	// +		 +	LLTimer timer; +	image_list_t::iterator enditer = mFastCacheList.begin(); +	for (image_list_t::iterator iter = mFastCacheList.begin(); +		 iter != mFastCacheList.end();) +	{ +		image_list_t::iterator curiter = iter++; +		enditer = iter; +		LLViewerFetchedTexture *imagep = *curiter; +		imagep->loadFromFastCache(); +		if (timer.getElapsedTimeF32() > max_time) +		{ +			break; +		} +	} +	mFastCacheList.erase(mFastCacheList.begin(), enditer); +	return timer.getElapsedTimeF32(); +} +  void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)  {  	if(!imagep) @@ -850,15 +938,24 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  {  	LLTimer image_op_timer; -	// Update the decode priority for N images each frame -	// Make a list with 32 high priority entries + 256 cycled entries -	const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); -	const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); +	// Update fetch for N images each frame +	static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority");         // default: 32 +	static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority");       // default: 256 +	static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority");       // default: 32 +	static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 +	static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority");          // default: false + +	size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); +	max_priority_count = llmin(max_priority_count, mImageList.size()); +	 +	size_t total_update_count = mUUIDMap.size(); +	size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); +	max_update_count = llmin(max_update_count, total_update_count);	 -	// 32 high priority entries +	// MAX_HIGH_PRIO_COUNT high priority entries  	typedef std::vector<LLViewerFetchedTexture*> entries_list_t;  	entries_list_t entries; -	size_t update_counter = llmin(max_priority_count, mImageList.size()); +	size_t update_counter = max_priority_count;  	image_priority_list_t::iterator iter1 = mImageList.begin();  	while(update_counter > 0)  	{ @@ -868,43 +965,46 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  		update_counter--;  	} -	// 256 cycled entries -	update_counter = llmin(max_update_count, mUUIDMap.size());	 +	// MAX_UPDATE_COUNT cycled entries +	update_counter = max_update_count;	  	if(update_counter > 0)  	{  		uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); -		uuid_map_t::iterator iter2p = iter2; -		while(update_counter > 0) +		while ((update_counter > 0) && (total_update_count > 0))  		{  			if (iter2 == mUUIDMap.end())  			{  				iter2 = mUUIDMap.begin();  			} -			entries.push_back(iter2->second); -			iter2p = iter2++; -			update_counter--; +			LLViewerFetchedTexture* imagep = iter2->second; +            // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. +            if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) +            { +                entries.push_back(imagep); +                update_counter--; +            } + +			iter2++; +			total_update_count--;  		} - -		mLastFetchUUID = iter2p->first;  	}  	S32 fetch_count = 0; -	S32 min_count = max_priority_count + max_update_count/4; +	size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); +	S32 min_count = max_priority_count + min_update_count;  	for (entries_list_t::iterator iter3 = entries.begin();  		 iter3 != entries.end(); )  	{  		LLViewerFetchedTexture* imagep = *iter3++; -		 -		bool fetching = imagep->updateFetch(); -		if (fetching) +		fetch_count += (imagep->updateFetch() ? 1 : 0); +		if (min_count <= min_update_count)  		{ -			fetch_count++; +			mLastFetchUUID = imagep->getID();  		} -		if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) +		if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))  		{  			break;  		} -		min_count--;  	}  	//if (fetch_count == 0)  	//{ @@ -936,6 +1036,9 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  {  	LLTimer timer; +	//loading from fast cache  +	updateImagesLoadingFastCache(max_time); +  	// Update texture stats and priorities  	std::vector<LLPointer<LLViewerFetchedTexture> > image_list;  	for (image_priority_list_t::iterator iter = mImageList.begin(); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e89997fe28..3dda973d3f 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -111,6 +111,7 @@ public:  	void doPrefetchImages();  	void clearFetchingRequests(); +	void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);  	static S32 getMinVideoRamSetting();  	static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -120,6 +121,7 @@ private:  	F32  updateImagesCreateTextures(F32 max_time);  	F32  updateImagesFetchTextures(F32 max_time);  	void updateImagesUpdateStats(); +	F32  updateImagesLoadingFastCache(F32 max_time);  	void addImage(LLViewerFetchedTexture *image);  	void deleteImage(LLViewerFetchedTexture *image); @@ -173,6 +175,7 @@ public:  	image_list_t mLoadingStreamList;  	image_list_t mCreateTextureList;  	image_list_t mCallbackList; +	image_list_t mFastCacheList;  	// Note: just raw pointers because they are never referenced, just compared against  	std::set<LLViewerFetchedTexture*> mDirtyTextureList; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 33dc12c473..f8502b17cb 100644..100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6665,7 +6665,7 @@ void LLVOAvatar::updateMeshTextures()  	if(!isSelf())  	{  		src_callback_list = &mCallbackTextureList ; -		paused = mLoadedCallbacksPaused ; +		paused = !isVisible();  	}  	std::vector<BOOL> is_layer_baked; @@ -7210,7 +7210,7 @@ void LLVOAvatar::onFirstTEMessageReceived()  		if(!isSelf())  		{  			src_callback_list = &mCallbackTextureList ; -			paused = mLoadedCallbacksPaused ; +			paused = !isVisible();  		}  		for (U32 i = 0; i < mBakedTextureDatas.size(); i++) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 6fb56a4c0b..6fb56a4c0b 100644..100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 98f7245f8d..d28ff3e28d 100644..100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2132,9 +2132,7 @@ LLSD LLVOAvatarSelf::metricsData()  {  	// runway - add region info  	LLSD result; -	result["id"] = getID();  	result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); -	result["is_self"] = isSelf();  	std::vector<S32> rez_counts;  	LLVOAvatar::getNearbyRezzedStats(rez_counts);  	result["nearby"] = LLSD::emptyMap(); @@ -2148,7 +2146,6 @@ LLSD LLVOAvatarSelf::metricsData()  	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();  	result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();  	result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); -	result["phases"] = getPhases().dumpPhases();  	result["startup"] = LLStartUp::getPhases().dumpPhases();  	return result; @@ -2157,7 +2154,12 @@ LLSD LLVOAvatarSelf::metricsData()  class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder  {  public: -	ViewerAppearanceChangeMetricsResponder() +	ViewerAppearanceChangeMetricsResponder( S32 expected_sequence, +											volatile const S32 & live_sequence, +											volatile bool & reporting_started): +		mExpectedSequence(expected_sequence), +		mLiveSequence(live_sequence), +		mReportingStarted(reporting_started)  	{  	} @@ -2176,14 +2178,44 @@ public:  			error(status,reason);  		}  	} + +	// virtual +	void error(U32 status_num, const std::string & reason) +	{ +	} + +	// virtual +	void result(const LLSD & content) +	{ +		if (mLiveSequence == mExpectedSequence) +		{ +			mReportingStarted = true; +		} +	} + +private: +	S32 mExpectedSequence; +	volatile const S32 & mLiveSequence; +	volatile bool & mReportingStarted;  };  void LLVOAvatarSelf::sendAppearanceChangeMetrics()  {  	// gAgentAvatarp->stopAllPhases(); +	static volatile bool reporting_started(false); +	static volatile S32 report_sequence(0);  	LLSD msg = metricsData();  	msg["message"] = "ViewerAppearanceChangeMetrics"; +	msg["session_id"] = gAgentSessionID; +	msg["agent_id"] = gAgentID; +	msg["sequence"] = report_sequence; +	msg["initial"] = !reporting_started; +	msg["break"] = false; + +	// Update sequence number +	if (S32_MAX == ++report_sequence) +		report_sequence = 0;  	LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;  	std::string	caps_url; @@ -2196,8 +2228,10 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics()  	{  		LLCurlRequest::headers_t headers;  		LLHTTPClient::post(caps_url, -							msg, -							new ViewerAppearanceChangeMetricsResponder); +						   msg, +						   new ViewerAppearanceChangeMetricsResponder(report_sequence, +																	  report_sequence, +																	  reporting_started));  	}  } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 543891ca63..543891ca63 100644..100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 5ea13ee0a6..7a2f6bc35b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -860,7 +860,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  				}  			} -			S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture +			S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture  			S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;  			if (texture_discard >= 0 && //texture has some data available @@ -1167,7 +1167,7 @@ void LLVOVolume::sculpt()  		S8 sculpt_components = 0;  		const U8* sculpt_data = NULL; -		S32 discard_level = mSculptTexture->getDiscardLevel() ; +		S32 discard_level = mSculptTexture->getCachedRawImageLevel() ;  		LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;  		S32 max_discard = mSculptTexture->getMaxDiscardLevel(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 49c4f37871..ed61ac5ca8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2526,6 +2526,31 @@ void LLPipeline::updateGL()  	}  } +void LLPipeline::clearRebuildGroups() +{ +	mGroupQ1Locked = true; +	// Iterate through all drawables on the priority build queue, +	for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); +		 iter != mGroupQ1.end(); ++iter) +	{ +		LLSpatialGroup* group = *iter; +		group->clearState(LLSpatialGroup::IN_BUILD_Q1); +	} +	mGroupQ1.clear(); +	mGroupQ1Locked = false; + +	mGroupQ2Locked = true; +	for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); +		 iter != mGroupQ2.end(); ++iter) +	{ +		LLSpatialGroup* group = *iter; +		group->clearState(LLSpatialGroup::IN_BUILD_Q2); +	}	 + +	mGroupQ2.clear(); +	mGroupQ2Locked = false; +} +  void LLPipeline::rebuildPriorityGroups()  {  	LLTimer update_timer; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 6ae482fa06..ae84c5886f 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -223,6 +223,7 @@ public:  	void updateGL();  	void rebuildPriorityGroups();  	void rebuildGroups(); +	void clearRebuildGroups();  	//calculate pixel area of given box from vantage point of given camera  	static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml index 44b6a63bca..1ea256b8b3 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -1,341 +1,428 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<floater
 - legacy_header_height="18"
 - can_minimize="false"
 - height="550"
 - layout="topleft"
 - name="TexFetchDebugger"
 - help_topic="texfetchdebugger"
 - title="Texture Fetching Debugger"
 - width="540">
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left="10"
 -   name="total_num_fetched_label"
 -   top="30"
 -   width="400">
 -    1, Total number of fetched textures: [NUM]
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_num_fetching_requests_label"
 -   top_delta="25"
 -   width="400">
 -    2, Total number of fetching requests: [NUM]
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_num_cache_hits_label"
 -   top_delta="25"
 -   width="400">
 -    3, Total number of cache hits: [NUM]
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_num_visible_tex_label"
 -   top_delta="25"
 -   width="400">
 -    4, Total number of visible textures: [NUM]
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_num_visible_tex_fetch_req_label"
 -   top_delta="25"
 -   width="450">
 -    5, Total number of visible texture fetching requests: [NUM]
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_fetched_data_label"
 -   top_delta="25"
 -   width="530">
 -    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_fetched_vis_data_label"
 -   top_delta="25"
 -   width="480">
 -    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_fetched_rendered_data_label"
 -   top_delta="25"
 -   width="530">
 -    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_time_cache_read_label"
 -   top_delta="25"
 -   width="400">
 -    9, Total time on cache readings: [TIME] seconds
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_time_cache_write_label"
 -   top_delta="25"
 -   width="400">
 -    10, Total time on cache writings: [TIME] seconds
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_time_decode_label"
 -   top_delta="25"
 -   width="400">
 -    11, Total time on decodings: [TIME] seconds
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_time_gl_label"
 -   top_delta="25"
 -   width="400">
 -    12, Total time on gl texture creation: [TIME] seconds
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_time_http_label"
 -   top_delta="25"
 -   width="400">
 -    13, Total time on HTTP fetching: [TIME] seconds
 -  </text>
 -  <text
 -   type="string"
 -   length="1"
 -   follows="left|top"
 -   height="25"
 -   layout="topleft"
 -   left_delta="0"
 -   name="total_time_fetch_label"
 -   top_delta="25"
 -   width="400">
 -    14, Total time on entire fetching: [TIME] seconds
 -  </text>
 -  <text
 -  type="string"
 -  length="1"
 -  follows="left|top"
 -  height="25"
 -  layout="topleft"
 -  left_delta="0"
 -  name="total_time_refetch_vis_cache_label"
 -  top_delta="25"
 -  width="540">
 -    15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
 -  </text>
 -  <text
 -  type="string"
 -  length="1"
 -  follows="left|top"
 -  height="25"
 -  layout="topleft"
 -  left_delta="0"
 -  name="total_time_refetch_vis_http_label"
 -  top_delta="25"
 -  width="540">
 -    16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
 -  </text>
 -  <spinner
 -     decimal_digits="2"
 -     follows="left|top"
 -     height="20"
 -     increment="0.01"
 -     initial_value="1.0"
 -     label="17, Ratio of Texel/Pixel:"
 -     label_width="130"
 -     layout="topleft"
 -     left_delta="0"
 -     max_val="10.0"
 -     min_val="0.01"
 -     name="texel_pixel_ratio"
 -     top_delta="30"
 -     width="200">
 -    <spinner.commit_callback
 -		function="TexFetchDebugger.ChangeTexelPixelRatio" />
 -  </spinner>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Start"
 -   layout="topleft"
 -   left_delta="0"
 -   name="start_btn"
 -   top_delta="30"
 -   width="70">
 -    <button.commit_callback
 -		function="TexFetchDebugger.Start" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Reset"
 -   layout="topleft"
 -   left_pad="7"
 -   name="clear_btn"
 -   top_delta="0"
 -   width="70">
 -    <button.commit_callback
 -		function="TexFetchDebugger.Clear" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Close"
 -   layout="topleft"
 -   left_pad="7"
 -   name="close_btn"
 -   top_delta="0"
 -   width="70">
 -    <button.commit_callback
 -		function="TexFetchDebugger.Close" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Cache Read"
 -   layout="topleft"
 -   left="10"
 -   name="cacheread_btn"
 -   top_delta="30"
 -   width="80">
 -    <button.commit_callback
 -		function="TexFetchDebugger.CacheRead" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Cache Write"
 -   layout="topleft"
 -   left_pad="7"
 -   name="cachewrite_btn"
 -   top_delta="0"
 -   width="80">
 -    <button.commit_callback
 -		function="TexFetchDebugger.CacheWrite" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="HTTP"
 -   layout="topleft"
 -   left_pad="7"
 -   name="http_btn"
 -   top_delta="0"
 -   width="70">
 -    <button.commit_callback
 -		function="TexFetchDebugger.HTTPLoad" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Decode"
 -   layout="topleft"
 -   left_pad="7"
 -   name="decode_btn"
 -   top_delta="0"
 -   width="70">
 -    <button.commit_callback
 -		function="TexFetchDebugger.Decode" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="GL Texture"
 -   layout="topleft"
 -   left_pad="7"
 -   name="gl_btn"
 -   top_delta="0"
 -   width="70">
 -    <button.commit_callback
 -		function="TexFetchDebugger.GLTexture" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Refetch Vis Cache"
 -   layout="topleft"
 -   left="10"
 -   name="refetchviscache_btn"
 -   top_delta="30"
 -   width="120">
 -    <button.commit_callback
 -		function="TexFetchDebugger.RefetchVisCache" />
 -  </button>
 -  <button
 -   follows="left|top"
 -   height="20"
 -   label="Refetch Vis HTTP"
 -   layout="topleft"
 -   left_pad="7"
 -   name="refetchvishttp_btn"
 -   top_delta="0"
 -   width="120">
 -    <button.commit_callback
 -		function="TexFetchDebugger.RefetchVisHTTP" />
 -  </button>
 -</floater>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_minimize="false" + height="600" + layout="topleft" + name="TexFetchDebugger" + help_topic="texfetchdebugger" + title="Texture Fetching Debugger" + width="540"> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left="10" +   name="total_num_fetched_label" +   top="30" +   width="400"> +    1, Total number of fetched textures: [NUM] +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_num_fetching_requests_label" +   top_delta="25" +   width="400"> +    2, Total number of fetching requests: [NUM] +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_num_cache_hits_label" +   top_delta="25" +   width="400"> +    3, Total number of cache hits: [NUM] +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_num_visible_tex_label" +   top_delta="25" +   width="400"> +    4, Total number of visible textures: [NUM] +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_num_visible_tex_fetch_req_label" +   top_delta="25" +   width="450"> +    5, Total number of visible texture fetching requests: [NUM] +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_fetched_data_label" +   top_delta="25" +   width="530"> +    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_fetched_vis_data_label" +   top_delta="25" +   width="480"> +    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_fetched_rendered_data_label" +   top_delta="25" +   width="530"> +    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_time_cache_read_label" +   top_delta="25" +   width="400"> +    9, Total time on cache readings: [TIME] seconds +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_time_cache_write_label" +   top_delta="25" +   width="400"> +    10, Total time on cache writings: [TIME] seconds +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_time_decode_label" +   top_delta="25" +   width="400"> +    11, Total time on decodings: [TIME] seconds +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_time_gl_label" +   top_delta="25" +   width="400"> +    12, Total time on gl texture creation: [TIME] seconds +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_time_http_label" +   top_delta="25" +   width="400"> +    13, Total time on HTTP fetching: [TIME] seconds +  </text> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="25" +   layout="topleft" +   left_delta="0" +   name="total_time_fetch_label" +   top_delta="25" +   width="400"> +    14, Total time on entire fetching: [TIME] seconds +  </text> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="total_time_refetch_vis_cache_label" +  top_delta="25" +  width="540"> +    15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +  </text> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="total_time_refetch_all_cache_label" +  top_delta="25" +  width="540"> +    16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +  </text> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="total_time_refetch_vis_http_label" +  top_delta="25" +  width="540"> +    17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +  </text> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="total_time_refetch_all_http_label" +  top_delta="25" +  width="540"> +    18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +  </text> +  <spinner +     decimal_digits="2" +     follows="left|top" +     height="20" +     increment="0.01" +     initial_value="1.0" +     label="19, Ratio of Texel/Pixel:" +     label_width="130" +     layout="topleft" +     left_delta="0" +     max_val="10.0" +     min_val="0.01" +     name="texel_pixel_ratio" +     top_delta="30" +     width="200"> +    <spinner.commit_callback +		function="TexFetchDebugger.ChangeTexelPixelRatio" /> +  </spinner> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="texture_source_label" +  top_delta="30" +  width="110"> +    20, Texture Source: +  </text> +  <radio_group +     control_name="TextureFetchSource" +     follows="top|left" +     draw_border="false" +     height="25" +     layout="topleft" +     left_pad="0" +     name="texture_source" +     top_delta="0" +     width="264"> +    <radio_item +     height="16" +     label="Cache + HTTP" +     layout="topleft" +     left="3" +     name="0" +     top="0" +     width="100" /> +    <radio_item +     height="16" +     label="HTTP Only" +     layout="topleft" +     left_delta="100" +     name="1" +     top_delta="0" +     width="200" /> +  </radio_group> +  <button +   follows="left|top" +   height="20" +   label="Start" +   layout="topleft" +   left="10" +   name="start_btn" +   top_delta="20" +   width="70"> +    <button.commit_callback +		function="TexFetchDebugger.Start" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Reset" +   layout="topleft" +   left_pad="7" +   name="clear_btn" +   top_delta="0" +   width="70"> +    <button.commit_callback +		function="TexFetchDebugger.Clear" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Close" +   layout="topleft" +   left_pad="7" +   name="close_btn" +   top_delta="0" +   width="70"> +    <button.commit_callback +		function="TexFetchDebugger.Close" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Cache Read" +   layout="topleft" +   left="10" +   name="cacheread_btn" +   top_delta="20" +   width="80"> +    <button.commit_callback +		function="TexFetchDebugger.CacheRead" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Cache Write" +   layout="topleft" +   left_pad="7" +   name="cachewrite_btn" +   top_delta="0" +   width="80"> +    <button.commit_callback +		function="TexFetchDebugger.CacheWrite" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="HTTP" +   layout="topleft" +   left_pad="7" +   name="http_btn" +   top_delta="0" +   width="70"> +    <button.commit_callback +		function="TexFetchDebugger.HTTPLoad" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Decode" +   layout="topleft" +   left_pad="7" +   name="decode_btn" +   top_delta="0" +   width="70"> +    <button.commit_callback +		function="TexFetchDebugger.Decode" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="GL Texture" +   layout="topleft" +   left_pad="7" +   name="gl_btn" +   top_delta="0" +   width="70"> +    <button.commit_callback +		function="TexFetchDebugger.GLTexture" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Refetch Vis Cache" +   layout="topleft" +   left="10" +   name="refetchviscache_btn" +   top_delta="20" +   width="120"> +    <button.commit_callback +		function="TexFetchDebugger.RefetchVisCache" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Refetch All Cache" +   layout="topleft" +   left_pad="7" +   name="refetchallcache_btn" +   top_delta="0" +   width="120"> +    <button.commit_callback +		function="TexFetchDebugger.RefetchAllCache" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Refetch Vis HTTP" +   layout="topleft" +   left_pad="7" +   name="refetchvishttp_btn" +   top_delta="0" +   width="120"> +    <button.commit_callback +		function="TexFetchDebugger.RefetchVisHTTP" /> +  </button> +  <button +   follows="left|top" +   height="20" +   label="Refetch All HTTP" +   layout="topleft" +   left_pad="7" +   name="refetchallhttp_btn" +   top_delta="0" +   width="120"> +    <button.commit_callback +		function="TexFetchDebugger.RefetchAllHTTP" /> +  </button> +</floater> diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index f8923b9868..f8923b9868 100644..100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp | 
