diff options
97 files changed, 1377 insertions, 762 deletions
| diff --git a/autobuild.xml b/autobuild.xml index 66b3093e11..e290b9dafc 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1561,7 +1561,7 @@            </map>          </map>          <key>version</key> -        <string>1.5.1.310043</string> +        <string>1.5.3.311349</string>        </map>        <key>llphysicsextensions_source</key>        <map> diff --git a/doc/contributions.txt b/doc/contributions.txt index e1e5b4c368..04586d4779 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -781,6 +781,12 @@ Kitty Barnett      VWR-24217  	STORM-1804  	MAINT-5416 +	MAINT-6041 +	MAINT-6142 +	MAINT-6144 +	MAINT-6152 +	MAINT-6153 +	MAINT-6154  Kolor Fall  Komiko Okamoto  Korvel Noh @@ -999,6 +1005,7 @@ NickyD  	MAINT-873  Nicky Dasmijn  	VWR-29228 +	MAINT-1392  	MAINT-873  	SUN-72  	BUG-2432 @@ -1252,6 +1259,7 @@ Sovereign Engineer      OPEN-195      OPEN-217      OPEN-295 +    MAINT-6107      STORM-2107  SpacedOut Frye  	VWR-34 diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index 2d88e2c676..d342dece84 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -36,10 +36,18 @@ StringVec sv(const StringVec& listof) { return listof; }  #if defined(LL_WINDOWS)  #define sleep(secs) _sleep((secs) * 1000) -#endif +// WOLF-300: It appears that driving a megabyte of data through an LLLeap pipe +// causes Windows abdominal pain such that it later fails code-signing in some +// mysterious way. Entirely suppressing these LLLeap tests pushes the failure +// rate MUCH lower. Can we re-enable them with a smaller data size on Windows? +const size_t BUFFERED_LENGTH =  100*1024; + +#else // not Windows  const size_t BUFFERED_LENGTH = 1023*1024; // try wrangling just under a megabyte of data +#endif +  void waitfor(const std::vector<LLLeap*>& instances, int timeout=60)  {      int i; diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 61663e1982..cab3073eca 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -158,28 +158,49 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )  }  ///---------------------------------------------------------------------------- +/// LLBaseDownloadRequest +///---------------------------------------------------------------------------- + +LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type) +: mUUID(uuid), +mType(type), +mDownCallback(NULL), +mUserData(NULL), +mHost(), +mIsTemp(FALSE), +mIsPriority(FALSE), +mDataSentInFirstPacket(FALSE), +mDataIsInVFS(FALSE) +{ +    // Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been +    //  running a message system loop. +    mTime = LLMessageSystem::getMessageTimeSeconds(TRUE); +} + +// virtual +LLBaseDownloadRequest::~LLBaseDownloadRequest() +{ +} + +// virtual +LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy() +{ +    return new LLBaseDownloadRequest(*this); +} + + +///----------------------------------------------------------------------------  /// LLAssetRequest  ///----------------------------------------------------------------------------  LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type) -:	mUUID(uuid), -	mType(type), -	mDownCallback( NULL ), +:	LLBaseDownloadRequest(uuid, type),  	mUpCallback( NULL ),  	mInfoCallback( NULL ), -	mUserData( NULL ), -	mHost(), -	mIsTemp( FALSE ),  	mIsLocal(FALSE),  	mIsUserWaiting(FALSE), -	mTimeout(LL_ASSET_STORAGE_TIMEOUT), -	mIsPriority(FALSE), -	mDataSentInFirstPacket(FALSE), -	mDataIsInVFS( FALSE ) +	mTimeout(LL_ASSET_STORAGE_TIMEOUT)  { -	// Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been -	//  running a message system loop. -	mTime = LLMessageSystem::getMessageTimeSeconds(TRUE);  }  // virtual @@ -217,56 +238,51 @@ LLSD LLAssetRequest::getFullDetails() const  	return sd;  } +LLBaseDownloadRequest* LLAssetRequest::getCopy() +{ +    return new LLAssetRequest(*this); +} +  ///----------------------------------------------------------------------------  /// LLInvItemRequest  ///----------------------------------------------------------------------------  LLInvItemRequest::LLInvItemRequest(const LLUUID &uuid, const LLAssetType::EType type) -:	mUUID(uuid), -	mType(type), -	mDownCallback( NULL ), -	mUserData( NULL ), -	mHost(), -	mIsTemp( FALSE ), -	mIsPriority(FALSE), -	mDataSentInFirstPacket(FALSE), -	mDataIsInVFS( FALSE ) +:	LLBaseDownloadRequest(uuid, type)  { -	// Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been -	//  running a message system loop. -	mTime = LLMessageSystem::getMessageTimeSeconds(TRUE);  } +// virtual  LLInvItemRequest::~LLInvItemRequest()  {  } +LLBaseDownloadRequest* LLInvItemRequest::getCopy() +{ +    return new LLInvItemRequest(*this); +} +  ///----------------------------------------------------------------------------  /// LLEstateAssetRequest  ///----------------------------------------------------------------------------  LLEstateAssetRequest::LLEstateAssetRequest(const LLUUID &uuid, const LLAssetType::EType atype,  										   EstateAssetType etype) -:	mUUID(uuid), -	mAType(atype), -	mEstateAssetType(etype), -	mDownCallback( NULL ), -	mUserData( NULL ), -	mHost(), -	mIsTemp( FALSE ), -	mIsPriority(FALSE), -	mDataSentInFirstPacket(FALSE), -	mDataIsInVFS( FALSE ) -{ -	// Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been -	//  running a message system loop. -	mTime = LLMessageSystem::getMessageTimeSeconds(TRUE); +:	LLBaseDownloadRequest(uuid, atype), +	mEstateAssetType(etype) +{  } +// Virtual  LLEstateAssetRequest::~LLEstateAssetRequest()  {  } +LLBaseDownloadRequest* LLEstateAssetRequest::getCopy() +{ +    return new LLEstateAssetRequest(*this); +} +  ///----------------------------------------------------------------------------  /// LLAssetStorage @@ -565,7 +581,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at  			// Set our destination file, and the completion callback.  			LLTransferTargetParamsVFile tpvf;  			tpvf.setAsset(uuid, atype); -			tpvf.setCallback(downloadCompleteCallback, req); +			tpvf.setCallback(downloadCompleteCallback, *req);  			//LL_INFOS() << "Starting transfer for " << uuid << LL_ENDL;  			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); @@ -589,7 +605,7 @@ void LLAssetStorage::downloadCompleteCallback(  	S32 result,  	const LLUUID& file_id,  	LLAssetType::EType file_type, -	void* user_data, LLExtStat ext_status) +	LLBaseDownloadRequest* user_data, LLExtStat ext_status)  {  	LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << LL_ENDL; @@ -608,36 +624,40 @@ void LLAssetStorage::downloadCompleteCallback(  		return;  	} +	LLUUID callback_id; +	LLAssetType::EType callback_type; +  	// Inefficient since we're doing a find through a list that may have thousands of elements.  	// This is due for refactoring; we will probably change mPendingDownloads into a set.  	request_list_t::iterator download_iter = std::find(gAssetStorage->mPendingDownloads.begin(),   													   gAssetStorage->mPendingDownloads.end(),  													   req); -	// If the LLAssetRequest doesn't exist in the downloads queue, then it either has already been deleted -	// by _cleanupRequests, or it's a transfer. +  	if (download_iter != gAssetStorage->mPendingDownloads.end())  	{ -		req->setUUID(file_id); -		req->setType(file_type); +		callback_id = file_id; +		callback_type = file_type; +	} +	else +	{ +		// either has already been deleted by _cleanupRequests or it's a transfer. +		callback_id = req->getUUID(); +		callback_type = req->getType();  	}  	if (LL_ERR_NOERR == result)  	{  		// we might have gotten a zero-size file -		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType()); +		LLVFile vfile(gAssetStorage->mVFS, callback_id, callback_type);  		if (vfile.getSize() <= 0)  		{ -			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset " << req->getUUID() << LL_ENDL; +			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL;  			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;  			vfile.remove();  		}  	} -	// we will be deleting elements of mPendingDownloads which req might be part of, save id and type for reference -	LLUUID callback_id = req->getUUID(); -	LLAssetType::EType callback_type = req->getType(); -	  	// find and callback ALL pending requests for this UUID  	// SJB: We process the callbacks in reverse order, I do not know if this is important,  	//      but I didn't want to mess with it. @@ -731,10 +751,10 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen  		if (source_host.isOk())  		{  			// stash the callback info so we can find it after we get the response message -			LLEstateAssetRequest *req = new LLEstateAssetRequest(asset_id, atype, etype); -			req->mDownCallback = callback; -			req->mUserData = user_data; -			req->mIsPriority = is_priority; +			LLEstateAssetRequest req(asset_id, atype, etype); +			req.mDownCallback = callback; +			req.mUserData = user_data; +			req.mIsPriority = is_priority;  			// send request message to our upstream data provider  			// Create a new asset transfer. @@ -768,7 +788,7 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(  	S32 result,  	const LLUUID& file_id,  	LLAssetType::EType file_type, -	void* user_data, +	LLBaseDownloadRequest* user_data,  	LLExtStat ext_status)  {  	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data; @@ -875,10 +895,10 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age  		if (source_host.isOk())  		{  			// stash the callback info so we can find it after we get the response message -			LLInvItemRequest *req = new LLInvItemRequest(asset_id, atype); -			req->mDownCallback = callback; -			req->mUserData = user_data; -			req->mIsPriority = is_priority; +			LLInvItemRequest req(asset_id, atype); +			req.mDownCallback = callback; +			req.mUserData = user_data; +			req.mIsPriority = is_priority;  			// send request message to our upstream data provider  			// Create a new asset transfer. @@ -916,7 +936,7 @@ void LLAssetStorage::downloadInvItemCompleteCallback(  	S32 result,  	const LLUUID& file_id,  	LLAssetType::EType file_type, -	void* user_data, +	LLBaseDownloadRequest* user_data,  	LLExtStat ext_status)  {  	LLInvItemRequest *req = (LLInvItemRequest*)user_data; diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 1bb4acea9e..8a4d41565f 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -92,38 +92,52 @@ public:  }; -class LLAssetRequest +class LLBaseDownloadRequest  {  public: -	LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType at); -	virtual ~LLAssetRequest(); -	 -	LLUUID getUUID() const					{ return mUUID; } -	LLAssetType::EType getType() const		{ return mType; } +    LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType at); +    virtual ~LLBaseDownloadRequest(); + +    LLUUID getUUID() const					{ return mUUID; } +    LLAssetType::EType getType() const		{ return mType; } + +    void setUUID(const LLUUID& id) { mUUID = id; } +    void setType(LLAssetType::EType type) { mType = type; } -	void setUUID(const LLUUID& id) { mUUID = id; } -	void setType(LLAssetType::EType type) { mType = type; } -	void setTimeout (F64Seconds timeout) { mTimeout = timeout; } +    virtual LLBaseDownloadRequest* getCopy();  protected: -	LLUUID	mUUID; -	LLAssetType::EType mType; +    LLUUID	mUUID; +    LLAssetType::EType mType; + +public: +    void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat); + +    void	*mUserData; +    LLHost  mHost; +    BOOL	mIsTemp; +    F64Seconds		mTime;				// Message system time +    BOOL    mIsPriority; +    BOOL	mDataSentInFirstPacket; +    BOOL	mDataIsInVFS; +}; +class LLAssetRequest : public LLBaseDownloadRequest +{  public: -	void	(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat); +    LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType at); +    virtual ~LLAssetRequest(); + +    void setTimeout(F64Seconds timeout) { mTimeout = timeout; } + +    virtual LLBaseDownloadRequest* getCopy(); +  	void	(*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);  	void	(*mInfoCallback)(LLAssetInfo *, void *, S32); -	void	*mUserData; -	LLHost  mHost; -	BOOL	mIsTemp;  	BOOL	mIsLocal;  	BOOL	mIsUserWaiting;		// We don't want to try forever if a user is waiting for a result. -	F64Seconds		mTime;				// Message system time  	F64Seconds		mTimeout;			// Amount of time before timing out. -	BOOL    mIsPriority; -	BOOL	mDataSentInFirstPacket; -	BOOL	mDataIsInVFS;  	LLUUID	mRequestingAgentID;	// Only valid for uploads from an agent  	virtual LLSD getTerseDetails() const; @@ -141,63 +155,27 @@ struct ll_asset_request_equal : public std::equal_to<T>  }; -class LLInvItemRequest +class LLInvItemRequest : public LLBaseDownloadRequest  {  public: -	LLInvItemRequest(const LLUUID &uuid, const LLAssetType::EType at); -	virtual ~LLInvItemRequest(); - -	LLUUID getUUID() const					{ return mUUID; } -	LLAssetType::EType getType() const		{ return mType; } - -	void setUUID(const LLUUID& id) { mUUID = id; } -	void setType(LLAssetType::EType type) { mType = type; } - -protected: -	LLUUID	mUUID; -	LLAssetType::EType mType; - -public: -	void	(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat); - -	void	*mUserData; -	LLHost  mHost; -	BOOL	mIsTemp; -	F64Seconds	mTime;				// Message system time -	BOOL    mIsPriority; -	BOOL	mDataSentInFirstPacket; -	BOOL	mDataIsInVFS; +    LLInvItemRequest(const LLUUID &uuid, const LLAssetType::EType at); +    virtual ~LLInvItemRequest(); +    virtual LLBaseDownloadRequest* getCopy();  }; -class LLEstateAssetRequest +class LLEstateAssetRequest : public LLBaseDownloadRequest  {  public: -	LLEstateAssetRequest(const LLUUID &uuid, const LLAssetType::EType at, EstateAssetType et); -	virtual ~LLEstateAssetRequest(); +    LLEstateAssetRequest(const LLUUID &uuid, const LLAssetType::EType at, EstateAssetType et); +    virtual ~LLEstateAssetRequest(); -	LLUUID getUUID() const					{ return mUUID; } -	LLAssetType::EType getAType() const		{ return mAType; } +    LLAssetType::EType getAType() const		{ return mType; } -	void setUUID(const LLUUID& id) { mUUID = id; } -	void setType(LLAssetType::EType type) { mAType = type; } +    virtual LLBaseDownloadRequest* getCopy();  protected: -	LLUUID	mUUID; -	LLAssetType::EType mAType;  	EstateAssetType mEstateAssetType; - -public: -	void	(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat); - -	void	*mUserData; -	LLHost  mHost; -	BOOL	mIsTemp; -	F64Seconds	mTime;				// Message system time -	BOOL    mIsPriority; -	BOOL	mDataSentInFirstPacket; -	BOOL	mDataIsInVFS; -  }; @@ -369,17 +347,17 @@ public:  		S32 result,  		const LLUUID& file_id,  		LLAssetType::EType file_type, -		void* user_data, LLExtStat ext_status); +		LLBaseDownloadRequest* user_data, LLExtStat ext_status);  	static void downloadEstateAssetCompleteCallback(  		S32 result,  		const LLUUID& file_id,  		LLAssetType::EType file_type, -		void* user_data, LLExtStat ext_status); +		LLBaseDownloadRequest* user_data, LLExtStat ext_status);  	static void downloadInvItemCompleteCallback(  		S32 result,  		const LLUUID& file_id,  		LLAssetType::EType file_type, -		void* user_data, LLExtStat ext_status); +		LLBaseDownloadRequest* user_data, LLExtStat ext_status);  	// upload process callbacks  	static void uploadCompleteCallback(const LLUUID&, void *user_data, S32 result, LLExtStat ext_status); diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index e202154445..ace65760c3 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -938,22 +938,22 @@ void LLHTTPAssetStorage::checkForTimeouts()  			long curl_result = 0;  			S32 xfer_result = LL_ERR_NOERR; -			LLHTTPAssetRequest *req = NULL; -			curl_easy_getinfo(curl_msg->easy_handle, CURLINFO_PRIVATE, &req); +			LLHTTPAssetRequest *http_req = NULL; +			curl_easy_getinfo(curl_msg->easy_handle, CURLINFO_PRIVATE, &http_req);  			// TODO: Throw curl_result at all callbacks.  			curl_easy_getinfo(curl_msg->easy_handle, CURLINFO_HTTP_CODE, &curl_result); -			if (RT_UPLOAD == req->mRequestType || RT_LOCALUPLOAD == req->mRequestType) +			if (RT_UPLOAD == http_req->mRequestType || RT_LOCALUPLOAD == http_req->mRequestType)  			{  				if (curl_msg->data.result == CURLE_OK &&   					(   curl_result == HTTP_OK   					 || curl_result == HTTP_CREATED  					 || curl_result == HTTP_NO_CONTENT))  				{ -					LL_INFOS() << "Success uploading " << req->getUUID() << " to " << req->mURLBuffer << LL_ENDL; -					if (RT_LOCALUPLOAD == req->mRequestType) +					LL_INFOS() << "Success uploading " << http_req->getUUID() << " to " << http_req->mURLBuffer << LL_ENDL; +					if (RT_LOCALUPLOAD == http_req->mRequestType)  					{ -						addTempAssetData(req->getUUID(), req->mRequestingAgentID, mHostName); +						addTempAssetData(http_req->getUUID(), http_req->mRequestingAgentID, mHostName);  					}  				}  				else if (curl_msg->data.result == CURLE_COULDNT_CONNECT || @@ -961,18 +961,18 @@ void LLHTTPAssetStorage::checkForTimeouts()  						curl_result == HTTP_BAD_GATEWAY ||  						curl_result == HTTP_SERVICE_UNAVAILABLE)  				{ -					LL_WARNS() << "Re-requesting upload for " << req->getUUID() << ".  Received upload error to " << req->mURLBuffer << +					LL_WARNS() << "Re-requesting upload for " << http_req->getUUID() << ".  Received upload error to " << http_req->mURLBuffer <<  						" with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << LL_ENDL;  					////HACK (probably) I am sick of this getting requeued and driving me mad. -					//if (req->mIsUserWaiting) +					//if (http_req->mIsUserWaiting)  					//{ -					//	deletePendingRequest(RT_UPLOAD, req->getType(), req->getUUID()); +					//	deletePendingRequest(RT_UPLOAD, http_req->getType(), http_req->getUUID());  					//}  				}  				else  				{ -					LL_WARNS() << "Failure uploading " << req->getUUID() << " to " << req->mURLBuffer << +					LL_WARNS() << "Failure uploading " << http_req->getUUID() << " to " << http_req->mURLBuffer <<  						" with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << LL_ENDL;  					xfer_result = LL_ERR_ASSET_REQUEST_FAILED; @@ -985,39 +985,39 @@ void LLHTTPAssetStorage::checkForTimeouts()  				{  					// shared upload finished callback  					// in the base class, this is called from processUploadComplete -					_callUploadCallbacks(req->getUUID(), req->getType(), (xfer_result == 0), LL_EXSTAT_CURL_RESULT | curl_result); +					_callUploadCallbacks(http_req->getUUID(), http_req->getType(), (xfer_result == 0), LL_EXSTAT_CURL_RESULT | curl_result);  					// Pending upload flag will get cleared when the request is deleted  				}  			} -			else if (RT_DOWNLOAD == req->mRequestType) +			else if (RT_DOWNLOAD == http_req->mRequestType)  			{  				if (curl_result == HTTP_OK && curl_msg->data.result == CURLE_OK)  				{ -					if (req->mVFile && req->mVFile->getSize() > 0) +					if (http_req->mVFile && http_req->mVFile->getSize() > 0)  					{					 -						LL_INFOS() << "Success downloading " << req->mURLBuffer << ", size " << req->mVFile->getSize() << LL_ENDL; +						LL_INFOS() << "Success downloading " << http_req->mURLBuffer << ", size " << http_req->mVFile->getSize() << LL_ENDL; -						req->mVFile->rename(req->getUUID(), req->getType()); +						http_req->mVFile->rename(http_req->getUUID(), http_req->getType());  					}  					else  					{  						// *TODO: if this actually indicates a bad asset on the server  						// (not certain at this point), then delete it -						LL_WARNS() << "Found " << req->mURLBuffer << " to be zero size" << LL_ENDL; +						LL_WARNS() << "Found " << http_req->mURLBuffer << " to be zero size" << LL_ENDL;  						xfer_result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;  					}  				}  				else  				{  					// KLW - TAT See if an avatar owns this texture, and if so request re-upload. -					LL_WARNS() << "Failure downloading " << req->mURLBuffer <<  +					LL_WARNS() << "Failure downloading " << http_req->mURLBuffer <<   						" with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << LL_ENDL;  					xfer_result = (curl_result == HTTP_NOT_FOUND) ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED; -					if (req->mVFile) +					if (http_req->mVFile)  					{ -						req->mVFile->remove(); +						http_req->mVFile->remove();  					}  				} @@ -1025,9 +1025,9 @@ void LLHTTPAssetStorage::checkForTimeouts()  				// this will cleanup all requests for this asset, including ours  				downloadCompleteCallback(  					xfer_result, -					req->getUUID(), -					req->getType(), -					(void *)req, +					http_req->getUUID(), +					http_req->getType(), +					http_req,  					LL_EXSTAT_CURL_RESULT | curl_result);  				// Pending download flag will get cleared when the request is deleted  			} @@ -1038,8 +1038,8 @@ void LLHTTPAssetStorage::checkForTimeouts()  			}  			// Deleting clears the pending upload/download flag if it's set and the request is transferring -			delete req; -			req = NULL; +			delete http_req; +			http_req = NULL;  		}  	} while (curl_msg && queue_length > 0); diff --git a/indra/llmessage/lltransfertargetvfile.cpp b/indra/llmessage/lltransfertargetvfile.cpp index 3c234b9726..a572c68a7f 100644 --- a/indra/llmessage/lltransfertargetvfile.cpp +++ b/indra/llmessage/lltransfertargetvfile.cpp @@ -42,7 +42,7 @@ LLTransferTargetParamsVFile::LLTransferTargetParamsVFile() :  	LLTransferTargetParams(LLTTT_VFILE),  	mAssetType(LLAssetType::AT_NONE),  	mCompleteCallback(NULL), -	mUserDatap(NULL), +	mRequestDatap(NULL),  	mErrCode(0)  {  } @@ -55,10 +55,14 @@ void LLTransferTargetParamsVFile::setAsset(  	mAssetType = asset_type;  } -void LLTransferTargetParamsVFile::setCallback(LLTTVFCompleteCallback cb, void *user_data) +void LLTransferTargetParamsVFile::setCallback(LLTTVFCompleteCallback cb, LLBaseDownloadRequest& request)  {  	mCompleteCallback = cb; -	mUserDatap = user_data; +    if (mRequestDatap) +    { +        delete mRequestDatap; +    } +	mRequestDatap = request.getCopy();  }  bool LLTransferTargetParamsVFile::unpackParams(LLDataPacker& dp) @@ -98,6 +102,12 @@ LLTransferTargetVFile::LLTransferTargetVFile(  LLTransferTargetVFile::~LLTransferTargetVFile()  { +    if (mParams.mRequestDatap) +    { +        // TODO: Consider doing it in LLTransferTargetParamsVFile's destructor +        delete mParams.mRequestDatap; +        mParams.mRequestDatap = NULL; +    }  } @@ -208,12 +218,18 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status)  		err_code = LL_ERR_ASSET_REQUEST_FAILED;  		break;  	} -	if (mParams.mCompleteCallback) -	{ -		mParams.mCompleteCallback(err_code, -								  mParams.getAssetID(), -								  mParams.getAssetType(), -								  mParams.mUserDatap, -								  LL_EXSTAT_NONE); -	} + +    if (mParams.mRequestDatap) +    { +        if (mParams.mCompleteCallback) +        { +            mParams.mCompleteCallback(err_code, +                mParams.getAssetID(), +                mParams.getAssetType(), +                mParams.mRequestDatap, +                LL_EXSTAT_NONE); +        } +        delete mParams.mRequestDatap; +        mParams.mRequestDatap = NULL; +    }  } diff --git a/indra/llmessage/lltransfertargetvfile.h b/indra/llmessage/lltransfertargetvfile.h index 23a65e4bb2..c819c1e2f2 100644 --- a/indra/llmessage/lltransfertargetvfile.h +++ b/indra/llmessage/lltransfertargetvfile.h @@ -39,7 +39,7 @@ typedef void (*LLTTVFCompleteCallback)(  	S32 status,  	const LLUUID& file_id,  	LLAssetType::EType file_type, -	void* user_data, LLExtStat ext_status ); +	LLBaseDownloadRequest* user_data, LLExtStat ext_status );  class LLTransferTargetParamsVFile : public LLTransferTargetParams  { @@ -47,7 +47,7 @@ public:  	LLTransferTargetParamsVFile();  	void setAsset(const LLUUID& asset_id, LLAssetType::EType asset_type); -	void setCallback(LLTTVFCompleteCallback cb, void* user_data); +	void setCallback(LLTTVFCompleteCallback cb, LLBaseDownloadRequest& request);  	LLUUID getAssetID() const						{ return mAssetID; }  	LLAssetType::EType getAssetType() const			{ return mAssetType; } @@ -60,7 +60,7 @@ protected:  	LLAssetType::EType	mAssetType;  	LLTTVFCompleteCallback	mCompleteCallback; -	void*					mUserDatap; +	LLBaseDownloadRequest*	mRequestDatap;  	S32						mErrCode;  }; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index afc88fc861..720986a411 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -62,6 +62,9 @@  #include "glh/glh_linear.h"  #include "llmatrix4a.h" +#include <boost/regex.hpp> +#include <boost/algorithm/string/replace.hpp> +  std::string colladaVersion[VERSIONTYPE_COUNT+1] =   {  	"1.4.0", @@ -236,7 +239,10 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  					// Don't share verts within the same tri, degenerate  					// -					if ((indices.size() % 3) && (indices[indices.size()-1] != shared_index)) +                    U32 indx_size = indices.size(); +                    U32 verts_new_tri = indx_size % 3; +                    if ((verts_new_tri < 1 || indices[indx_size - 1] != shared_index) +                        && (verts_new_tri < 2 || indices[indx_size - 2] != shared_index))  					{  						found = true;  						indices.push_back(shared_index); @@ -810,7 +816,8 @@ LLDAELoader::LLDAELoader(  	void*						opaque_userdata,  	JointTransformMap&	jointMap,  	JointSet&				jointsFromNodes, -	U32					modelLimit) +	U32					modelLimit, +	bool					preprocess)  : LLModelLoader(  		filename,  		lod, @@ -822,7 +829,7 @@ LLDAELoader::LLDAELoader(  		jointMap,  		jointsFromNodes),  mGeneratedModelLimit(modelLimit), -mForceIdNaming(false) +mPreprocessDAE(preprocess)  {  } @@ -846,7 +853,16 @@ bool LLDAELoader::OpenFile(const std::string& filename)  {  	//no suitable slm exists, load from the .dae file  	DAE dae; -	domCOLLADA* dom = dae.open(filename); +	domCOLLADA* dom; +	if (mPreprocessDAE) +	{ +		dom = dae.openFromMemory(filename, preprocessDAE(filename).c_str()); +	} +	else +	{ +		LL_INFOS() << "Skipping dae preprocessing" << LL_ENDL; +		dom = dae.open(filename); +	}  	if (!dom)  	{ @@ -874,7 +890,7 @@ bool LLDAELoader::OpenFile(const std::string& filename)  	daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); -	daeDocument* doc = dae.getDoc(mFilename); +	daeDocument* doc = dae.getDoc(filename);  	if (!doc)  	{  		LL_WARNS() << "can't find internal doc" << LL_ENDL; @@ -945,32 +961,6 @@ bool LLDAELoader::OpenFile(const std::string& filename)  	mTransform.condition();	 -	mForceIdNaming = false; -	std::vector<std::string> checkNames; -	for (daeInt idx = 0; idx < count; ++idx) -	{ -		domMesh* mesh = NULL; -		db->getElement((daeElement**)&mesh, idx, NULL, COLLADA_TYPE_MESH); - -		if (mesh) -		{ -			std::string name = getLodlessLabel(mesh, false); - -			std::vector<std::string>::iterator it; -			it = std::find(checkNames.begin(), checkNames.end(), name); -			if (it != checkNames.end()) -			{ -				LL_WARNS() << "document has duplicate names, using IDs instead" << LL_ENDL; -				mForceIdNaming = true; -				break; -			} -			else -			{ -				checkNames.push_back(name); -			} -		} -	} -	  	U32 submodel_limit = count > 0 ? mGeneratedModelLimit/count : 0;  	for (daeInt idx = 0; idx < count; ++idx)  	{ //build map of domEntities to LLModel @@ -1078,6 +1068,41 @@ bool LLDAELoader::OpenFile(const std::string& filename)  	return true;  } +std::string LLDAELoader::preprocessDAE(std::string filename) +{ +	// Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678 +	std::ifstream inFile; +	inFile.open(filename.c_str(), std::ios_base::in); +	std::stringstream strStream; +	strStream << inFile.rdbuf(); +	std::string buffer = strStream.str(); + +	LL_INFOS() << "Preprocessing dae file to remove spaces from the names, ids, etc." << LL_ENDL; + +	try +	{ +		boost::regex re("\"[\\w\\.@#$-]*(\\s[\\w\\.@#$-]*)+\""); +		boost::sregex_iterator next(buffer.begin(), buffer.end(), re); +		boost::sregex_iterator end; +		while (next != end) +		{ +			boost::smatch match = *next; +			std::string s = match.str(); +			LL_INFOS() << s << " found" << LL_ENDL; +			boost::replace_all(s, " ", "_"); +			LL_INFOS() << "Replacing with " << s << LL_ENDL; +			boost::replace_all(buffer, match.str(), s); +			next++; +		} +	} +	catch (boost::regex_error &) +	{ +		LL_INFOS() << "Regex error" << LL_ENDL; +	} + +	return buffer; +} +  void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, domMesh* mesh, domSkin* skin)  {  	llassert(model && dae && mesh && skin); @@ -1971,7 +1996,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da  					if (model->mLabel.empty())  					{ -						label = getLodlessLabel(instance_geo, mForceIdNaming); +						label = getLodlessLabel(instance_geo);  						llassert(!label.empty()); @@ -2186,17 +2211,12 @@ LLImportMaterial LLDAELoader::profileToMaterial(domProfile_COMMON* material, DAE  	return mat;  } -std::string LLDAELoader::getElementLabel(daeElement *element) -{ -	return getElementLabel(element, mForceIdNaming); -} -  // try to get a decent label for this element -std::string LLDAELoader::getElementLabel(daeElement *element, bool forceIdNaming) +std::string LLDAELoader::getElementLabel(daeElement *element)  {  	// if we have a name attribute, use it  	std::string name = element->getAttribute("name"); -	if (name.length() && !forceIdNaming) +	if (name.length())  	{  		return name;  	} @@ -2219,7 +2239,7 @@ std::string LLDAELoader::getElementLabel(daeElement *element, bool forceIdNaming  		// if parent has a name or ID, use it  		std::string name = parent->getAttribute("name"); -		if (!name.length() || forceIdNaming) +		if (!name.length())  		{  			name = std::string(parent->getID());  		} @@ -2262,9 +2282,9 @@ size_t LLDAELoader::getSuffixPosition(std::string label)  }  // static -std::string LLDAELoader::getLodlessLabel(daeElement *element, bool forceIdNaming) +std::string LLDAELoader::getLodlessLabel(daeElement *element)  { -	std::string label = getElementLabel(element, forceIdNaming); +	std::string label = getElementLabel(element);  	size_t ext_pos = getSuffixPosition(label);  	if (ext_pos != -1)  	{ @@ -2335,13 +2355,8 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh)  	return (status == LLModel::NO_ERRORS);  } -LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh) -{ -	return loadModelFromDomMesh(mesh, mForceIdNaming); -} -  //static  -LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh, bool forceIdNaming) +LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh)  {  	LLVolumeParams volume_params;  	volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); @@ -2349,7 +2364,7 @@ LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh, bool forceIdNaming)  	createVolumeFacesFromDomMesh(ret, mesh);      if (ret->mLabel.empty())      { -		ret->mLabel = getElementLabel(mesh, forceIdNaming); +	    ret->mLabel = getElementLabel(mesh);      }      return ret;  } @@ -2367,7 +2382,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo  	LLModel* ret = new LLModel(volume_params, 0.f); -	std::string model_name = getLodlessLabel(mesh, mForceIdNaming); +	std::string model_name = getLodlessLabel(mesh);  	ret->mLabel = model_name + lod_suffix[mLod];  	llassert(!ret->mLabel.empty()); diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 3ababd3156..27db5326d5 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -56,7 +56,8 @@ public:  		void*											opaque_userdata,  		JointTransformMap&						jointMap,  		JointSet&									jointsFromNodes, -		U32									modelLimit); +		U32									modelLimit, +		bool									preprocess);  	virtual ~LLDAELoader() ;  	virtual bool OpenFile(const std::string& filename); @@ -89,22 +90,22 @@ protected:  	static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh);  	static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh); -	static LLModel* loadModelFromDomMesh(domMesh* mesh, bool forceIdNaming); -	LLModel* loadModelFromDomMesh(domMesh* mesh); +	static LLModel* loadModelFromDomMesh(domMesh* mesh);  	// Loads a mesh breaking it into one or more models as necessary  	// to get around volume face limitations while retaining >8 materials  	//  	bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit); -	static std::string getElementLabel(daeElement *element, bool forceIdNaming); -	std::string getElementLabel(daeElement *element); +	static std::string getElementLabel(daeElement *element);  	static size_t getSuffixPosition(std::string label); -	static std::string getLodlessLabel(daeElement *element, bool forceIdNaming = false); +	static std::string getLodlessLabel(daeElement *element); + +	static std::string preprocessDAE(std::string filename);  private:  	U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels -	bool mForceIdNaming; +	bool mPreprocessDAE;  };  #endif  // LL_LLDAELLOADER_H diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 53ca080d66..0e2946632a 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -94,26 +94,33 @@ BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dp  static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts"); -S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,  +S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, +    ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const +{ +    LLRectf rect_float(rect.mLeft, rect.mTop, rect.mRight, rect.mBottom); +    return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses); +} + +S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,   					 ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const  { -	F32 x = (F32)rect.mLeft; +	F32 x = rect.mLeft;  	F32 y = 0.f;  	switch(valign)  	{  	case TOP: -		y = (F32)rect.mTop; +		y = rect.mTop;  		break;  	case VCENTER: -		y = (F32)rect.getCenterY(); +		y = rect.getCenterY();  		break;  	case BASELINE:  	case BOTTOM: -		y = (F32)rect.mBottom; +		y = rect.mBottom;  		break;  	default: -		y = (F32)rect.mBottom; +		y = rect.mBottom;  		break;  	}  	return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses); @@ -357,7 +364,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  	if (right_x)  	{ -		*right_x = (cur_x - origin.mV[VX]) / sScaleX; +        F32 cr_x = (cur_x - origin.mV[VX]) / sScaleX; +        if (*right_x < cr_x) +        { +            // rightmost edge of previously drawn text, don't draw over previous text +            *right_x = cr_x; +        }  	}  	//FIXME: add underline as glyph? diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 0988e99deb..7d0e53f60f 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -99,6 +99,15 @@ public:  				BOOL use_ellipses = FALSE) const;  	S32 render(const LLWString &text, S32 begin_offset,  +				const LLRectf& rect,  +				const LLColor4 &color,  +				HAlign halign = LEFT,  VAlign valign = BASELINE,  +				U8 style = NORMAL, ShadowType shadow = NO_SHADOW,  +				S32 max_chars = S32_MAX, +				F32* right_x=NULL,  +				BOOL use_ellipses = FALSE) const; + +	S32 render(const LLWString &text, S32 begin_offset,   				F32 x, F32 y,   				const LLColor4 &color,   				HAlign halign = LEFT,  VAlign valign = BASELINE,  diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 0f260674ed..52b8de8365 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -325,14 +325,20 @@ LLGLSLShader::~LLGLSLShader()  void LLGLSLShader::unload()  { +    mShaderFiles.clear(); +    mDefines.clear(); + +    unloadInternal(); +} + +void LLGLSLShader::unloadInternal() +{      sInstances.erase(this);      stop_glerror();      mAttribute.clear();      mTexture.clear();      mUniform.clear(); -    mShaderFiles.clear(); -    mDefines.clear();      if (mProgramObject)      { @@ -354,13 +360,13 @@ void LLGLSLShader::unload()          mProgramObject = 0;      } -     +      if (mTimerQuery)      {          glDeleteQueriesARB(1, &mTimerQuery);          mTimerQuery = 0;      } -     +      if (mSamplesQuery)      {          glDeleteQueriesARB(1, &mSamplesQuery); @@ -369,7 +375,7 @@ void LLGLSLShader::unload()      //hack to make apple not complain      glGetError(); -     +      stop_glerror();  } @@ -378,6 +384,8 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,                                  U32 varying_count,                                  const char** varyings)  { +    unloadInternal(); +      sInstances.insert(this);      //reloading, reset matrix hash values diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 5abddf274b..0746e8760a 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -198,7 +198,9 @@ public:  	bool mTextureStateFetched;  	std::vector<U32> mTextureMagFilter;  	std::vector<U32> mTextureMinFilter; -	 + +private: +	void unloadInternal();  };  //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index 58b66f60ca..f841901801 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -54,7 +54,9 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)  	mUseDrawContextAlpha(p.use_draw_context_alpha),  	mPriority(0),  	mMinWidth(p.min_width), -	mMinHeight(p.min_height) +	mMinHeight(p.min_height), +	mMaxWidth(0), +	mMaxHeight(0)  {  	if (mImagep.notNull())  	{ @@ -104,7 +106,15 @@ void LLIconCtrl::setValue(const LLSD& value )  		&& mMinWidth   		&& mMinHeight)  	{ -		mImagep->getImage()->setKnownDrawSize(llmax(mMinWidth, mImagep->getWidth()), llmax(mMinHeight, mImagep->getHeight())); +        S32 desired_draw_width = llmax(mMinWidth, mImagep->getWidth()); +        S32 desired_draw_height = llmax(mMinHeight, mImagep->getHeight()); +        if (mMaxWidth && mMaxHeight) +        { +            desired_draw_width = llmin(desired_draw_width, mMaxWidth); +            desired_draw_height = llmin(desired_draw_height, mMaxHeight); +        } + +        mImagep->getImage()->setKnownDrawSize(desired_draw_width, desired_draw_height);  	}  } diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index 8b1092df46..7971cd44d3 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -79,7 +79,9 @@ protected:  	//the output size of the icon image if set.  	S32 mMinWidth, -		mMinHeight; +		mMinHeight, +		mMaxWidth, +		mMaxHeight;  	// If set to true (default), use the draw context transparency.  	// If false, will use transparency returned by getCurrentTransparency(). See STORM-698. diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 4a3780e2ef..ab68451149 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -673,7 +673,7 @@ void LLTextBase::drawText()  			line_end = next_start;  		} -		LLRect text_rect(line.mRect); +        LLRectf text_rect(line.mRect.mLeft, line.mRect.mTop, line.mRect.mRight, line.mRect.mBottom);  		text_rect.mRight = mDocumentView->getRect().getWidth(); // clamp right edge to document extents  		text_rect.translate(mDocumentView->getRect().mLeft, mDocumentView->getRect().mBottom); // adjust by scroll position @@ -746,7 +746,7 @@ void LLTextBase::drawText()  				++misspell_it;  			} -			text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect)); +			text_rect.mLeft = cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect);  			seg_start = clipped_end + cur_segment->getStart();  		} @@ -3031,7 +3031,7 @@ bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32  S32	LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; }  S32	LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; }  void LLTextSegment::updateLayout(const LLTextBase& editor) {} -F32	LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { return draw_rect.mLeft; } +F32	LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; }  bool LLTextSegment::canEdit() const { return false; }  void LLTextSegment::unlinkFromDocument(LLTextBase*) {}  void LLTextSegment::linkToDocument(LLTextBase*) {} @@ -3097,7 +3097,7 @@ LLNormalTextSegment::~LLNormalTextSegment()  } -F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  {  	if( end - start > 0 )  	{ @@ -3107,7 +3107,7 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec  }  // Draws a single text segment, reversing the color for selection if needed. -F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect) +F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect)  {  	F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha; @@ -3139,7 +3139,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele  				 &right_x,   				 mEditor.getUseEllipses());  	} -	rect.mLeft = (S32)ceil(right_x); +	rect.mLeft = right_x;  	if( (selection_start < seg_end) && (selection_end > seg_start) )  	{ @@ -3158,7 +3158,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele  				 &right_x,   				 mEditor.getUseEllipses());  	} -	rect.mLeft = (S32)ceil(right_x); +	rect.mLeft = right_x;  	if( selection_end < seg_end )  	{  		// Draw normally @@ -3175,7 +3175,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele  				 &right_x,   				 mEditor.getUseEllipses());  	} -	return right_x; +    return right_x;  }  BOOL LLNormalTextSegment::handleHover(S32 x, S32 y, MASK mask) @@ -3406,7 +3406,7 @@ LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP s  	  mNormalStyle(normal_style){}  /*virtual*/  -F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  {  	F32 result = LLNormalTextSegment::draw(start, end, selection_start, selection_end, draw_rect);  	if (end == mEnd - mStart) @@ -3484,7 +3484,7 @@ void LLInlineViewSegment::updateLayout(const LLTextBase& editor)  	mView->setOrigin(start_rect.mLeft + mLeftPad, start_rect.mBottom + mBottomPad);  } -F32	LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +F32	LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  {  	// return padded width of widget  	// widget is actually drawn during mDocumentView's draw() @@ -3525,7 +3525,7 @@ S32	LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32  {  	return 1;  } -F32	LLLineBreakTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +F32	LLLineBreakTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  {  	return  draw_rect.mLeft;  } @@ -3591,7 +3591,7 @@ void LLImageTextSegment::setToolTip(const std::string& tooltip)  	mTooltip = tooltip;  } -F32	LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +F32	LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  {  	if ( (start >= 0) && (end <= mEnd - mStart))  	{ diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index e64cdf2ee0..faab405f74 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -66,7 +66,7 @@ public:  	virtual S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;  	virtual S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;  	virtual void				updateLayout(const class LLTextBase& editor); -	virtual F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	virtual F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);  	virtual bool				canEdit() const;  	virtual void				unlinkFromDocument(class LLTextBase* editor);  	virtual void				linkToDocument(class LLTextBase* editor); @@ -117,7 +117,7 @@ public:  	/*virtual*/ bool				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;  	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;  	/*virtual*/ S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; -	/*virtual*/ F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	/*virtual*/ F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);  	/*virtual*/ bool				canEdit() const { return true; }  	/*virtual*/ const LLColor4&		getColor() const					{ return mStyle->getColor(); }  	/*virtual*/ LLStyleConstSP		getStyle() const					{ return mStyle; } @@ -135,7 +135,7 @@ public:  	/*virtual*/ BOOL				handleToolTip(S32 x, S32 y, MASK mask);  protected: -	F32					drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect); +	F32					drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect);  	virtual		const LLWString&	getWText()	const;  	virtual		const S32			getLength()	const; @@ -169,7 +169,7 @@ class LLOnHoverChangeableTextSegment : public LLNormalTextSegment  {  public:  	LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ); -	/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);  	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);  protected:  	// Style used for text when mouse pointer is over segment @@ -203,7 +203,7 @@ public:  	/*virtual*/ bool		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;  	/*virtual*/ S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;  	/*virtual*/ void		updateLayout(const class LLTextBase& editor); -	/*virtual*/ F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	/*virtual*/ F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);  	/*virtual*/ bool		canEdit() const { return false; }  	/*virtual*/ void		unlinkFromDocument(class LLTextBase* editor);  	/*virtual*/ void		linkToDocument(class LLTextBase* editor); @@ -226,7 +226,7 @@ public:  	~LLLineBreakTextSegment();  	bool		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;  	S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; -	F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);  private:  	S32			mFontHeight; @@ -239,7 +239,7 @@ public:  	~LLImageTextSegment();  	bool		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;  	S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; -	F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);  	/*virtual*/ BOOL	handleToolTip(S32 x, S32 y, MASK mask);  	/*virtual*/ void	setToolTip(const std::string& tooltip); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 576fff5fb2..57de35dfde 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -229,7 +229,7 @@ static std::string getStringAfterToken(const std::string str, const std::string  LLUrlEntryHTTP::LLUrlEntryHTTP()  	: LLUrlEntryBase()  { -	mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?\\.[a-z](:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*", +	mPattern = boost::regex("https?://([^\\s/?\\.#]+\\.?)+\\.\\w+(:\\d+)?(/\\S*)?",  							boost::regex::perl|boost::regex::icase);  	mMenuName = "menu_url_http.xml";  	mTooltip = LLTrans::getString("TooltipHttpUrl"); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index dde54c78c4..d41930a492 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -232,6 +232,14 @@ namespace tut  		testRegex("http url with newlines", url,  				  "XX\nhttp://www.secondlife.com/\nXX",  				  "http://www.secondlife.com/"); + +		testRegex("http url without tld shouldn't be decorated (1)", url, +				  "http://test", +				  ""); + +		testRegex("http url without tld shouldn't be decorated (2)", url, +				  "http://test .com", +				  "");  	}  	template<> template<> diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 9028f73e30..8d9d1dd975 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -69,6 +69,7 @@ private:  	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);  	void onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle);  	void onFileDownloadCallback(std::string filename); +	const std::string onFileDialogCallback();  	void postDebugMessage(const std::string& msg);  	void authResponse(LLPluginMessage &message); @@ -95,6 +96,7 @@ private:  	bool mCanPaste;  	std::string mCachePath;  	std::string mCookiePath; +	std::string mPickedFile;  	LLCEFLib* mLLCEFLib;      VolumeCatcher mVolumeCatcher; @@ -123,6 +125,7 @@ MediaPluginBase(host_send_func, host_user_data)  	mCanPaste = false;  	mCachePath = "";  	mCookiePath = ""; +	mPickedFile = "";  	mLLCEFLib = new LLCEFLib();  } @@ -305,6 +308,20 @@ void MediaPluginCEF::onFileDownloadCallback(const std::string filename)  	sendMessage(message);  } +//////////////////////////////////////////////////////////////////////////////// +// +const std::string MediaPluginCEF::onFileDialogCallback() +{ +	mPickedFile.clear(); + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); +	message.setValueBoolean("blocking_request", true); + +	sendMessage(message); + +	return mPickedFile; +} +  void MediaPluginCEF::onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle)  {  	std::string name = ""; @@ -439,6 +456,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2));  				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));  				mLLCEFLib->setOnFileDownloadCallback(boost::bind(&MediaPluginCEF::onFileDownloadCallback, this, _1)); +				mLLCEFLib->setOnFileDialogCallback(boost::bind(&MediaPluginCEF::onFileDialogCallback, this));  				mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2));  				mLLCEFLib->setOnRequestExitCallback(boost::bind(&MediaPluginCEF::onRequestExitCallback, this)); @@ -648,6 +666,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  			{  				mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");  			} +			if (message_name == "pick_file_response") +			{ +				mPickedFile = message_in.getValue("file"); +			}  			if (message_name == "auth_response")  			{  				authResponse(message_in); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ef6107b1d5..6c30c93ae7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -35,6 +35,17 @@      <key>Value</key>      <integer>768</integer>    </map> +  <key>ImporterPreprocessDAE</key> +  <map> +    <key>Comment</key> +    <string>Enable preprocessing for DAE files to fix some ColladaDOM related problems (like support for space characters within names and ids).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>IMShowTime</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 790c76e216..ff7944b3db 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3205,7 +3205,7 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global)  }  BOOL LLAgent::leftButtonGrabbed() const	 -{  +{  	const BOOL camera_mouse_look = gAgentCamera.cameraMouselook();  	return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)   		|| (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0) @@ -3213,6 +3213,13 @@ BOOL LLAgent::leftButtonGrabbed() const  		|| (camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);  } +BOOL LLAgent::leftButtonBlocked() const +{ +    const BOOL camera_mouse_look = gAgentCamera.cameraMouselook(); +    return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) +        || (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0); +} +  BOOL LLAgent::rotateGrabbed() const		  {   	return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0) @@ -3670,7 +3677,14 @@ BOOL LLAgent::anyControlGrabbed() const  BOOL LLAgent::isControlGrabbed(S32 control_index) const  { -	return mControlsTakenCount[control_index] > 0; +    if (gAgent.mControlsTakenCount[control_index] > 0) +        return TRUE; +    return gAgent.mControlsTakenPassedOnCount[control_index] > 0; +} + +BOOL LLAgent::isControlBlocked(S32 control_index) const +{ +    return mControlsTakenCount[control_index] > 0;  }  void LLAgent::forceReleaseControls() @@ -3849,6 +3863,7 @@ void LLAgent::startTeleportRequest()      }  	if (hasPendingTeleportRequest())  	{ +        mTeleportCanceled.reset();  		if  (!isMaturityPreferenceSyncedWithServer())  		{  			gTeleportDisplay = TRUE; @@ -3878,6 +3893,7 @@ void LLAgent::startTeleportRequest()  void LLAgent::handleTeleportFinished()  {  	clearTeleportRequest(); +    mTeleportCanceled.reset();  	if (mIsMaturityRatingChangingDuringTeleport)  	{  		// notify user that the maturity preference has been changed @@ -4021,13 +4037,25 @@ void LLAgent::teleportCancel()  			msg->addUUIDFast(_PREHASH_AgentID, getID());  			msg->addUUIDFast(_PREHASH_SessionID, getSessionID());  			sendReliableMessage(); -		}	 +		} +		mTeleportCanceled = mTeleportRequest;  	}  	clearTeleportRequest();  	gAgent.setTeleportState( LLAgent::TELEPORT_NONE );  	gPipeline.resetVertexBuffers();  } +void LLAgent::restoreCanceledTeleportRequest() +{ +    if (mTeleportCanceled != NULL) +    { +        gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); +        mTeleportRequest = mTeleportCanceled; +        mTeleportCanceled.reset(); +        gTeleportDisplay = TRUE; +        gTeleportDisplayTimer.reset(); +    } +}  void LLAgent::teleportViaLocation(const LLVector3d& pos_global)  { diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 4830cb754b..9e8550e280 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -432,7 +432,8 @@ private:  	// Grab  	//--------------------------------------------------------------------  public: -	BOOL 			leftButtonGrabbed() const; +    BOOL 			leftButtonGrabbed() const; +    BOOL 			leftButtonBlocked() const;  	BOOL 			rotateGrabbed() const;  	BOOL 			forwardGrabbed() const;  	BOOL 			backwardGrabbed() const; @@ -449,8 +450,9 @@ public:  	BOOL			controlFlagsDirty() const;  	void			enableControlFlagReset();  	void 			resetControlFlags(); -	BOOL			anyControlGrabbed() const; 		// True iff a script has taken over a control -	BOOL			isControlGrabbed(S32 control_index) const; +	BOOL			anyControlGrabbed() const; 		// True if a script has taken over any control +    BOOL			isControlGrabbed(S32 control_index) const; // True if a script has taken over a control +    BOOL			isControlBlocked(S32 control_index) const; // Control should be ignored or won't be passed  	// Send message to simulator to force grabbed controls to be  	// released, in case of a poorly written script.  	void			forceReleaseControls(); @@ -616,6 +618,7 @@ public:  	void 			teleportViaLocation(const LLVector3d& pos_global);		// To a global location - this will probably need to be deprecated  	void			teleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation  	void 			teleportCancel();										// May or may not be allowed by server +    void            restoreCanceledTeleportRequest();  	bool			getTeleportKeepsLookAt() { return mbTeleportKeepsLookAt; } // Whether look-at reset after teleport  protected:  	bool 			teleportCore(bool is_local = false); 					// Stuff for all teleports; returns true if the teleport can proceed @@ -638,6 +641,7 @@ private:  	friend class LLTeleportRequestViaLocationLookAt;  	LLTeleportRequestPtr        mTeleportRequest; +	LLTeleportRequestPtr        mTeleportCanceled;  	boost::signals2::connection mTeleportFinishedSlot;  	boost::signals2::connection mTeleportFailedSlot; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index aed27924fe..fa16f02c16 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -879,7 +879,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)  	}  	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); -	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) +	if (LLToolMgr::getInstance()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)  	{  		// just update hud zoom level  		mHUDTargetZoom /= fraction; diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 714b456ae7..d8b6cc729d 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -567,13 +567,25 @@ void AISUpdate::parseCategory(const LLSD& category_map)  		parseDescendentCount(category_id, category_map["_embedded"]);  	} -	LLPointer<LLViewerInventoryCategory> new_cat(new LLViewerInventoryCategory(category_id)); +	LLPointer<LLViewerInventoryCategory> new_cat;  	LLViewerInventoryCategory *curr_cat = gInventory.getCategory(category_id);  	if (curr_cat)  	{  		// Default to current values where not provided. -		new_cat->copyViewerCategory(curr_cat); -	} +        new_cat = new LLViewerInventoryCategory(curr_cat); +    } +    else +    { +        if (category_map.has("agent_id")) +        { +            new_cat = new LLViewerInventoryCategory(category_map["agent_id"].asUUID()); +        } +        else +        { +            LL_DEBUGS() << "No owner provided, folder might be assigned wrong owner" << LL_ENDL; +            new_cat = new LLViewerInventoryCategory(LLUUID::null); +        } +    }  	BOOL rv = new_cat->unpackMessage(category_map);  	// *NOTE: unpackMessage does not unpack version or descendent count.  	//if (category_map.has("version")) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6f09bd8eea..c146e97c2e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4536,7 +4536,13 @@ void LLAppViewer::purgeCache()  	LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;  	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);  	LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); -	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*"); +	std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); +	if (LLFile::isdir(browser_cache)) +	{ +		// cef does not support clear_cache and clear_cookies, so clear what we can manually. +		gDirUtilp->deleteDirAndContents(browser_cache); +	} +	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*");  }  //purge cache immediately, do not wait until the next login. diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 25a5df9781..932326acae 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -182,38 +182,12 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)  	mSymbolPos(p.symbol_pos)  {  	mPriority = LLViewerFetchedTexture::BOOST_ICON; -	 -	LLRect rect = p.rect; - -	// BottomRight is the default position -	S32 left = rect.getWidth() - mSymbolSize - mSymbolHpad; -	S32 bottom = mSymbolVpad; -	switch(mSymbolPos) -	{ -	case LLAvatarIconCtrlEnums::BOTTOM_LEFT: -	{ -		left = mSymbolHpad; -		bottom = mSymbolVpad; -	} - -	case LLAvatarIconCtrlEnums::TOP_LEFT: -	{ -		left = mSymbolHpad; -		bottom = rect.getHeight() - mSymbolSize - mSymbolVpad; -	} - -	case LLAvatarIconCtrlEnums::TOP_RIGHT: -	{ -		left = rect.getWidth() - mSymbolSize - mSymbolHpad; -		bottom = rect.getHeight() - mSymbolSize - mSymbolVpad; -	} - -	case LLAvatarIconCtrlEnums::BOTTOM_RIGHT: -		// fallthrough, is default -	default: -		rect.setOriginAndSize(left, bottom, mSymbolSize, mSymbolSize); -	} +    // don't request larger image then necessary to save gl memory, +    // but ensure that quality is sufficient +    LLRect rect = p.rect; +    mMaxHeight = llmax((S32)p.min_height, rect.getHeight()); +    mMaxWidth = llmax((S32)p.min_width, rect.getWidth());  	if (p.avatar_id.isProvided())  	{ diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index aa6c9c094c..38f58abba6 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -56,9 +56,9 @@ public:  		return mEditor->getDocumentView()->getRect().getWidth();  	} -	/*virtual*/ F32	draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +	/*virtual*/ F32	draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  	{ -		gl_line_2d(draw_rect.mLeft + 5, draw_rect.getCenterY(), draw_rect.mRight - 5, draw_rect.getCenterY(), LLColor4::grey); +		gl_line_2d((S32)(draw_rect.mLeft + 5), (S32)draw_rect.getCenterY(), (S32)(draw_rect.mRight - 5), (S32)draw_rect.getCenterY(), LLColor4::grey);  		return draw_rect.getWidth();  	} diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index a03178adf6..80d810d159 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -292,7 +292,7 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )  									subject->mColor.mV[VALPHA] ); // keep current alpha  			subject->mColor = updatedColor;  			subject->setControlValue(updatedColor.getValue()); - +			pickerp->setRevertOnCancel(TRUE);  			if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)  			{  				subject->mOnCancelCallback( subject, LLSD()); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 61b5748201..4dbed114bb 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -77,7 +77,7 @@ public:  			return 0;  		}  	} -	/*virtual*/ F32		draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +	/*virtual*/ F32		draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  	{  		F32 right_x;  		mStyle->getFont()->renderUTF8(mExpanderLabel, start,  diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index b779d8f461..d614d612ff 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -969,6 +969,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it  		{  			LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField);  		} +		LLFavoritesOrderStorage::instance().mSaveOnExit = true;  	}  	return TRUE; @@ -1530,10 +1531,10 @@ void LLFavoritesOrderStorage::destroyClass()  	{  		file.close();  		LLFile::remove(filename); -		if(mSaveOnExit) -		{ -			LLFavoritesOrderStorage::instance().saveFavoritesRecord(true); -		} +	} +	if(mSaveOnExit) +	{ +	    LLFavoritesOrderStorage::instance().saveFavoritesRecord(true);  	}  } @@ -1799,6 +1800,16 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)  	    }  	} +	for (std::set<LLUUID>::iterator it = mMissingSLURLs.begin(); it != mMissingSLURLs.end(); it++) +	{ +		slurls_map_t::iterator slurl_iter = mSLURLs.find(*it); +		if (slurl_iter != mSLURLs.end()) +		{ +			pref_changed = true; +			break; +		} +	} +  	if((items != mPrevFavorites) || name_changed || pref_changed)  	{  	    std::string filename = getStoredFavoritesFilename(); @@ -1819,6 +1830,7 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)  			LLSD user_llsd;  			S32 fav_iter = 0; +			mMissingSLURLs.clear();  			for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)  			{  				LLSD value; @@ -1836,8 +1848,10 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)  					else  					{  						getSLURL((*it)->getAssetUUID()); +						value["slurl"] = ""; +						user_llsd[fav_iter] = value;  						mUpdateRequired = true; -						return FALSE; +						mMissingSLURLs.insert((*it)->getAssetUUID());  					}  				}  				else @@ -1868,7 +1882,6 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)  												<< "' at '" << filename << "' " << LL_ENDL;  			}  		} -  		mPrevFavorites = items;  	} diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 846d62227a..2115f77cf3 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -245,7 +245,7 @@ private:  	typedef std::map<LLUUID, std::string> slurls_map_t;  	slurls_map_t mSLURLs; - +	std::set<LLUUID> mMissingSLURLs;  	bool mIsDirty;  	struct IsNotInFavorites diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 535cb368bd..ec2c9740af 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -173,6 +173,7 @@ void LLFloaterColorPicker::showUI ()  	openFloater(getKey());  	setVisible ( TRUE );  	setFocus ( TRUE ); +	setRevertOnCancel(FALSE);  	// HACK: if system color picker is required - close the SL one we made and use default system dialog  	if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) @@ -390,7 +391,10 @@ void LLFloaterColorPicker::onClickCancel ( void* data )  		if ( self )  		{ -			self->cancelSelection (); +		    if(self->getRevertOnCancel()) +		    { +		        self->cancelSelection (); +		    }  			self->closeFloater();  		}  	} @@ -447,8 +451,7 @@ void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data)  	if (self)  	{  		gSavedSettings.setBOOL("ApplyColorImmediately", self->mApplyImmediateCheck->get()); - -		if (self->mApplyImmediateCheck->get()) +		if (self->mApplyImmediateCheck->get() && self->isColorChanged())  		{  			LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );  		} @@ -473,6 +476,11 @@ F32 LLFloaterColorPicker::getSwatchTransparency()  	return getTransparencyType() == TT_ACTIVE ? 1.f : LLFloater::getCurrentTransparency();  } +BOOL LLFloaterColorPicker::isColorChanged() +{ +    return ((getOrigR() != getCurR()) || (getOrigG() != getCurG()) || (getOrigB() != getCurB())); +} +  //////////////////////////////////////////////////////////////////////////////  //  void LLFloaterColorPicker::draw() diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 8c16ebdf03..16974a872e 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -104,6 +104,11 @@ class LLFloaterColorPicker  		void setMouseDownInSwatch (BOOL mouse_down_in_swatch);  		BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; } +		void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; }; +		BOOL getRevertOnCancel () { return mRevertOnCancel; } + +		BOOL isColorChanged (); +  		// called when text entries (RGB/HSL etc.) are changed by user  		void onTextEntryChanged ( LLUICtrl* ctrl ); @@ -144,6 +149,8 @@ class LLFloaterColorPicker  		BOOL mMouseDownInHueRegion;  		BOOL mMouseDownInSwatch; +		BOOL mRevertOnCancel; +  		const S32 mRGBViewerImageLeft;  		const S32 mRGBViewerImageTop;  		const S32 mRGBViewerImageWidth; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 15fb07f159..459c598f6d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -610,7 +610,7 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)  {  	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; -	fp->mModelPreview->genLODs(); +    fp->mModelPreview->queryLODs();  }  void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) @@ -638,7 +638,12 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)  //-----------------------------------------------------------------------------  void LLFloaterModelPreview::draw()  { -	LLFloater::draw(); +    LLFloater::draw(); + +    if (!mModelPreview) +    { +        return; +    }  	mModelPreview->update(); @@ -668,7 +673,7 @@ void LLFloaterModelPreview::draw()  	childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));  	childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size())); -	if (mModelPreview) +    if (mModelPreview->lodsReady())  	{  		gGL.color3f(1.f, 1.f, 1.f); @@ -1178,6 +1183,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl  LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)  : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL) +, mLodsQuery()  , mPelvisZOffset( 0.0f )  , mLegacyRigValid( false )  , mRigValidJointUpload( false ) @@ -1544,9 +1550,18 @@ void LLModelPreview::rebuildUploadData()  					}  					instance.mLOD[i] = lod_model;  				} -				else if (importerDebug) +				else  				{ -					LL_INFOS() << "List of models does not include " << instance.mLabel << LL_ENDL; +					if (i < LLModel::LOD_HIGH && !lodsReady()) +					{ +						// assign a placeholder from previous LOD until lod generation is complete. +						// Note: we might need to assign it regardless of conditions like named search does, to prevent crashes. +						instance.mLOD[i] = instance.mLOD[i + 1]; +					} +					if (importerDebug) +					{ +						LL_INFOS() << "List of models does not include " << instance.mLabel << LL_ENDL; +					}  				}  			} @@ -1760,7 +1775,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable  		this,  		mJointTransformMap,  		mJointsFromNode, -		gSavedSettings.getU32("ImporterModelLimit")); +		gSavedSettings.getU32("ImporterModelLimit"), +		gSavedSettings.getBOOL("ImporterPreprocessDAE"));  	if (force_disable_slm)  	{ @@ -2573,112 +2589,6 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  		shader->bind();  	}  } -void LLModelPreview::genModelBBox() -{ -	LLVector3 min, max; -	min = this->mModelLoader->mExtents[0]; -	max = this->mModelLoader->mExtents[1]; -	std::vector<LLVector3> v_list; -	v_list.resize(4); -	std::map<U8, std::vector<LLVector3> > face_list; - -	// Face 0 -	v_list[0] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]); -	v_list[1] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]); -	v_list[2] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]); -	v_list[3] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]); -	face_list.insert(std::pair<U8, std::vector<LLVector3> >(0, v_list)); - -	// Face 1 -	v_list[0] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]); -	v_list[1] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]); -	v_list[2] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]); -	v_list[3] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]); -	face_list.insert(std::pair<U8, std::vector<LLVector3> >(1, v_list)); - -	// Face 2 -	v_list[0] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]); -	v_list[1] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]); -	v_list[2] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]); -	v_list[3] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]); -	face_list.insert(std::pair<U8, std::vector<LLVector3> >(2, v_list)); - -	// Face 3 -	v_list[0] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]); -	v_list[1] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]); -	v_list[2] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]); -	v_list[3] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]); -	face_list.insert(std::pair<U8, std::vector<LLVector3> >(3, v_list)); - -	// Face 4 -	v_list[0] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]); -	v_list[1] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]); -	v_list[2] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]); -	v_list[3] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]); -	face_list.insert(std::pair<U8, std::vector<LLVector3> >(4, v_list)); - -	// Face 5 -	v_list[0] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]); -	v_list[1] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]); -	v_list[2] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]); -	v_list[3] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]); -	face_list.insert(std::pair<U8, std::vector<LLVector3> >(5, v_list)); - -	U16 Idx[] = { 0, 1, 2, 3, 0, 2, }; - -	U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; -	LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0); -	buff->allocateBuffer(4, 6, true); - -	LLStrider<LLVector3> pos; -	LLStrider<U16> idx; -	LLStrider<LLVector3> norm; -	LLStrider<LLVector2> tc; - -	buff->getVertexStrider(pos); -	buff->getIndexStrider(idx); - -	buff->getNormalStrider(norm); -	buff->getTexCoord0Strider(tc); - -	for (U32 i = 0; i < 6; ++i) -	{ -		idx[i] = Idx[i]; -	} - -	LLVolumeParams volume_params; -	volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); -	LLModel* mdl = new LLModel(volume_params, 0.f); -	mdl->mLabel = "BBOX";  // please adopt name from high LOD (mBaseModel) or from original model otherwise it breaks search mechanics which is name based - -	mdl->setNumVolumeFaces(6); -	for (U8 i = 0; i < 6; ++i) -	{ -		for (U8 j = 0; j < 4; ++j) -		{ -			pos[j] = face_list[i][j]; -		} - -		mdl->setVolumeFaceData(i, pos, norm, tc, idx, buff->getNumVerts(), buff->getNumIndices()); -	} - -	if (validate_model(mdl)) -	{ -		LLMatrix4 mat; -		std::map<std::string, LLImportMaterial> materials; -		std::vector<LLModelInstance> instance_list; -		instance_list.push_back(LLModelInstance(mdl, mdl->mLabel, mat, materials)); - -		for (S32 i = LLModel::LOD_HIGH - 1; i >= 0; i--) -		{ -			mModel[i].clear(); -			mModel[i].push_back(mdl); - -			mScene[i].clear(); -			mScene[i].insert(std::pair<LLMatrix4, std::vector<LLModelInstance> >(mat, instance_list)); -		} -	} -}  void LLModelPreview::updateStatusMessages()  { @@ -3422,14 +3332,25 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  void LLModelPreview::update()  {      if (mGenLOD) -	{ -		mGenLOD = false; -		genLODs(); -		refresh(); -		updateStatusMessages(); -	} +    { +        bool subscribe_for_generation = mLodsQuery.empty(); +        mGenLOD = false; +        mDirty = true; +        mLodsQuery.clear(); + +        for (S32 lod = LLModel::LOD_HIGH; lod >= 0; --lod) +        { +            // adding all lods into query for generation +            mLodsQuery.push_back(lod); +        } + +        if (subscribe_for_generation) +        { +            doOnIdleRepeating(lodQueryCallback); +        } +    } -	if (mDirty) +    if (mDirty && mLodsQuery.empty())  	{  		mDirty = false;  		mResourceCost = calcResourceCost(); @@ -4346,6 +4267,29 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture  	}  } +// static +bool LLModelPreview::lodQueryCallback() +{ +    // not the best solution, but model preview belongs to floater +    // so it is an easy way to check that preview still exists. +    LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; +    if (fmp && fmp->mModelPreview) +    { +        LLModelPreview* preview = fmp->mModelPreview; +        if (preview->mLodsQuery.size() > 0) +        { +            S32 lod = preview->mLodsQuery.back(); +            preview->mLodsQuery.pop_back(); +            preview->genLODs(lod); + +            // return false to continue cycle +            return false; +        } +    } +    // nothing to process +    return true; +} +  void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)  {  	if (!mLODFrozen) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 07e29d09c7..b2bb15ef05 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -261,8 +261,9 @@ public:  	void clearModel(S32 lod);  	void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);  	void loadModelCallback(S32 lod); +    bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); } +    void queryLODs() { mGenLOD = true; };  	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); -	void genModelBBox(); // Generate just a model BBox if we can't generate proper LOD  	void generateNormals();  	void restoreNormals();  	U32 calcResourceCost(); @@ -290,6 +291,7 @@ public:  	void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }		  	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); +    static bool lodQueryCallback();  	boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){  return mDetailsSignal.connect(cb);  }  	boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){  return mModelLoadedSignal.connect(cb);  } @@ -303,6 +305,7 @@ public:  	LLVector3 getTranslationForJointOffset( std::string joint );  	static bool 		sIgnoreLoadedCallback; +    std::vector<S32> mLodsQuery;  protected: diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 3a0abc919f..113b307255 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -496,6 +496,10 @@ BOOL LLFloaterPreference::postBuild()  	LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this)); +	LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov"); +	fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView()); +	fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView()); +  	return TRUE;  } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 5d1e01c1f7..16566bea73 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2049,6 +2049,8 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)  	BOOL manager = (region && region->isEstateManager());  	setCtrlsEnabled(god || owner || manager); +	getChildView("apply_btn")->setEnabled(FALSE); +  	BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ?  TRUE : FALSE;  	BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ?  TRUE : FALSE;  	BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ?  TRUE : FALSE; diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 307e259006..62cbea6401 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -162,6 +162,7 @@ void LLInitialFriendCardsFetch::done()  // LLFriendCardsManager Constructor / Destructor  LLFriendCardsManager::LLFriendCardsManager() +:   mState(INIT)  {  	LLAvatarTracker::instance().addObserver(this);  } @@ -423,6 +424,7 @@ void LLFriendCardsManager::ensureFriendsFolderExists()  	LLUUID friends_folder_ID = findFriendFolderUUIDImpl();  	if (friends_folder_ID.notNull())  	{ +        mState = LOADING_FRIENDS_FOLDER;  		fetchAndCheckFolderDescendents(friends_folder_ID,  				boost::bind(&LLFriendCardsManager::ensureFriendsAllFolderExists, this));  	} @@ -452,6 +454,7 @@ void LLFriendCardsManager::ensureFriendsAllFolderExists()  	LLUUID friends_all_folder_ID = findFriendAllSubfolderUUIDImpl();  	if (friends_all_folder_ID.notNull())  	{ +        mState = LOADING_ALL_FOLDER;  		fetchAndCheckFolderDescendents(friends_all_folder_ID,  				boost::bind(&LLFriendCardsManager::syncFriendsFolder, this));  	} @@ -506,6 +509,9 @@ void LLFriendCardsManager::syncFriendsFolder()  							  NULL);  	} +    // All folders created and updated. +    mState = MANAGER_READY; +  	// 2. Add missing Friend Cards for friends  	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();  	LL_INFOS() << "try to build friends, count: " << all_buddies.size() << LL_ENDL; @@ -540,6 +546,12 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)  		<< ", id: " << avatarID  		<< LL_ENDL;  +    if (shouldBeAdded && !isManagerReady()) +    { +        shouldBeAdded = false; +        LL_DEBUGS() << "Calling cards manager not ready, state: " << getManagerState() << LL_ENDL; +    } +  	if (shouldBeAdded && findFriendCardInventoryUUIDImpl(avatarID).notNull())  	{  		shouldBeAdded = false; @@ -583,13 +595,30 @@ void LLFriendCardsManager::onFriendListUpdate(U32 changed_mask)  	switch(changed_mask) {  	case LLFriendObserver::ADD:  		{ -			const std::set<LLUUID>& changed_items = at.getChangedIDs(); -			std::set<LLUUID>::const_iterator id_it = changed_items.begin(); -			std::set<LLUUID>::const_iterator id_end = changed_items.end(); -			for (;id_it != id_end; ++id_it) -			{ -				LLFriendCardsManager::instance().addFriendCardToInventory(*id_it); -			} +            LLFriendCardsManager& cards_manager = LLFriendCardsManager::instance(); +            if (cards_manager.isManagerReady()) +            { +                // Try to add cards into inventory. +                // If cards already exist they won't be created. +                const std::set<LLUUID>& changed_items = at.getChangedIDs(); +                std::set<LLUUID>::const_iterator id_it = changed_items.begin(); +                std::set<LLUUID>::const_iterator id_end = changed_items.end(); +                for (; id_it != id_end; ++id_it) +                { +                    cards_manager.addFriendCardToInventory(*id_it); +                } +            } +            else +            { +                // User either removed calling cards' folders and manager is loading them +                // or update came too early, before viewer had chance to load all folders. +                // Either way don't process 'add' operation - manager will recreate all +                // cards after fetching folders. +                LL_INFOS_ONCE() << "Calling cards manager not ready, state: " +                    << cards_manager.getManagerState() +                    << ", postponing update." +                    << LL_ENDL; +            }  		}  		break;  	case LLFriendObserver::REMOVE: diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index 48a9f70079..ae3800e17b 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -45,6 +45,14 @@ class LLFriendCardsManager  public:  	typedef std::map<LLUUID, uuid_vec_t > folderid_buddies_map_t; +    enum EManagerState +    { +        INIT = 1, +        LOADING_FRIENDS_FOLDER, +        LOADING_ALL_FOLDER, +        MANAGER_READY +    }; +  	// LLFriendObserver implementation  	void changed(U32 mask)  	{ @@ -71,7 +79,14 @@ public:  	/**  	 *	Checks is the specified category is a Friend folder or any its subfolder  	 */ -	bool isAnyFriendCategory(const LLUUID& catID) const; +    bool isAnyFriendCategory(const LLUUID& catID) const; + +    /** +    *	Indicates that all calling card related folders are created or loaded +    */ +    bool isManagerReady() const { return mState == MANAGER_READY; } + +    EManagerState getManagerState() const { return mState; }  	/**  	 *	Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" category @@ -144,6 +159,8 @@ private:  	typedef std::set<LLUUID> avatar_uuid_set_t;  	avatar_uuid_set_t mBuddyIDSet; +    EManagerState mState; +  };  #endif // LL_LLFRIENDCARD_H diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 813d2081ce..a9bf8a9a50 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -139,8 +139,10 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item)  			BOOL copyable = false;  			if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true; -			if (!copyable || get_is_item_worn(item->getUUID())) +			if (!copyable && get_is_item_worn(item->getUUID()))  			{ +				// worn no-copy items can't be transfered, +				// but it is valid to transfer a copy of a worn item  				acceptable = false;  			}  		} diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp index 6abf9ea637..1974a073dd 100644 --- a/indra/newview/llgroupiconctrl.cpp +++ b/indra/newview/llgroupiconctrl.cpp @@ -37,7 +37,10 @@ LLGroupIconCtrl::Params::Params()  :	group_id("group_id"),  	draw_tooltip("draw_tooltip", true),  	default_icon_name("default_icon_name") -{} +{ +    changeDefault(min_width, 32); +    changeDefault(min_height, 32); +}  LLGroupIconCtrl::LLGroupIconCtrl(const LLGroupIconCtrl::Params& p) @@ -48,6 +51,12 @@ LLGroupIconCtrl::LLGroupIconCtrl(const LLGroupIconCtrl::Params& p)  {  	mPriority = LLViewerFetchedTexture::BOOST_ICON; +    // don't request larger image then necessary to save gl memory, +    // but ensure that quality is sufficient +    LLRect rect = p.rect; +    mMaxHeight = llmax((S32)p.min_height, rect.getHeight()); +    mMaxWidth = llmax((S32)p.min_width, rect.getWidth()); +  	if (p.group_id.isProvided())  	{  		LLSD value(p.group_id); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index e1315adfde..012a4fdb2f 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1053,6 +1053,11 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)  {  	LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL; +	if (!msg) +	{ +		LL_ERRS() << "Can't access the messaging system" << LL_ENDL; +		return; +	}  	LLUUID agent_id;  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id) diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 2c204170f2..52e83fe412 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -53,6 +53,7 @@ const F32 VERTICAL_PADDING = 12.f;  const F32 BUFFER_SIZE = 2.f;  const F32 HUD_TEXT_MAX_WIDTH = 190.f;  const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f; +const F32 MAX_DRAW_DISTANCE = 64.f;  std::set<LLPointer<LLHUDText> > LLHUDText::sTextObjects;  std::vector<LLPointer<LLHUDText> > LLHUDText::sVisibleTextObjects; @@ -373,7 +374,7 @@ void LLHUDText::updateVisibility()  		mVisible = FALSE;  		return;  	} -		 +  	if (vec_from_camera * LLViewerCamera::getInstance()->getAtAxis() <= LLViewerCamera::getInstance()->getNear() + 0.1f + mSourceObject->getVObjRadius())  	{  		mPositionAgent = LLViewerCamera::getInstance()->getOrigin() + vec_from_camera * ((LLViewerCamera::getInstance()->getNear() + 0.1f) / (vec_from_camera * LLViewerCamera::getInstance()->getAtAxis())); @@ -391,6 +392,15 @@ void LLHUDText::updateVisibility()  		return;  	} +	LLVector3 pos_agent_center = gAgent.getPosAgentFromGlobal(mPositionGlobal) - dir_from_camera; +	F32 last_distance_center = (pos_agent_center - LLViewerCamera::getInstance()->getOrigin()).magVec(); +	if(last_distance_center > MAX_DRAW_DISTANCE) +	{ +		mVisible = FALSE; +		return; +	} + +  	LLVector3 x_pixel_vec;  	LLVector3 y_pixel_vec; diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp index 76617b55bf..8e91af321e 100644 --- a/indra/newview/llinspectgroup.cpp +++ b/indra/newview/llinspectgroup.cpp @@ -42,16 +42,13 @@  #include "lltrans.h"  #include "lluictrl.h" -class LLFetchGroupData; - -  //////////////////////////////////////////////////////////////////////////////  // LLInspectGroup  //////////////////////////////////////////////////////////////////////////////  /// Group Inspector, a small information window used when clicking  /// on group names in the 2D UI -class LLInspectGroup : public LLInspect +class LLInspectGroup : public LLInspect, public LLGroupMgrObserver  {  	friend class LLFloaterReg; @@ -65,12 +62,16 @@ public:  	// (for example, inspector about same group but in different position)  	/*virtual*/ void onOpen(const LLSD& group_id); +	void setGroupID(const LLUUID& group_id); +  	// When closing they should close their gear menu   	/*virtual*/ void onClose(bool app_quitting);  	// Update view based on information from group manager  	void processGroupData(); -	 + +	virtual void changed(LLGroupChange gc); +  	// Make network requests for all the data to display in this view.  	// Used on construction and if avatar id changes.  	void requestUpdate(); @@ -88,53 +89,12 @@ public:  private:  	LLUUID				mGroupID; -	// an in-flight network request for group properties  -	// is represented by this object -	LLFetchGroupData*	mPropertiesRequest;  }; -////////////////////////////////////////////////////////////////////////////// -// LLFetchGroupData -////////////////////////////////////////////////////////////////////////////// - -// This object represents a pending request for avatar properties information -class LLFetchGroupData : public LLGroupMgrObserver -{ -public: -	// If the inspector closes it will delete the pending request object, so the -	// inspector pointer will be valid for the lifetime of this object -	LLFetchGroupData(const LLUUID& group_id, LLInspectGroup* inspector) -	:	LLGroupMgrObserver(group_id), -		mInspector(inspector) -	{ -		LLGroupMgr* mgr = LLGroupMgr::getInstance(); -		// register ourselves as an observer -		mgr->addObserver(this); -		// send a request -		mgr->sendGroupPropertiesRequest(group_id); -	} -	 -	~LLFetchGroupData() -	{ -		// remove ourselves as an observer -		LLGroupMgr::getInstance()->removeObserver(this); -	} -	 -	void changed(LLGroupChange gc) -	{ -		if (gc == GC_PROPERTIES) -		{ -			mInspector->processGroupData(); -		} -	} -	 -	LLInspectGroup* mInspector; -};  LLInspectGroup::LLInspectGroup(const LLSD& sd)  :	LLInspect( LLSD() ),	// single_instance, doesn't really need key -	mGroupID(),			// set in onOpen() -	mPropertiesRequest(NULL) +	mGroupID()			// set in onOpen()  {  	mCommitCallbackRegistrar.add("InspectGroup.ViewProfile",  		boost::bind(&LLInspectGroup::onClickViewProfile, this)); @@ -149,10 +109,7 @@ LLInspectGroup::LLInspectGroup(const LLSD& sd)  LLInspectGroup::~LLInspectGroup()  { -	// clean up any pending requests so they don't call back into a deleted -	// view -	delete mPropertiesRequest; -	mPropertiesRequest = NULL; +    LLGroupMgr::getInstance()->removeObserver(this);  } @@ -164,7 +121,7 @@ void LLInspectGroup::onOpen(const LLSD& data)  	// start fade animation  	LLInspect::onOpen(data); -	mGroupID = data["group_id"]; +	setGroupID(data["group_id"]);  	// Position the inspector relative to the mouse cursor  	// Similar to how tooltips are positioned @@ -185,7 +142,8 @@ void LLInspectGroup::onOpen(const LLSD& data)  // virtual  void LLInspectGroup::onClose(bool app_quitting)  { -	// *TODO: If we add a gear menu, close it here +    LLGroupMgr::getInstance()->removeObserver(this); +    // *TODO: If we add a gear menu, close it here  }	  void LLInspectGroup::requestUpdate() @@ -213,9 +171,15 @@ void LLInspectGroup::requestUpdate()  	getChild<LLUICtrl>("leave_btn")->setVisible(false);  	getChild<LLUICtrl>("join_btn")->setVisible(false); -	// Make a new request for properties -	delete mPropertiesRequest; -	mPropertiesRequest = new LLFetchGroupData(mGroupID, this); +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); +	if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) +	{ +	    LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); +	} +	else +	{ +	    processGroupData(); +	}  	// Name lookup will be faster out of cache, use that  	gCacheName->getGroup(mGroupID, @@ -223,6 +187,16 @@ void LLInspectGroup::requestUpdate()  			this, _1, _2, _3));  } +void LLInspectGroup::setGroupID(const LLUUID& group_id) +{ +    LLGroupMgr::getInstance()->removeObserver(this); + +    mID = group_id; +    mGroupID = group_id; + +    LLGroupMgr::getInstance()->addObserver(this); +} +  void LLInspectGroup::nameUpdatedCallback(  	const LLUUID& id,  	const std::string& name, @@ -236,6 +210,14 @@ void LLInspectGroup::nameUpdatedCallback(  	// Otherwise possibly a request for an older inspector, ignore it  } +void LLInspectGroup::changed(LLGroupChange gc) +{ +    if (gc == GC_PROPERTIES) +    { +        processGroupData(); +    } +} +  void LLInspectGroup::processGroupData()  {  	LLGroupMgrGroupData* data = @@ -288,10 +270,6 @@ void LLInspectGroup::processGroupData()  		bool can_join = !is_member && data->mOpenEnrollment;  		getChild<LLUICtrl>("join_btn")->setEnabled(can_join);  	} - -	// Delete the request object as it has been satisfied -	delete mPropertiesRequest; -	mPropertiesRequest = NULL;  }  void LLInspectGroup::onClickViewProfile() diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 0bad4702e0..e123a3e68a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1075,7 +1075,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32  	else  	{  		// add this category -		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat->getParentUUID()); +		LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat->getOwnerID());  		new_cat->copyViewerCategory(cat);  		addCategory(new_cat); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 46c1ffa789..366b9ac034 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -135,7 +135,7 @@ LLLocalBitmap::~LLLocalBitmap()  	}  	// delete self from gimagelist -	LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID); +	LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_DISCARD);  	gTextureList.deleteImage(image);  	if (image) @@ -207,7 +207,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)  					texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);  					texture->ref();  -					gTextureList.addImage(texture); +					gTextureList.addImage(texture, TEX_LIST_DISCARD);  					if (optional_firstupdate != UT_FIRSTUSE)  					{ @@ -215,7 +215,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)  						replaceIDs(old_id, mWorldID);  						// remove old_id from gimagelist -						LLViewerFetchedTexture* image = gTextureList.findImage(old_id); +						LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_DISCARD);  						if (image != NULL)  						{  							gTextureList.deleteImage(image); @@ -384,7 +384,7 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)  {  	std::vector<LLViewerObject*> obj_list; -	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); +	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD);  	for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)  	{ @@ -502,7 +502,7 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)  void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id)  { -	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); +	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD);  	for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++)  	{  		LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter]; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 5510598ae7..fe75ab8e50 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -345,7 +345,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(  					}  					mAvatarNameCacheConnections.erase(it);  				} -				mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle())); +				mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, prefix, item->getHandle()));  				if(mPendingLookupsRemaining <= 0)  				{ @@ -418,6 +418,7 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)  void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,  									   const LLAvatarName& av_name,  									   std::string suffix, +									   std::string prefix,  									   LLHandle<LLNameListItem> item)  {  	avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); @@ -442,6 +443,11 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,  		name.append(suffix);  	} +	if (!prefix.empty()) +	{ +	    name.insert(0, prefix); +	} +  	LLNameListItem* list_item = item.get();  	if (list_item && list_item->getUUID() == agent_id)  	{ diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 19ce3c7aed..677b49e667 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -170,7 +170,7 @@ public:  	/*virtual*/ void mouseOverHighlightNthItem( S32 index );  private:  	void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false); -	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle<LLNameListItem> item); +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);  private:  	S32    			mNameColumnIndex; diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 8cdc2d7c0b..cbcf9cac9c 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -381,7 +381,7 @@ LLGroupNoticeNotificationListItem::LLGroupNoticeNotificationListItem(const Param      buildFromFile("panel_notification_list_item.xml");  } -LLGroupNoticeNotificationListItem::~LLGroupNoticeNotificationListItem() +LLGroupNotificationListItem::~LLGroupNotificationListItem()  {  	LLGroupMgr::getInstance()->removeObserver(this);  } @@ -539,7 +539,6 @@ void LLGroupNoticeNotificationListItem::close()          mInventoryOffer->forceResponse(IOR_DECLINE);          mInventoryOffer = NULL;      } -    LLGroupMgr::getInstance()->removeObserver(this);  }  void LLGroupNoticeNotificationListItem::onClickAttachment() diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h index 9a4ce2be4b..3dd52986b0 100644 --- a/indra/newview/llnotificationlistitem.h +++ b/indra/newview/llnotificationlistitem.h @@ -136,6 +136,7 @@ class LLGroupNotificationListItem      : public LLNotificationListItem, public LLGroupMgrObserver  {  public: +	virtual ~LLGroupNotificationListItem();      virtual BOOL postBuild();      void setGroupId(const LLUUID& value); @@ -192,7 +193,6 @@ class LLGroupNoticeNotificationListItem      : public LLGroupNotificationListItem  {  public: -	~LLGroupNoticeNotificationListItem();      static std::set<std::string> getTypes();      virtual BOOL postBuild(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 21d8b4248c..551495c6ad 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2214,7 +2214,7 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)  				LLTextureEntry *te = object->getTE(te_index);  				if (te)  				{ -					LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL; +					LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL;  					if(!tex)  					{  						tex = LLViewerFetchedTexture::sDefaultImagep; diff --git a/indra/newview/llpanelgroupexperiences.cpp b/indra/newview/llpanelgroupexperiences.cpp index 76b68122fb..2d7690895f 100644 --- a/indra/newview/llpanelgroupexperiences.cpp +++ b/indra/newview/llpanelgroupexperiences.cpp @@ -102,7 +102,7 @@ void LLPanelGroupExperiences::activate()  	}  	// search for experiences owned by the current group -	std::string url = gAgent.getRegion()->getCapability("GroupExperiences");  +	std::string url = (gAgent.getRegion()) ? gAgent.getRegion()->getCapability("GroupExperiences") : LLStringUtil::null;  	if (!url.empty())  	{  		url += "?" + getGroupID().asString(); diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 866cb8dbef..82ea8377de 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -501,25 +501,22 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)  		}  		else  		{ -			//looks like user try to invite offline friend +			//looks like user try to invite offline avatar (or the avatar from the other region)  			//for offline avatar_id gObjectList.findObject() will return null  			//so we need to do this additional search in avatar tracker, see EXT-4732 -			if (LLAvatarTracker::instance().isBuddy(agent_id)) +			LLAvatarName av_name; +			if (!LLAvatarNameCache::get(agent_id, &av_name))  			{ -				LLAvatarName av_name; -				if (!LLAvatarNameCache::get(agent_id, &av_name)) -				{ -					// actually it should happen, just in case -					//LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupInvite::addUserCallback, this, _1, _2)); -					// for this special case! -					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence -					// removed id will be added in callback -					agent_ids.erase(agent_ids.begin() + i); -				} -				else -				{ -					names.push_back(av_name.getAccountName()); -				} +				// actually it should happen, just in case +				//LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupInvite::addUserCallback, this, _1, _2)); +				// for this special case! +				//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence +				// removed id will be added in callback +				agent_ids.erase(agent_ids.begin() + i); +			} +			else +			{ +				names.push_back(av_name.getAccountName());  			}  		}  	} diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 953f234a53..8374eea2e0 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -858,12 +858,17 @@ void LLPanelLogin::onClickConnect(void *)  		// The start location SLURL has already been sent to LLStartUp::setStartSLURL  		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); +		std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();  		if(username.empty())  		{  			// user must type in something into the username field  			LLNotificationsUtil::add("MustHaveAccountToLogIn");  		} +		else if(password.empty()) +		{ +		    LLNotificationsUtil::add("MustEnterPasswordToLogIn"); +		}  		else  		{  			LLPointer<LLCredential> cred; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 01a22df9e1..8331c152e2 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -850,7 +850,7 @@ void LLPanelOutfitEdit::onShopButtonClicked()  		url = url_resolver.resolveURL(LLWearableType::WT_NONE, SEX_FEMALE);  	} -	LLWeb::loadURLExternal(url); +	LLWeb::loadURL(url);  }  LLWearableType::EType LLPanelOutfitEdit::getCOFWearablesSelectionType() const diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index ce9231d6f2..263c73dc0e 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -590,25 +590,49 @@ void LLPanelPermissions::refresh()  																			&next_owner_mask_on,  																			&next_owner_mask_off); -	 +  	if (gSavedSettings.getBOOL("DebugPermissions") )  	{  		if (valid_base_perms)  		{  			getChild<LLUICtrl>("B:")->setValue("B: " + mask_to_string(base_mask_on)); -			getChildView("B:")->setVisible(							TRUE); -			 +			getChildView("B:")->setVisible(TRUE);  			getChild<LLUICtrl>("O:")->setValue("O: " + mask_to_string(owner_mask_on)); -			getChildView("O:")->setVisible(							TRUE); -			 +			getChildView("O:")->setVisible(TRUE);  			getChild<LLUICtrl>("G:")->setValue("G: " + mask_to_string(group_mask_on)); -			getChildView("G:")->setVisible(							TRUE); -			 +			getChildView("G:")->setVisible(TRUE);  			getChild<LLUICtrl>("E:")->setValue("E: " + mask_to_string(everyone_mask_on)); -			getChildView("E:")->setVisible(							TRUE); -			 +			getChildView("E:")->setVisible(TRUE);  			getChild<LLUICtrl>("N:")->setValue("N: " + mask_to_string(next_owner_mask_on)); -			getChildView("N:")->setVisible(							TRUE); +			getChildView("N:")->setVisible(TRUE); +		} +		else if(!root_selected) +		{ +			if(object_count == 1) +			{ +				LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); +				if (node && node->mValid) +				{ +					getChild<LLUICtrl>("B:")->setValue("B: " + mask_to_string( node->mPermissions->getMaskBase())); +					getChildView("B:")->setVisible(TRUE); +					getChild<LLUICtrl>("O:")->setValue("O: " + mask_to_string(node->mPermissions->getMaskOwner())); +					getChildView("O:")->setVisible(TRUE); +					getChild<LLUICtrl>("G:")->setValue("G: " + mask_to_string(node->mPermissions->getMaskGroup())); +					getChildView("G:")->setVisible(TRUE); +					getChild<LLUICtrl>("E:")->setValue("E: " + mask_to_string(node->mPermissions->getMaskEveryone())); +					getChildView("E:")->setVisible(TRUE); +					getChild<LLUICtrl>("N:")->setValue("N: " + mask_to_string(node->mPermissions->getMaskNextOwner())); +					getChildView("N:")->setVisible(TRUE); +				} +			} +		} +		else +		{ +		    getChildView("B:")->setVisible(FALSE); +		    getChildView("O:")->setVisible(FALSE); +		    getChildView("G:")->setVisible(FALSE); +		    getChildView("E:")->setVisible(FALSE); +		    getChildView("N:")->setVisible(FALSE);  		}  		U32 flag_mask = 0x0; diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index f42df221e4..763657ebad 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -314,12 +314,14 @@ void LLPanelPrimMediaControls::updateShape()  	if (objectp)  	{ +		bool hasPermsControl = true;  		bool mini_controls = false;  		LLMediaEntry *media_data = objectp->getTE(mTargetObjectFace)->getMediaData();  		if (media_data && NULL != dynamic_cast<LLVOVolume*>(objectp))  		{  			// Don't show the media controls if we do not have permissions  			enabled = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL); +			hasPermsControl = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL);  			mini_controls = (LLMediaEntry::MINI == media_data->getControls());  		}  		const bool is_hud = objectp->isHUDAttachment(); @@ -562,7 +564,32 @@ void LLPanelPrimMediaControls::updateShape()  			}  		} -		setVisible(enabled); +		// MAINT-1392 If this is a HUD always set it visible, but hide each control if user has no perms. +		// When setting it invisible it won't receive any mouse messages anymore + +		if( !is_hud ) +			setVisible(enabled); +		else +		{ +			if( !hasPermsControl ) +			{ +				mBackCtrl->setVisible(false); +				mFwdCtrl->setVisible(false); +				mReloadCtrl->setVisible(false); +				mStopCtrl->setVisible(false); +				mHomeCtrl->setVisible(false); +				mZoomCtrl->setVisible(false); +				mUnzoomCtrl->setVisible(false); +				mOpenCtrl->setVisible(false); +				mMediaAddressCtrl->setVisible(false); +				mMediaPlaySliderPanel->setVisible(false); +				mVolumeCtrl->setVisible(false); +				mMediaProgressPanel->setVisible(false); +				mVolumeSliderCtrl->setVisible(false); +			} + +			setVisible(true); +		}  		//  		// Calculate position and shape of the controls @@ -767,10 +794,18 @@ void LLPanelPrimMediaControls::draw()  	// ignore space from right bookend padding  	controls_bg_area.mRight -= mRightBookend->getRect().getWidth() - space - 2; -		 +  	// draw control background UI image -	mBackgroundImage->draw( controls_bg_area, UI_VERTEX_COLOR % alpha); +	LLViewerObject* objectp = getTargetObject(); +	LLMediaEntry *media_data(0); + +	if( objectp ) +		media_data = objectp->getTE(mTargetObjectFace)->getMediaData(); + +	if( !dynamic_cast<LLVOVolume*>(objectp) || !media_data || dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL) ) +		mBackgroundImage->draw( controls_bg_area, UI_VERTEX_COLOR % alpha); +  	// draw volume slider background UI image  	if (mVolumeSliderCtrl->getVisible())  	{ diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index f1f87e212d..c9f8683e0e 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -713,7 +713,7 @@ void LLPanelVolume::onLightCancelTexture(const LLSD& data)  	if (LightTextureCtrl)  	{ -		LightTextureCtrl->setImageAssetID(LLUUID::null); +        LightTextureCtrl->setImageAssetID(mLightSavedTexture);  	}  	LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); @@ -722,7 +722,16 @@ void LLPanelVolume::onLightCancelTexture(const LLSD& data)  		// Cancel the light texture as requested  		// NORSPEC-292  		// -		volobjp->setLightTextureID(LLUUID::null); +        bool is_spotlight = volobjp->isLightSpotlight(); +        volobjp->setLightTextureID(mLightSavedTexture); //updates spotlight + +        if (!is_spotlight && mLightSavedTexture.notNull()) +        { +            LLVector3 spot_params = volobjp->getSpotLightParams(); +            getChild<LLUICtrl>("Light FOV")->setValue(spot_params.mV[0]); +            getChild<LLUICtrl>("Light Focus")->setValue(spot_params.mV[1]); +            getChild<LLUICtrl>("Light Ambiance")->setValue(spot_params.mV[2]); +        }  	}  } @@ -821,7 +830,12 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )  				self->getChild<LLUICtrl>("Light Ambiance")->setValue(spot_params.mV[2]);  			}  			else -			{ //modifying existing params +			{ //modifying existing params, this time volobjp won't change params on its own. +                if (volobjp->getLightTextureID() != id) +                { +                    volobjp->setLightTextureID(id); +                } +  				LLVector3 spot_params;  				spot_params.mV[0] = (F32) self->getChild<LLUICtrl>("Light FOV")->getValue().asReal();  				spot_params.mV[1] = (F32) self->getChild<LLUICtrl>("Light Focus")->getValue().asReal(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 1e6a23f365..9c115ee711 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1871,7 +1871,8 @@ LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) :  	mCloseAfterSave(FALSE),  	mPendingUploads(0),  	mIsModifiable(FALSE), -	mIsNew(false) +	mIsNew(false), +	mIsSaving(FALSE)  {  	mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);  } @@ -1912,6 +1913,8 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id,  	LL_DEBUGS() << "LSL Bytecode saved" << LL_ENDL;  	mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful"));  	mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); +	getChild<LLCheckBoxCtrl>("running")->set(is_script_running); +	mIsSaving = FALSE;  	closeIfNeeded();  } @@ -1932,6 +1935,7 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)  		mScriptEd->mErrorList->addElement(row);  	}  	mScriptEd->selectFirstError(); +	mIsSaving = FALSE;  	closeIfNeeded();  } @@ -2159,12 +2163,12 @@ void LLLiveLSLEditor::draw()  		if(object->permAnyOwner())  		{  			runningCheckbox->setLabel(getString("script_running")); -			runningCheckbox->setEnabled(TRUE); +			runningCheckbox->setEnabled(!mIsSaving);  			if(object->permAnyOwner())  			{  				runningCheckbox->setLabel(getString("script_running")); -				runningCheckbox->setEnabled(TRUE); +				runningCheckbox->setEnabled(!mIsSaving);  			}  			else  			{ @@ -2297,6 +2301,7 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/)  	getWindow()->incBusyCount();  	mPendingUploads++;  	BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get(); +	mIsSaving = TRUE;  	if (!url.empty())  	{  		uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running, mScriptEd->getAssociatedExperience()); diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 71ca3e31b1..d6ee692b10 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -308,6 +308,8 @@ private:  	// need to save both text and script, so need to decide when done  	S32					mPendingUploads; +	BOOL                mIsSaving; +  	BOOL getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert  	LLCheckBoxCtrl*	mMonoCheckbox; diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index c8cf0faa15..2a2c51be40 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -89,8 +89,12 @@ LLPreviewTexture::~LLPreviewTexture()  	{  		getWindow()->decBusyCount();  	} -	mImage->setBoostLevel(mImageOldBoostLevel); -	mImage = NULL; + +	if (mImage.notNull()) +	{ +		mImage->setBoostLevel(mImageOldBoostLevel); +		mImage = NULL; +	}  }  // virtual diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 6d94b178dd..ba2c37ce7c 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -36,7 +36,7 @@  #include "llviewerwindow.h"  #include "llfloaterreg.h"  #include "lltrans.h" - +#include "llagent.h"  #include "lldockablefloater.h"  #include "llsyswellwindow.h"  #include "llfloaterimsession.h" @@ -265,7 +265,11 @@ void LLScreenChannel::addToast(const LLToast::Params& p)  	if(!show_toast && !store_toast)  	{ -		LLNotificationPtr notification = LLNotifications::instance().find(p.notif_id); +	    if(gAgent.isDoNotDisturb()) +        { +	        return; +        } +	    LLNotificationPtr notification = LLNotifications::instance().find(p.notif_id);  		if (notification &&  			(!notification->canLogToIM() || !notification->hasFormElements())) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7620046ee3..323689b788 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1628,7 +1628,11 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)  		f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}  		bool apply(LLViewerObject* objectp, S32 te)  		{ -			if (mItem) +		    if(objectp && !objectp->permModify()) +		    { +		        return false; +		    } +		    if (mItem)  			{  				if (te == -1) // all faces  				{ @@ -6742,7 +6746,8 @@ LLBBox LLSelectMgr::getBBoxOfSelection() const  //-----------------------------------------------------------------------------  BOOL LLSelectMgr::canUndo() const  { -	return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG +	// Can edit or can move +	return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstUndoEnabledObject() != NULL; // HACK: casting away constness - MG;  }  //----------------------------------------------------------------------------- @@ -7668,6 +7673,22 @@ LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent)  }  //----------------------------------------------------------------------------- +// getFirstUndoEnabledObject() +//----------------------------------------------------------------------------- +LLViewerObject* LLObjectSelection::getFirstUndoEnabledObject(BOOL get_parent) +{ +    struct f : public LLSelectedNodeFunctor +    { +        bool apply(LLSelectNode* node) +        { +            LLViewerObject* obj = node->getObject(); +            return obj && (obj->permModify() || (obj->permMove() && !obj->isPermanentEnforced())); +        } +    } func; +    return getFirstSelectedObject(&func, get_parent); +} + +//-----------------------------------------------------------------------------  // Position + Rotation update methods called from LLViewerJoystick  //-----------------------------------------------------------------------------  bool LLSelectMgr::selectionMove(const LLVector3& displ, diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 90f7fdfe13..bc50e443f8 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -305,6 +305,7 @@ public:  	LLViewerObject*	getFirstCopyableObject(BOOL get_parent = FALSE);  	LLViewerObject* getFirstDeleteableObject();  	LLViewerObject*	getFirstMoveableObject(BOOL get_parent = FALSE); +	LLViewerObject*	getFirstUndoEnabledObject(BOOL get_parent = FALSE);  	/// Return the object that lead to this selection, possible a child  	LLViewerObject* getPrimaryObject() { return mPrimaryObject; } diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 0e23e2ad10..6743a78dcb 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -452,7 +452,7 @@ void LLSidepanelInventory::onShareButtonClicked()  void LLSidepanelInventory::onShopButtonClicked()  { -	LLWeb::loadURLExternal(gSavedSettings.getString("MarketplaceURL")); +	LLWeb::loadURL(gSavedSettings.getString("MarketplaceURL"));  }  void LLSidepanelInventory::performActionOnSelection(const std::string &action) diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 2548d730f0..403ca7bcbf 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -380,6 +380,10 @@ void LLSidepanelTaskInfo::refresh()  		mDACreatorName->setValue(creator_name);  		mCreatorID = creator_id;  	} +	if(mDACreatorName->getValue().asString() == LLStringUtil::null) +	{ +	    mDACreatorName->setValue(creator_name); +	}  	mDACreatorName->setEnabled(TRUE);  	// Update owner text field @@ -415,6 +419,11 @@ void LLSidepanelTaskInfo::refresh()  		mDAOwnerName->setValue(owner_name);  		mOwnerID = owner_id;  	} +	if(mDAOwnerName->getValue().asString() == LLStringUtil::null) +	{ +	    mDAOwnerName->setValue(owner_name); +	} +  	getChildView("Owner Name")->setEnabled(TRUE);  	// update group text field diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 6d5adc3a43..041eae4b3c 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -164,7 +164,7 @@ BOOL LLStatusBar::postBuild()  	getChild<LLUICtrl>("buyL")->setCommitCallback(  		boost::bind(&LLStatusBar::onClickBuyCurrency, this)); -	getChild<LLUICtrl>("goShop")->setCommitCallback(boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL"))); +    getChild<LLUICtrl>("goShop")->setCommitCallback(boost::bind(&LLWeb::loadURL, gSavedSettings.getString("MarketplaceURL"), LLStringUtil::null, LLStringUtil::null));  	mBoxBalance = getChild<LLTextBox>("balance");  	mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this ); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 5306ee6be0..cb6a04a44e 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2067,11 +2067,18 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  	if (log_texture_traffic && data_size > 0)  	{ -		LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID); -		if (tex) -		{ -			gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ; -		} +        // one worker per multiple textures +        std::vector<LLViewerTexture*> textures; +        LLViewerTextureManager::findTextures(mID, textures); +        std::vector<LLViewerTexture*>::iterator iter = textures.begin(); +        while (iter != textures.end()) +        { +            LLViewerTexture* tex = *iter++; +            if (tex) +            { +                gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size; +            } +        }  	}  	mFetcher->removeFromHTTPQueue(mID, data_size); @@ -4327,26 +4334,33 @@ bool LLTextureFetchDebugger::processStartDebug(F32 max_time)  			fetched_textures.insert(mFetchingHistory[i].mID);  			in_list = false;  		} -		 -		LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID); -		if(tex && tex->isJustBound()) //visible -		{ -			if(!in_list) -			{ -				mNumVisibleFetchedTextures++; -			} -			mNumVisibleFetchingRequests++; -	 -			mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; -			mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; -	 -			if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) -			{ -				mRenderedData += mFetchingHistory[i].mFetchedSize; -				mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; -				mRenderedPixels += tex->getWidth() * tex->getHeight(); -			} -		} + +        std::vector<LLViewerFetchedTexture*> textures; +        LLViewerTextureManager::findFetchedTextures(mFetchingHistory[i].mID, textures); +        std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin(); +        while (iter != textures.end()) +        { +            LLViewerFetchedTexture* tex = *iter++; +            // fetched data will be counted for both ui and regular elements +            if (tex && tex->isJustBound()) //visible +            { +                if (!in_list) +                { +                    mNumVisibleFetchedTextures++; +                } +                mNumVisibleFetchingRequests++; + +                mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; +                mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; + +                if (tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) +                { +                    mRenderedData += mFetchingHistory[i].mFetchedSize; +                    mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; +                    mRenderedPixels += tex->getWidth() * tex->getHeight(); +                } +            } +        }  	}  	mNumFetchedTextures = fetched_textures.size(); @@ -4446,7 +4460,8 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)  			mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();  			mRefetchedAllData += worker->mFormattedImage->getDataSize(); -			LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID); +			// refetch list only requests/creates normal images, so requesting ui='false' +			LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_DISCARD);  			if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end())  			{  				if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) @@ -4673,12 +4688,18 @@ void LLTextureFetchDebugger::debugGLTextureCreation()  	{  		if(mFetchingHistory[i].mRawImage.notNull())  		{ -			LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; -			if(tex && !tex->isForSculptOnly()) -			{ -				tex->destroyGLTexture() ; -				mTempTexList.push_back(tex); -			} +            std::vector<LLViewerFetchedTexture*> textures; +            gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures); +            std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin(); +            while (iter != textures.end()) +            { +                LLViewerFetchedTexture* tex = *iter++; +                if (tex && !tex->isForSculptOnly()) +                { +                    tex->destroyGLTexture(); +                    mTempTexList.push_back(tex); +                } +            }  		}  	} @@ -4733,11 +4754,17 @@ void LLTextureFetchDebugger::clearTextures()  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++)  	{ -		LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; -		if(tex) -		{ -			tex->clearFetchedResults() ; -		} +        std::vector<LLViewerFetchedTexture*> textures; +        gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures); +        std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin(); +        while (iter != textures.end()) +        { +            LLViewerFetchedTexture* tex = *iter++; +            if (tex) +            { +                tex->clearFetchedResults(); +            } +        }  	}  } @@ -4753,6 +4780,8 @@ void LLTextureFetchDebugger::makeRefetchList()  			continue; //the texture fetch pipeline will take care of visible textures.  		} +		// todo: Will attempt to refetch icons and ui elements as normal images (boost_none) +		// thus will create unnecessary LLViewerFetchedTexture, consider supporting separate UI textures  		mRefetchList[tex].push_back(i); 		  	}  } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index a2658ecd85..dc9df71c67 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -540,7 +540,7 @@ private:  	S32 mNbCurlRequests;  	S32 mNbCurlCompleted; -	std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; +	std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; // treats UI textures as normal textures  	std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList;  	S32 mTempIndex;  	S32 mHistoryListIndex; diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index 4aad650b68..5e703933ca 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -38,6 +38,7 @@  #include "lltoolfocus.h"  #include "llfocusmgr.h"  #include "llagent.h" +#include "llagentcamera.h"  #include "llviewerjoystick.h"  extern BOOL gDebugClicks; @@ -84,7 +85,14 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)  	}  	// by default, didn't handle it  	// LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL; -	gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); +    if (gAgentCamera.cameraMouselook()) +    { +        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); +    } +    else +    { +        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); +    }  	return TRUE;  } @@ -95,8 +103,15 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)  		LL_INFOS() << "LLTool left mouse up" << LL_ENDL;  	}  	// by default, didn't handle it -	// LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL; -	gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); +    // LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL; +    if (gAgentCamera.cameraMouselook()) +    { +        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +    } +    else +    { +        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); +    }  	return TRUE;  } diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 76a791c6e9..2b4fa757f6 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -742,12 +742,13 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)  {  -	// if the left button is grabbed, don't put up the pie menu -	if (gAgent.leftButtonGrabbed()) -	{ -		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); -		return FALSE; -	} +    // if the left button is blocked, don't put up the pie menu +    if (gAgent.leftButtonBlocked()) +    { +        // in case of "grabbed" control flag will be set later +        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); +        return FALSE; +    }  	// On mousedown, start grabbing  	gGrabTransientTool = this; @@ -759,12 +760,13 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)  { -	// if the left button is grabbed, don't put up the pie menu -	if (gAgent.leftButtonGrabbed()) -	{ -		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); -		return FALSE; -	} +    // if the left button is blocked, don't put up the pie menu +    if (gAgent.leftButtonBlocked()) +    { +        // in case of "grabbed" control flag will be set later +        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); +        return FALSE; +    }  	// On mousedown, start grabbing  	gGrabTransientTool = this; diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 92e8af985b..c0ca4d7a9a 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -143,7 +143,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)  	// call the base class to propogate info to sim  	LLTool::handleMouseDown(x, y, mask); -	if (!gAgent.leftButtonGrabbed()) +	if (!gAgent.leftButtonBlocked())  	{  		// can grab transparent objects (how touch event propagates, scripters rely on this)  		gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 3ecb4015ce..2f8e464b71 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -400,6 +400,9 @@ void LLToolMgr::clearTransientTool()  void LLToolMgr::onAppFocusLost()  { +	if (LLApp::isQuitting()) +		return; +  	if (mSelectedTool)  	{  		mSelectedTool->handleDeselect(); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index abb9a63238..e17651dc91 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -86,7 +86,8 @@ LLToolPie::LLToolPie()  	mBlockClickToWalk(false),  	mClickAction(0),  	mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ), -	mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ) +	mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ), +	mDoubleClickTimer()  {  } @@ -102,7 +103,12 @@ BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktyp  BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)  { -	mMouseOutsideSlop = FALSE; +    if (mDoubleClickTimer.getStarted()) +    { +        mDoubleClickTimer.stop(); +    } + +    mMouseOutsideSlop = FALSE;  	mMouseDownX = x;  	mMouseDownY = y; @@ -644,7 +650,15 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  { -	LLViewerObject* obj = mPick.getObject(); +    if (!mDoubleClickTimer.getStarted()) +    { +        mDoubleClickTimer.start(); +    } +    else +    { +        mDoubleClickTimer.reset(); +    } +    LLViewerObject* obj = mPick.getObject();  	U8 click_action = final_click_action(obj);  	// let media have first pass at click @@ -738,10 +752,17 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)  		LL_INFOS() << "LLToolPie handleDoubleClick (becoming mouseDown)" << LL_ENDL;  	} -    if (handleMediaDblClick(mPick)) -    { -        return TRUE; -    } +	if (handleMediaDblClick(mPick)) +	{ +		return TRUE; +	} +     +    	if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f)) +	{ +		mDoubleClickTimer.stop(); +		return FALSE; +	} +	mDoubleClickTimer.stop();  	if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))  	{ @@ -754,6 +775,15 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)                                               FALSE /* ignore transparent */,                                               FALSE /* ignore particles */); +        if(mPick.mPickType == LLPickInfo::PICK_OBJECT) +        { +            if (mPick.getObject() && mPick.getObject()->isHUDAttachment()) +            { +                mPick = savedPick; +                return FALSE; +            } +        } +  		if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||  			(mPick.mObjectID.notNull()  && !mPick.mPosGlobal.isExactlyZero()))  		{ diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index c4a2f4a35b..6391e675c5 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -119,6 +119,7 @@ private:  	LLSafeHandle<LLObjectSelection> mLeftClickSelection;  	BOOL				mClickActionBuyEnabled;  	BOOL				mClickActionPayEnabled; +	LLFrameTimer mDoubleClickTimer;  };  #endif diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 5fb99ce02f..2db9c7e67c 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -367,7 +367,7 @@ void LLViewerAssetStorage::_queueDataRequest(  			// Set our destination file, and the completion callback.  			LLTransferTargetParamsVFile tpvf;  			tpvf.setAsset(uuid, atype); -			tpvf.setCallback(downloadCompleteCallback, req); +			tpvf.setCallback(downloadCompleteCallback, *req);  			LL_DEBUGS("AssetStorage") << "Starting transfer for " << uuid << LL_ENDL;  			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index ffae3c0e1f..0b70af44bc 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1660,6 +1660,8 @@ void LLViewerMedia::onTeleportFinished()  {  	// On teleport, clear this setting (i.e. set it to true)  	gSavedSettings.setBOOL("MediaTentativeAutoPlay", true); + +	LLViewerMediaImpl::sMimeTypesFailed.clear();  } @@ -1671,6 +1673,7 @@ void LLViewerMedia::setOnlyAudibleMediaTextureID(const LLUUID& texture_id)  	sForceUpdate = true;  } +std::vector<std::string> LLViewerMediaImpl::sMimeTypesFailed;  //////////////////////////////////////////////////////////////////////////////////////////  // LLViewerMediaImpl  ////////////////////////////////////////////////////////////////////////////////////////// @@ -1943,10 +1946,16 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_  	}  	LL_WARNS_ONCE("Plugin") << "plugin initialization failed for mime type: " << media_type << LL_ENDL; -	LLSD args; -	args["MIME_TYPE"] = media_type; -	LLNotificationsUtil::add("NoPlugin", args); - +	if(gAgent.isInitialized()) +	{ +	    if (std::find(sMimeTypesFailed.begin(), sMimeTypesFailed.end(), media_type) == sMimeTypesFailed.end()) +	    { +	        LLSD args; +	        args["MIME_TYPE"] = media_type; +	        LLNotificationsUtil::add("NoPlugin", args); +	        sMimeTypesFailed.push_back(media_type); +	    } +	}  	return NULL;  } diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index ede408dd0c..268dcae20e 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -469,6 +469,7 @@ private:  	std::string mTarget;  	LLNotificationPtr mNotification;      bool mCleanBrowser;     // force the creation of a clean browsing target with full options enabled +    static std::vector<std::string> sMimeTypesFailed;  private:  	BOOL mIsUpdated ; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a890d64c3a..e605cf1061 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3021,6 +3021,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			{  				send_do_not_disturb_message(msg, from_id);  			} +			else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL)) +			{ +				return; +			}  			else  			{  				LLVector3 pos, look_at; @@ -3952,6 +3956,13 @@ void process_teleport_finish(LLMessageSystem* msg, void**)  		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;  		return;  	} + +    if (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE) +    { +        // Server either ignored teleport cancel message or did not receive it in time. +        // This message can't be ignored since teleport is complete at server side +        gAgent.restoreCanceledTeleportRequest(); +    }  	// Teleport is finished; it can't be cancelled now.  	gViewerWindow->setProgressCancelButtonVisible(FALSE); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 2a6b105cab..aafb6b4d12 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -143,8 +143,8 @@ LLViewerParcelMgr::LLViewerParcelMgr()  	// JC: Resolved a merge conflict here, eliminated  	// mBlockedImage->setAddressMode(LLTexUnit::TAM_WRAP);  	// because it is done in llviewertexturelist.cpp -	mBlockedImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png"); -	mPassImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png"); +	mBlockedImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI); +	mPassImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);  	S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS;  	sPackedOverlay = new U8[overlay_size]; @@ -1453,6 +1453,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  	BOOL	region_deny_identified_override = false; // Deprecated  	BOOL	region_deny_transacted_override = false; // Deprecated  	BOOL	region_deny_age_unverified_override = false; +    BOOL	agent_parcel_update = false; // updating previous(existing) agent parcel  	S32		other_clean_time = 0; @@ -1542,6 +1543,18 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  	// Actually extract the data.  	if (parcel)  	{ +        if (local_id == parcel_mgr.mAgentParcel->getLocalID()) +        { +            // Parcels in different regions can have same ids. +            LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion(msg->getSender()); +            LLViewerRegion* agent_region = gAgent.getRegion(); +            if (parcel_region && agent_region && parcel_region->getRegionID() == agent_region->getRegionID()) +            { +                // we got an updated version of agent parcel +                agent_parcel_update = true; +            } +        } +  		parcel->init(owner_id,  			FALSE, FALSE, FALSE,  			claim_date, claim_price_per_meter, rent_price_per_meter, @@ -1600,16 +1613,10 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  				}  			}  		} -		else if (local_id == parcel_mgr.mAgentParcel->getLocalID()) +		else if (agent_parcel_update)  		{ -			// Parcels in different regions can have same ids. -			LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion( msg->getSender() ); -			LLViewerRegion* agent_region = gAgent.getRegion(); -			if (parcel_region && agent_region && parcel_region->getRegionID() == agent_region->getRegionID()) -			{ -				// updated agent parcel -				parcel_mgr.mAgentParcel->unpackMessage(msg); -			} +			// updated agent parcel +			parcel_mgr.mAgentParcel->unpackMessage(msg);  		}  	} @@ -1752,33 +1759,37 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  		{  			if (parcel)  			{ -				std::string music_url_raw = parcel->getMusicURL(); - -				// Trim off whitespace from front and back -				std::string music_url = music_url_raw; -				LLStringUtil::trim(music_url); - -				// If there is a new music URL and it's valid, play it. -				if (music_url.size() > 12) -				{ -					if (music_url.substr(0,7) == "http://") -					{ -						optionally_start_music(music_url); -					} -					else -					{ -						LL_INFOS() << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL; -						// clears the URL  -						// null value causes fade out -						LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); -					} -				} -				else if (!gAudiop->getInternetStreamURL().empty()) -				{ -					LL_INFOS() << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL; -					// null value causes fade out -					LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); -				} +                // Only update stream if parcel changed (recreated) or music is playing (enabled) +                if (!agent_parcel_update || gSavedSettings.getBOOL("MediaTentativeAutoPlay")) +                { +                    std::string music_url_raw = parcel->getMusicURL(); + +                    // Trim off whitespace from front and back +                    std::string music_url = music_url_raw; +                    LLStringUtil::trim(music_url); + +                    // If there is a new music URL and it's valid, play it. +                    if (music_url.size() > 12) +                    { +                        if (music_url.substr(0, 7) == "http://") +                        { +                            optionally_start_music(music_url); +                        } +                        else +                        { +                            LL_INFOS() << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL; +                            // clears the URL +                            // null value causes fade out +                            LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); +                        } +                    } +                    else if (!gAudiop->getInternetStreamURL().empty()) +                    { +                        LL_INFOS() << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL; +                        // null value causes fade out +                        LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); +                    } +                }  			}  			else  			{ diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 85ae64aeff..09cdfe1309 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -212,12 +212,12 @@ public:  			}  		}  	} -	/*virtual*/ F32				draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +	/*virtual*/ F32				draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect)  	{ -		LLRect image_rect = draw_rect; +		LLRectf image_rect = draw_rect;  		image_rect.mRight = image_rect.mLeft + mImage->getWidth();  		image_rect.mTop = image_rect.mBottom + mImage->getHeight(); -		mImage->draw(image_rect); +		mImage->draw(LLRect(image_rect.mLeft, image_rect.mTop, image_rect.mRight, image_rect.mBottom));  		LLColor4 color;  		if (mEditor.getReadOnly()) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index a957367f61..e2b8ff8e80 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -97,6 +97,7 @@ S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size  const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;  const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez;  const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128; +const S32 DEFAULT_ICON_DIMENTIONS = 32;  S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.  S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;  BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE; @@ -130,7 +131,7 @@ LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,  {  	if(mSourceCallbackList)  	{ -		mSourceCallbackList->insert(target->getID()); +        mSourceCallbackList->insert(LLTextureKey(target->getID(), (ETexListType)target->getTextureListType()));  	}  } @@ -142,7 +143,7 @@ void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex)  {  	if(mSourceCallbackList)  	{ -		mSourceCallbackList->erase(tex->getID()); +		mSourceCallbackList->erase(LLTextureKey(tex->getID(), (ETexListType)tex->getTextureListType()));  	}  } @@ -169,24 +170,39 @@ LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &m  {  	return new LLViewerMediaTexture(media_id, usemipmaps, gl_image);		  } -  -LLViewerTexture*  LLViewerTextureManager::findTexture(const LLUUID& id)  + +void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output)  { -	LLViewerTexture* tex; -	//search fetched texture list -	tex = gTextureList.findImage(id); -	 -	//search media texture list -	if(!tex) -	{ -		tex = LLViewerTextureManager::findMediaTexture(id); -	} -	return tex; +    return gTextureList.findTexturesByID(id, output); +} + +void  LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output) +{ +    std::vector<LLViewerFetchedTexture*> fetched_output; +    gTextureList.findTexturesByID(id, fetched_output); +    std::vector<LLViewerFetchedTexture*>::iterator iter = fetched_output.begin(); +    while (iter != fetched_output.end()) +    { +        output.push_back(*iter); +        iter++; +    } + +    //search media texture list +    if (output.empty()) +    { +        LLViewerTexture* tex; +        tex = LLViewerTextureManager::findMediaTexture(id); +        if (tex) +        { +            output.push_back(tex); +        } +    } +  } -LLViewerFetchedTexture*  LLViewerTextureManager::findFetchedTexture(const LLUUID& id)  +LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id, S32 tex_type)  { -	return gTextureList.findImage(id); +    return gTextureList.findImage(id, (ETexListType)tex_type);  }  LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id) @@ -1178,6 +1194,17 @@ void LLViewerFetchedTexture::loadFromFastCache()  		}  		else  		{ +            if (mBoostLevel == LLGLTexture::BOOST_ICON) +            { +                S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; +                S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; +                if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) +                { +                    // scale oversized icon, no need to give more work to gl +                    mRawImage->scale(expected_width, expected_height); +                } +            } +  			mRequestedDiscardLevel = mDesiredDiscardLevel + 1;  			mIsRawImageValid = TRUE;			  			addToCreateTexture(); @@ -1506,6 +1533,17 @@ void LLViewerFetchedTexture::processTextureStats()  		{  			mDesiredDiscardLevel = 0;  		} +        else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON) +        { +            if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) +            { +                mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 +            } +            else +            { +                mDesiredDiscardLevel = 0; +            } +        }  		else if(!mFullWidth || !mFullHeight)  		{  			mDesiredDiscardLevel = 	llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel); @@ -1936,6 +1974,17 @@ bool LLViewerFetchedTexture::updateFetch()  					addToCreateTexture();  				} +                if (mBoostLevel == LLGLTexture::BOOST_ICON) +                { +                    S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; +                    S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; +                    if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) +                    { +                        // scale oversized icon, no need to give more work to gl +                        mRawImage->scale(expected_width, expected_height); +                    } +                } +  				return TRUE;  			}  			else @@ -2670,7 +2719,7 @@ LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)  	if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)  	{ -		if(mSavedRawDiscardLevel != discard_level) +		if (mSavedRawDiscardLevel != discard_level && mBoostLevel != BOOST_ICON)  		{  			mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());  			mRawImage->copy(getSavedRawImage()); @@ -2771,8 +2820,25 @@ void LLViewerFetchedTexture::switchToCachedImage()  void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)   {  	if(imageraw != mRawImage.get()) -	{ -		mCachedRawImage = imageraw; +    { +        if (mBoostLevel == LLGLTexture::BOOST_ICON) +        { +            S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; +            S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; +            if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) +            { +                mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents()); +                mCachedRawImage->copyScaled(imageraw); +            } +            else +            { +                mCachedRawImage = imageraw; +            } +        } +        else +        { +            mCachedRawImage = imageraw; +        }  		mCachedRawDiscardLevel = discard_level;  		mCachedRawImageReady = TRUE;  	} @@ -2862,7 +2928,24 @@ void LLViewerFetchedTexture::saveRawImage()  	}  	mSavedRawDiscardLevel = mRawDiscardLevel; -	mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); +    if (mBoostLevel == LLGLTexture::BOOST_ICON) +    { +        S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; +        S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; +        if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) +        { +            mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents()); +            mSavedRawImage->copyScaled(mRawImage); +        } +        else +        { +            mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); +        } +    } +    else +    { +        mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); +    }  	if(mForceToSaveRawImage && mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel)  	{ @@ -3239,7 +3322,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL  	setCategory(LLGLTexture::MEDIA); -	LLViewerTexture* tex = gTextureList.findImage(mID); +	LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);  	if(tex) //this media is a parcel media for tex.  	{  		tex->setParcelMedia(this); @@ -3249,7 +3332,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL  //virtual   LLViewerMediaTexture::~LLViewerMediaTexture()   {	 -	LLViewerTexture* tex = gTextureList.findImage(mID); +	LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);  	if(tex) //this media is a parcel media for tex.  	{  		tex->setParcelMedia(NULL); @@ -3304,7 +3387,7 @@ BOOL LLViewerMediaTexture::findFaces()  	BOOL ret = TRUE; -	LLViewerTexture* tex = gTextureList.findImage(mID); +	LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);  	if(tex) //this media is a parcel media for tex.  	{  		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) @@ -3413,7 +3496,7 @@ void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)  	const LLTextureEntry* te = facep->getTextureEntry();  	if(te && te->getID().notNull())  	{ -		LLViewerTexture* tex = gTextureList.findImage(te->getID()); +		LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD);  		if(tex)  		{  			mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it. @@ -3442,7 +3525,7 @@ void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)  	const LLTextureEntry* te = facep->getTextureEntry();  	if(te && te->getID().notNull())  	{ -		LLViewerTexture* tex = gTextureList.findImage(te->getID()); +		LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD);  		if(tex)  		{  			for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin(); @@ -3551,10 +3634,10 @@ void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)  			const LLTextureEntry* te = facep->getTextureEntry();  			if(te)  			{ -				LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL; +				LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL;  				if(!tex && te->getID() != mID)//try parcel media.  				{ -					tex = gTextureList.findImage(mID); +					tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);  				}  				if(!tex)  				{ diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index aed7e94945..cedac44633 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -58,11 +58,12 @@ class LLVFile;  class LLMessageSystem;  class LLViewerMediaImpl ;  class LLVOVolume ; +struct LLTextureKey;  class LLLoadedCallbackEntry  {  public: -	typedef std::set< LLUUID > source_callback_list_t; +    typedef std::set< LLTextureKey > source_callback_list_t;  public:  	LLLoadedCallbackEntry(loaded_callback_func cb, @@ -132,6 +133,8 @@ public:  	/*virtual*/ const LLUUID& getID() const { return mID; }  	void setBoostLevel(S32 level);  	S32  getBoostLevel() { return mBoostLevel; } +	void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } +	S32 getTextureListType() { return mTextureListType; }  	void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;  	void resetTextureStats();	 @@ -185,6 +188,8 @@ private:  	static bool isMemoryForTextureLow() ;  protected:  	LLUUID mID; +	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList +  	F32 mSelectedTime;				// time texture was last selected  	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	  	mutable S32  mMaxVirtualSizeResetCounter ; @@ -626,8 +631,9 @@ public:  	//  	//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.  	// -	static LLViewerTexture*           findTexture(const LLUUID& id) ; -	static LLViewerFetchedTexture*    findFetchedTexture(const LLUUID& id) ; +	static void                       findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output); +	static void                       findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output); +	static LLViewerFetchedTexture*    findFetchedTexture(const LLUUID& id, S32 tex_type);  	static LLViewerMediaTexture*      findMediaTexture(const LLUUID& id) ;  	static LLViewerMediaTexture*      createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 926c40307b..fc6eabd651 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -70,6 +70,29 @@ S32 LLViewerTextureList::sNumImages = 0;  LLViewerTextureList gTextureList;  static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMAGES("Process Images"); +ETexListType get_element_type(S32 priority) +{ +    // don't discard flag can be used in some cases, but it usually is not set yet +    if (priority == LLViewerFetchedTexture::BOOST_ICON +        || priority == LLViewerFetchedTexture::BOOST_UI) +    { +        return TEX_LIST_UI; +    } +    return TEX_LIST_DISCARD; +} + +/////////////////////////////////////////////////////////////////////////////// + +LLTextureKey::LLTextureKey() +: textureId(LLUUID::null), +textureType(TEX_LIST_DISCARD) +{ +} + +LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type) +: textureId(id), textureType(tex_type) +{ +}  /////////////////////////////////////////////////////////////////////////////// @@ -351,7 +374,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&  	if (full_path.empty())  	{  		LL_WARNS() << "Failed to find local image file: " << filename << LL_ENDL; -		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +		LLViewerTexture::EBoostLevel priority = LLGLTexture::BOOST_UI; +		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, priority);  	}  	std::string url = "file://" + full_path; @@ -384,7 +408,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  		new_id.generate(url);  	} -	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id); +	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id, get_element_type(boost_priority));  	if (!imagep.isNull())  	{ @@ -422,12 +446,12 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  			imagep->setExplicitFormat(internal_format, primary_format);  		} -		addImage(imagep); -		 +		addImage(imagep, get_element_type(boost_priority)); +  		if (boost_priority != 0)  		{ -			if (boost_priority == LLViewerFetchedTexture::BOOST_UI || -				boost_priority == LLViewerFetchedTexture::BOOST_ICON) +			if (boost_priority == LLViewerFetchedTexture::BOOST_UI +				|| boost_priority == LLViewerFetchedTexture::BOOST_ICON)  			{  				imagep->dontDiscard();  			} @@ -464,7 +488,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  		return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI));  	} -	LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id); +	LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id, get_element_type(boost_priority));  	if (!imagep.isNull())  	{  		LLViewerFetchedTexture *texture = imagep.get(); @@ -525,13 +549,13 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  	{  		imagep->setExplicitFormat(internal_format, primary_format);  	} -	 -	addImage(imagep); -	 + +	addImage(imagep, get_element_type(boost_priority)); +  	if (boost_priority != 0)  	{ -		if (boost_priority == LLViewerFetchedTexture::BOOST_UI || -			boost_priority == LLViewerFetchedTexture::BOOST_ICON) +		if (boost_priority == LLViewerFetchedTexture::BOOST_UI +			|| boost_priority == LLViewerFetchedTexture::BOOST_ICON)  		{  			imagep->dontDiscard();  		} @@ -553,12 +577,28 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  	return imagep ;  } -LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id) +void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output)  { -	uuid_map_t::iterator iter = mUUIDMap.find(image_id); -	if(iter == mUUIDMap.end()) -		return NULL; -	return iter->second; +    LLTextureKey search_key(image_id, TEX_LIST_DISCARD); +    uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key); +    while (iter != mUUIDMap.end() && iter->first.textureId == image_id) +    { +        output.push_back(iter->second); +        iter++; +    } +} + +LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLTextureKey &search_key) +{ +    uuid_map_t::iterator iter = mUUIDMap.find(search_key); +    if (iter == mUUIDMap.end()) +        return NULL; +    return iter->second; +} + +LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id, ETexListType tex_type) +{ +    return findImage(LLTextureKey(image_id, tex_type));  }  void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) @@ -603,7 +643,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  			<< " but doesn't have mInImageList set"  			<< " ref count is " << image->getNumRefs()  			<< LL_ENDL; -		uuid_map_t::iterator iter = mUUIDMap.find(image->getID()); +		uuid_map_t::iterator iter = mUUIDMap.find(LLTextureKey(image->getID(), (ETexListType)image->getTextureListType()));  		if(iter == mUUIDMap.end())  		{  			LL_INFOS() << "Image  " << image->getID() << " is also not in mUUIDMap!" << LL_ENDL ; @@ -628,7 +668,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  	image->setInImageList(FALSE) ;  } -void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image) +void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type)  {  	if (!new_image)  	{ @@ -636,16 +676,18 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image)  	}  	//llassert(new_image);  	LLUUID image_id = new_image->getID(); +	LLTextureKey key(image_id, tex_type); -	LLViewerFetchedTexture *image = findImage(image_id); +	LLViewerFetchedTexture *image = findImage(key);  	if (image)  	{  		LL_INFOS() << "Image with ID " << image_id << " already in list" << LL_ENDL;  	}  	sNumImages++; -	 +  	addImageToList(new_image); -	mUUIDMap[image_id] = new_image; +	mUUIDMap[key] = new_image; +	new_image->setTextureListType(tex_type);  } @@ -657,8 +699,8 @@ void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)  		{  			mCallbackList.erase(image);  		} - -		llverify(mUUIDMap.erase(image->getID()) == 1); +		LLTextureKey key(image->getID(), (ETexListType)image->getTextureListType()); +		llverify(mUUIDMap.erase(key) == 1);  		sNumImages--;  		removeImageFromList(image);  	} @@ -801,14 +843,14 @@ void LLViewerTextureList::updateImagesDecodePriorities()          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.value()) + 1, MAX_PRIO_UPDATES);  		S32 update_counter = llmin(max_update_count, mUUIDMap.size()); -		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); +		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);  		while ((update_counter-- > 0) && !mUUIDMap.empty())  		{  			if (iter == mUUIDMap.end())  			{  				iter = mUUIDMap.begin(); -			} -			mLastUpdateUUID = iter->first; +            } +            mLastUpdateKey = iter->first;  			LLPointer<LLViewerFetchedTexture> imagep = iter->second;  			++iter; // safe to increment now @@ -1061,7 +1103,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  	update_counter = max_update_count;	  	if(update_counter > 0)  	{ -		uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); +		uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey);  		while ((update_counter > 0) && (total_update_count > 0))  		{  			if (iter2 == mUUIDMap.end()) @@ -1091,7 +1133,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  		fetch_count += (imagep->updateFetch() ? 1 : 0);  		if (min_count <= min_update_count)  		{ -			mLastFetchUUID = imagep->getID(); +			mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());  		}  		if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))  		{ @@ -1543,12 +1585,19 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **  	LLUUID image_id;  	msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id); -	LLViewerFetchedTexture* image = gTextureList.findImage( image_id ); +	LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_DISCARD);  	if( image )  	{ -		LL_WARNS() << "not in db" << LL_ENDL; +		LL_WARNS() << "Image not in db" << LL_ENDL;  		image->setIsMissingAsset();  	} + +    image = gTextureList.findImage(image_id, TEX_LIST_UI); +    if (image) +    { +        LL_WARNS() << "Icon not in db" << LL_ENDL; +        image->setIsMissingAsset(); +    }  } @@ -1630,14 +1679,18 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st  	//don't compress UI images  	imagep->getGLTexture()->setAllowCompression(false); -	//all UI images are non-deletable -	imagep->setNoDelete(); -  	LLUIImagePtr new_imagep = new LLUIImage(name, imagep);  	new_imagep->setScaleStyle(scale_style); -	mUIImages.insert(std::make_pair(name, new_imagep)); -	mUITextureList.push_back(imagep); +	if (imagep->getBoostLevel() != LLGLTexture::BOOST_ICON && +		imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW) +	{ +		// Don't add downloadable content into this list +		// all UI images are non-deletable and list does not support deletion +		imagep->setNoDelete(); +		mUIImages.insert(std::make_pair(name, new_imagep)); +		mUITextureList.push_back(imagep); +	}  	//Note:  	//Some other textures such as ICON also through this flow to be fetched. diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index fbbfe9a7d4..9f94f2f1bc 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -59,6 +59,32 @@ typedef	void (*LLImageCallback)(BOOL success,  								BOOL final,  								void* userdata); +enum ETexListType +{ +    TEX_LIST_DISCARD = 0, +    TEX_LIST_UI +}; + +struct LLTextureKey +{ +    LLTextureKey(); +    LLTextureKey(LLUUID id, ETexListType tex_type); +    LLUUID textureId; +    ETexListType textureType; + +    friend bool operator<(const LLTextureKey& key1, const LLTextureKey& key2) +    { +        if (key1.textureId != key2.textureId) +        { +            return key1.textureId < key2.textureId; +        } +        else +        { +            return key1.textureType < key2.textureType; +        } +    } +}; +  class LLViewerTextureList  {  	friend class LLTextureView; @@ -83,7 +109,9 @@ public:  	void restoreGL();  	BOOL isInitialized() const {return mInitialized;} -	LLViewerFetchedTexture *findImage(const LLUUID &image_id); +	void findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output); +	LLViewerFetchedTexture *findImage(const LLUUID &image_id, ETexListType tex_type); +	LLViewerFetchedTexture *findImage(const LLTextureKey &search_key);  	void dirtyImage(LLViewerFetchedTexture *image); @@ -120,7 +148,7 @@ private:  	void updateImagesUpdateStats();  	F32  updateImagesLoadingFastCache(F32 max_time); -	void addImage(LLViewerFetchedTexture *image); +	void addImage(LLViewerFetchedTexture *image, ETexListType tex_type);  	void deleteImage(LLViewerFetchedTexture *image);  	void addImageToList(LLViewerFetchedTexture *image); @@ -184,10 +212,10 @@ public:  	BOOL mForceResetTextureStats;  private: -	typedef std::map< LLUUID, LLPointer<LLViewerFetchedTexture> > uuid_map_t; -	uuid_map_t mUUIDMap; -	LLUUID mLastUpdateUUID; -	LLUUID mLastFetchUUID; +    typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t; +    uuid_map_t mUUIDMap; +    LLTextureKey mLastUpdateKey; +    LLTextureKey mLastFetchKey;  	typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;	  	image_priority_list_t mImageList; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 00cfce12cf..2555073926 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1989,7 +1989,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU  		uuid == IMG_INVISIBLE)  	{  		// Should already exist, don't need to find it on sim or baked-texture host. -		result = gTextureList.findImage(uuid); +		result = gTextureList.findImage(uuid, TEX_LIST_DISCARD);  	}  	if (!result)  	{ @@ -4263,7 +4263,7 @@ bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const  {  	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)  	{ -		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);  		if (imagep && imagep->getDiscardLevel()!=0)  		{  			return false; @@ -4335,7 +4335,7 @@ S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)  	S32Bytes result(0);  	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)  	{ -		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);  		if (imagep)  		{  			result += imagep->getTextureMemory(); @@ -4423,7 +4423,7 @@ void LLVOAvatar::releaseOldTextures()  	{  		if (new_texture_ids.find(*it) == new_texture_ids.end())  		{ -			LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); +			LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);  			if (imagep)  			{  				current_texture_mem += imagep->getTextureMemory(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 44daa939ad..8f0b233f01 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2115,6 +2115,8 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)  	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)  	{  		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); +		if (cur_material.isNull()) +			continue;  		switch(range_it->second.map)  		{ @@ -3909,7 +3911,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&  	if (mDrawable->isState(LLDrawable::RIGGED))  	{ -		if ((pick_rigged) || ((getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) +		if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))  		{  			updateRiggedVolume(true);  			volume = mRiggedVolume; diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 7b5bcf4db0..2782cd9545 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -124,11 +124,17 @@ void LLWatchdogTimeout::setTimeout(F32 d)  void LLWatchdogTimeout::start(const std::string& state)   { -	// Order of operation is very impmortant here. +    if (mTimeout == 0) +    { +        LL_WARNS() << "Cant' start watchdog entry - no timeout set" << LL_ENDL; +        return; +    } +	// Order of operation is very important here.  	// After LLWatchdogEntry::start() is called  	// LLWatchdogTimeout::isAlive() will be called asynchronously.   	ping(state); -	mTimer.start();  +	mTimer.start(); +    mTimer.setTimerExpirySec(mTimeout); // timer expiration set to 0 by start()  	LLWatchdogEntry::start();  } @@ -235,7 +241,6 @@ void LLWatchdog::run()  				mSuspects.end(),   				std::not1(std::mem_fun(&LLWatchdogEntry::isAlive))  				); -  		if(result != mSuspects.end())  		{  			// error!!! diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index df4b1a8a50..18a30f083b 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -421,7 +421,7 @@ public:  			MASK_BODYPART		= 0x02,  			MASK_ATTACHMENT		= 0x04,  			MASK_GESTURE		= 0x08, -			MASK_UNKNOWN		= 0x16, +			MASK_UNKNOWN		= 0x10,  		};  		/* virtual */ LLContextMenu* createMenu(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 5d657f7eef..11d3706821 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1281,7 +1281,7 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi  	{  		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter; -		if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy) +		if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy && !pVOAvatar->isOrphaned())  		{  			LLVector3d pos_global = pVOAvatar->getPositionGlobal();  			LLUUID uuid = pVOAvatar->getID(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index a4d41164e5..af29a1751a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6115,7 +6115,9 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)  			const Light* light = &(*iter);  			LLDrawable* drawable = light->drawable;              const LLViewerObject *vobj = light->drawable->getVObj(); -            if(vobj && vobj->getAvatar() && vobj->getAvatar()->isTooComplex()) +            if(vobj && vobj->getAvatar()  +               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()) +               )              {                  drawable->clearState(LLDrawable::NEARBY_LIGHT);                  continue; @@ -8664,6 +8666,11 @@ void LLPipeline::renderDeferredLighting()  						}  					} +					const LLViewerObject *vobj = drawablep->getVObj(); +					if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList()) +					{ +						continue; +					}  					LLVector4a center;  					center.load3(drawablep->getPositionAgent().mV); diff --git a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml index c17d2a1f37..b5ae9db7e9 100644 --- a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml +++ b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml @@ -136,16 +136,16 @@      </tab_container>      <layout_stack width="336" height="26" enabled="true" orientation="horizontal"  follows="left|right" name="ButtonsStack"> -      <layout_panel width="336" height="30" enabled="true" name="CondenseAllButtonPanel"> +      <layout_panel width="93" height="30" enabled="true" name="CondenseAllButtonPanel">          <button width="93" height="21" left="2" label="Collapse all" name="collapse_all_button">          </button>        </layout_panel> -      <layout_panel width="336" height="30" enabled="true" name="GapLayoutPanel"> +      <layout_panel width="93" height="30" enabled="true" name="GapLayoutPanel">          <panel width="90" height="21" left="2" label="Gap Panel" border="false" name="GapPanel">          </panel>        </layout_panel> -      <layout_panel width="336" height="30" enabled="true" name="DeleteAllButtonPanel"> -        <button width="93" height="21" left="2" label="Delete all" name="delete_all_button"> +      <layout_panel width="100" height="30" enabled="true" name="DeleteAllButtonPanel"> +        <button width="93" height="21" left="0" label="Delete all" follows="right" name="delete_all_button">          </button>        </layout_panel>      </layout_stack> diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index ebbb53729d..170b7177fb 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -14,6 +14,7 @@        <file>ヒラギノ角ゴ ProN W3.otf</file>        <file>AppleGothic.dfont</file>        <file>AppleGothic.ttf</file> +      <file>AppleSDGothicNeo-Regular.otf</file>        <file>华文细黑.ttf</file>      </os>    </font> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 271061a0ec..5153c62885 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1222,6 +1222,14 @@ You can not wear that item because it has not yet loaded. Please try again in a    <tag>fail</tag>    </notification> +    <notification +   icon="alertmodal.tga" +   name="MustEnterPasswordToLogIn" +   type="alertmodal"> +   <tag>fail</tag> +Please enter your Password to log in. +  </notification> +      <notification     icon="alertmodal.tga"     name="MustHaveAccountToLogIn" @@ -4164,7 +4172,6 @@ Leave Group?    </notification>    <notification -   icon="alert.tga"     name="GroupDepartError"     type="alert">  Unable to leave group: [reason]. diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml index 10907344ae..79493d3885 100644 --- a/indra/newview/skins/default/xui/es/floater_about_land.xml +++ b/indra/newview/skins/default/xui/es/floater_about_land.xml @@ -353,10 +353,10 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.  				Foto:  			</text>  			<texture_picker label="" name="snapshot_ctrl" tool_tip="Pulse para elegir una imagen"/> -			<text name="allow_label5"> +			<text name="allow_label5" top="170">  				Los avatares de otras parcelas pueden ver a los avatares de esta parcela y chatear con ellos  			</text> -			<check_box label="Ver los avatares" name="SeeAvatarsCheck" tool_tip="Permite que los avatares de otras parcelas vean a los avatares de ésta y chateen con ellos, y también que tú puedas verles y chatear con ellos."/> +			<check_box label="Ver los avatares" name="SeeAvatarsCheck" top="170" tool_tip="Permite que los avatares de otras parcelas vean a los avatares de ésta y chateen con ellos, y también que tú puedas verles y chatear con ellos."/>  			<text name="landing_point">  				Punto de llegada: [LANDING]  			</text> | 
