diff options
| author | Oz Linden <oz@lindenlab.com> | 2011-01-21 15:29:40 -0500 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2011-01-21 15:29:40 -0500 | 
| commit | 790dfe7556a476b502ef3a0ea921efdd11735f28 (patch) | |
| tree | 3db004c2acdfcf32f01abbf284e6dbd67c61a4c8 | |
| parent | 6a3d06deca73683514d4668f78adf684d760708c (diff) | |
| parent | 4652e26196ed43e3a2fdd5bbb2e6c4b6b8466719 (diff) | |
merge changes for storm-844
84 files changed, 1516 insertions, 676 deletions
| @@ -43,3 +43,11 @@ dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1  25bd6007e3d2fc15db9326ed4b18a24a5969a46a 2.4.0-beta2  1ed382c6a08ba3850b6ce9061bc551ddece0ea07 2.4.0-release  a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start +76f586a8e22b1abe6b2339758c8ac0fa718975de 76f586a8e22b +76f586a8e22b1abe6b2339758c8ac0fa718975de 76f586a8e22b +0000000000000000000000000000000000000000 76f586a8e22b +0000000000000000000000000000000000000000 76f586a8e22b +345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b +345b17e7cf630db77e840b4fe3451bd476d750a3 2.5.0-beta1 +345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b +0000000000000000000000000000000000000000 76f586a8e22b diff --git a/doc/contributions.txt b/doc/contributions.txt index 42e030ac66..70ae5a2ba5 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -72,6 +72,7 @@ Aleric Inglewood  	VWR-10837  	VWR-12691  	VWR-12984 +	VWR-13040  	VWR-13996  	VWR-14426  	VWR-24247 @@ -79,6 +80,9 @@ Aleric Inglewood  	VWR-24252  	VWR-24254  	VWR-24261 +	VWR-24315 +	VWR-24317 +	VWR-24320  	SNOW-84  	SNOW-477  	SNOW-744 @@ -366,15 +370,18 @@ JB Kraft  Joghert LeSabre  	VWR-64  Jonathan Yap -	STORM-596  	STORM-523 +	STORM-596 +	STORM-615  	STORM-616  	STORM-679 -	STORM-737 +	STORM-723  	STORM-726 +	STORM-737 +	STORM-869 +	STORM-785  	STORM-812  	VWR-17801 -	STORM-785  	STORM-844  Kage Pixel  	VWR-11 @@ -392,6 +399,7 @@ Kitty Barnett  	STORM-288  	STORM-799  	STORM-800 +    VWR-24217  Kunnis Basiat  	VWR-82  	VWR-102 @@ -735,6 +743,7 @@ Thickbrick Sleaford  	VWR-9287  	VWR-13483  	VWR-13947 +	VWR-24420  Thraxis Epsilon  	SVC-371  	VWR-383 diff --git a/etc/message.xml b/etc/message.xml index 7c4a927cc5..764aea3879 100644 --- a/etc/message.xml +++ b/etc/message.xml @@ -678,20 +678,17 @@  			<key>EstateChangeInfo</key>  			<boolean>true</boolean> -			<key>FetchInventoryDescendents</key> +			<key>FetchInventoryDescendents2</key>  			<boolean>false</boolean> -			<key>WebFetchInventoryDescendents</key> -			<boolean>true</boolean> -		 -			<key>FetchInventory</key> -			<boolean>true</boolean> +			<key>FetchInventory2</key> +			<boolean>false</boolean> -			<key>FetchLibDescendents</key> -			<boolean>true</boolean> +			<key>FetchLibDescendents2</key> +			<boolean>false</boolean> -			<key>FetchLib</key> -			<boolean>true</boolean> +			<key>FetchLib2</key> +			<boolean>false</boolean>  			<key>UploadBakedTexture</key>  			<boolean>true</boolean> diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index c9cb1cd6e7..5e540ad8c5 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -97,7 +97,11 @@ void LLAudioEngine::setDefaults()  	}  	mMasterGain = 1.f; -	mInternalGain = 0.f; +	// Setting mInternalGain to an out of range value fixes the issue reported in STORM-830. +	// There is an edge case in setMasterGain during startup which prevents setInternalGain from  +	// being called if the master volume setting and mInternalGain both equal 0, so using -1 forces +	// the if statement in setMasterGain to execute when the viewer starts up. +	mInternalGain = -1.f;  	mNextWindUpdate = 0.f;  	mStreamingAudioImpl = NULL; diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index b1ec9e9875..ad1845d387 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -48,7 +48,7 @@ LLAvatarName::LLAvatarName()  	mLegacyFirstName(),  	mLegacyLastName(),  	mIsDisplayNameDefault(false), -	mIsDummy(false), +	mIsTemporaryName(false),  	mExpires(F64_MAX),  	mNextUpdate(0.0)  { } diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 145aeccd35..ba258d6d52 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -79,7 +79,7 @@ public:  	// Under error conditions, we may insert "dummy" records with  	// names like "???" into caches as placeholders.  These can be  	// shown in UI, but are not serialized. -	bool mIsDummy; +	bool mIsTemporaryName;  	// Names can change, so need to keep track of when name was  	// last checked. diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 8f02391e75..c32a776c3f 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -92,6 +92,17 @@ LLFILE*	LLFile::_fsopen(const std::string& filename, const char* mode, int shari  #endif  } +int	LLFile::close(LLFILE * file) +{ +	int ret_value = 0; +	if (file) +	{ +		ret_value = fclose(file); +	} +	return ret_value; +} + +  int	LLFile::remove(const std::string& filename)  {  #if	LL_WINDOWS diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 4913af7cb5..dd7d36513a 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -71,6 +71,8 @@ public:  	static	LLFILE*	fopen(const std::string& filename,const char* accessmode);	/* Flawfinder: ignore */  	static	LLFILE*	_fsopen(const std::string& filename,const char* accessmode,int	sharingFlag); +	static	int		close(LLFILE * file); +  	// perms is a permissions mask like 0777 or 0700.  In most cases it will  	// be overridden by the user's umask.  It is ignored on Windows.  	static	int		mkdir(const std::string& filename, int perms = 0700); diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index fe737e2072..2cc7d3c460 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -50,8 +50,6 @@ LLPngWrapper::LLPngWrapper()  	  mCompressionType( 0 ),  	  mFilterMethod( 0 ),  	  mFinalSize( 0 ), -	  mHasBKGD(false), -	  mBackgroundColor(),  	  mGamma(0.f)  {  } @@ -111,9 +109,9 @@ void LLPngWrapper::writeFlush(png_structp png_ptr)  }  // Read the PNG file using the libpng.  The low-level interface is used here -// because we want to do various transformations (including setting the -// matte background if any, and applying gama) which can't be done with -// the high-level interface. The scanline also begins at the bottom of +// because we want to do various transformations (including applying gama) +// which can't be done with the high-level interface. +// The scanline also begins at the bottom of  // the image (per SecondLife conventions) instead of at the top, so we  // must assign row-pointers in "reverse" order.  BOOL LLPngWrapper::readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop) @@ -201,8 +199,7 @@ void LLPngWrapper::normalizeImage()  	//		2. Convert grayscales to RGB  	//		3. Create alpha layer from transparency  	//		4. Ensure 8-bpp for all images -	//		5. Apply background matte if any -	//		6. Set (or guess) gamma +	//		5. Set (or guess) gamma  	if (mColorType == PNG_COLOR_TYPE_PALETTE)  	{ @@ -229,12 +226,6 @@ void LLPngWrapper::normalizeImage()  	{  		png_set_strip_16(mReadPngPtr);  	} -	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor); -	if (mHasBKGD) -	{ -		png_set_background(mReadPngPtr, mBackgroundColor, -			PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); -	}  #if LL_DARWIN  	const F64 SCREEN_GAMMA = 1.8; @@ -261,7 +252,6 @@ void LLPngWrapper::updateMetaData()      mBitDepth = png_get_bit_depth(mReadPngPtr, mReadInfoPtr);      mColorType = png_get_color_type(mReadPngPtr, mReadInfoPtr);  	mChannels = png_get_channels(mReadPngPtr, mReadInfoPtr); -	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor);  }  // Method to write raw image into PNG at dest. The raw scanline begins diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 47a4207d66..739f435996 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -88,9 +88,6 @@ private:  	U32 mFinalSize; -	bool mHasBKGD; -	png_color_16p mBackgroundColor; -  	F64 mGamma;  	std::string mErrorMessage; diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 03c28eb2a5..767001b633 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -81,8 +81,11 @@ namespace LLAvatarNameCache  	// only need per-frame timing resolution  	LLFrameTimer sRequestTimer; -	// Periodically clean out expired entries from the cache -	//LLFrameTimer sEraseExpiredTimer; +    /// Maximum time an unrefreshed cache entry is allowed +    const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; + +    /// Time when unrefreshed cached names were checked last +    static F64 sLastExpireCheck;  	//-----------------------------------------------------------------------  	// Internal methods @@ -99,8 +102,9 @@ namespace LLAvatarNameCache  	// Legacy name system callback  	void legacyNameCallback(const LLUUID& agent_id, -		const std::string& full_name, -		bool is_group); +							const std::string& full_name, +							bool is_group +							);  	void requestNamesViaLegacy(); @@ -117,7 +121,7 @@ namespace LLAvatarNameCache  	bool isRequestPending(const LLUUID& agent_id);  	// Erase expired names from cache -	void eraseExpired(); +	void eraseUnrefreshed();  	bool expirationFromCacheControl(LLSD headers, F64 *expires);  } @@ -187,6 +191,7 @@ public:  	{  		// Pull expiration out of headers if available  		F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mHeaders); +		F64 now = LLFrameTimer::getTotalSeconds();  		LLSD agents = content["agents"];  		LLSD::array_const_iterator it = agents.beginArray(); @@ -207,84 +212,91 @@ public:  				av_name.mDisplayName = av_name.mUsername;  			} +			LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " " +									 << "user '" << av_name.mUsername << "' " +									 << "display '" << av_name.mDisplayName << "' " +									 << "expires in " << expires - now << " seconds" +									 << LL_ENDL; +			  			// cache it and fire signals  			LLAvatarNameCache::processName(agent_id, av_name, true);  		}  		// Same logic as error response case  		LLSD unresolved_agents = content["bad_ids"]; -		if (unresolved_agents.size() > 0) +		S32  num_unresolved = unresolved_agents.size(); +		if (num_unresolved > 0)  		{ -			const std::string DUMMY_NAME("\?\?\?"); -			LLAvatarName av_name; -			av_name.mUsername = DUMMY_NAME; -			av_name.mDisplayName = DUMMY_NAME; -			av_name.mIsDisplayNameDefault = false; -			av_name.mIsDummy = true; -			av_name.mExpires = expires; - +            LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; " +                                    << "expires in " << expires - now << " seconds" +                                    << LL_ENDL;  			it = unresolved_agents.beginArray();  			for ( ; it != unresolved_agents.endArray(); ++it)  			{  				const LLUUID& agent_id = *it; -				// cache it and fire signals -				LLAvatarNameCache::processName(agent_id, av_name, true); + +				LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " +                                        << "failed id " << agent_id +                                        << LL_ENDL; + +                LLAvatarNameCache::handleAgentError(agent_id);  			}  		} -	} +        LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "  +                                 << LLAvatarNameCache::sCache.size() << " cached names" +                                 << LL_ENDL; +    }  	/*virtual*/ void error(U32 status, const std::string& reason)  	{  		// If there's an error, it might be caused by PeopleApi,  		// or when loading textures on startup and using a very slow  -		// network, this query may time out. Fallback to the legacy -		// cache.  - -		llwarns << "LLAvatarNameResponder error " << status << " " << reason << llendl; +		// network, this query may time out. +		// What we should do depends on whether or not we have a cached name +		LL_WARNS("AvNameCache") << "LLAvatarNameResponder::error " << status << " " << reason +								<< LL_ENDL; -		// Add dummy records for all agent IDs in this request +		// Add dummy records for any agent IDs in this request that we do not have cached already  		std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();  		for ( ; it != mAgentIDs.end(); ++it)  		{  			const LLUUID& agent_id = *it; -			gCacheName->get(agent_id, false,  // legacy compatibility -						boost::bind(&LLAvatarNameCache::legacyNameCallback, -						_1, _2, _3)); -		} -	} - -	// Return time to retry a request that generated an error, based on -	// error type and headers.  Return value is seconds-since-epoch. -	F64 errorRetryTimestamp(S32 status) -	{ -		F64 now = LLFrameTimer::getTotalSeconds(); - -		// Retry-After takes priority -		LLSD retry_after = mHeaders["retry-after"]; -		if (retry_after.isDefined()) -		{ -			// We only support the delta-seconds type -			S32 delta_seconds = retry_after.asInteger(); -			if (delta_seconds > 0) -			{ -				// ...valid delta-seconds -				return now + F64(delta_seconds); -			} +			LLAvatarNameCache::handleAgentError(agent_id);  		} - -		// If no Retry-After, look for Cache-Control max-age -		F64 expires = 0.0; -		if (LLAvatarNameCache::expirationFromCacheControl(mHeaders, &expires)) -		{ -			return expires; -		} - -		// No information in header, make a guess -		const F64 DEFAULT_DELAY = 120.0; // 2 mintues -		return now + DEFAULT_DELAY;  	}  }; +// Provide some fallback for agents that return errors +void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) +{ +	std::map<LLUUID,LLAvatarName>::iterator existing = sCache.find(agent_id); +	if (existing == sCache.end()) +    { +        // there is no existing cache entry, so make a temporary name from legacy +        LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent " +                                << agent_id << LL_ENDL; +        gCacheName->get(agent_id, false,  // legacy compatibility +                        boost::bind(&LLAvatarNameCache::legacyNameCallback, +                                    _1, _2, _3)); +    } +	else +    { +        // we have a chached (but probably expired) entry - since that would have +        // been returned by the get method, there is no need to signal anyone + +        // Clear this agent from the pending list +        LLAvatarNameCache::sPendingQueue.erase(agent_id); + +        const LLAvatarName& av_name = existing->second; +        LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " +                                 << agent_id  +                                 << "user '" << av_name.mUsername << "' " +                                 << "display '" << av_name.mDisplayName << "' " +                                 << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds" +                                 << LL_ENDL; +    } +} +  void LLAvatarNameCache::processName(const LLUUID& agent_id,  									const LLAvatarName& av_name,  									bool add_to_cache) @@ -326,6 +338,7 @@ void LLAvatarNameCache::requestNamesViaCapability()  	std::vector<LLUUID> agent_ids;  	agent_ids.reserve(128); +	U32 ids = 0;  	ask_queue_t::const_iterator it = sAskQueue.begin();  	for ( ; it != sAskQueue.end(); ++it)  	{ @@ -336,11 +349,13 @@ void LLAvatarNameCache::requestNamesViaCapability()  			// ...starting new request  			url += sNameLookupURL;  			url += "?ids="; +			ids = 1;  		}  		else  		{  			// ...continuing existing request  			url += "&ids="; +			ids++;  		}  		url += agent_id.asString();  		agent_ids.push_back(agent_id); @@ -350,8 +365,10 @@ void LLAvatarNameCache::requestNamesViaCapability()  		if (url.size() > NAME_URL_SEND_THRESHOLD)  		{ -			//llinfos << "requestNames " << url << llendl; -			LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));//, LLSD(), 10.0f); +			LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first " +									 << ids << " ids" +									 << LL_ENDL; +			LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));  			url.clear();  			agent_ids.clear();  		} @@ -359,8 +376,10 @@ void LLAvatarNameCache::requestNamesViaCapability()  	if (!url.empty())  	{ -		//llinfos << "requestNames " << url << llendl; -		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));//, LLSD(), 10.0f); +		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all " +								 << ids << " ids" +								 << LL_ENDL; +		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));  		url.clear();  		agent_ids.clear();  	} @@ -376,6 +395,11 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,  	// Construct a dummy record for this name.  By convention, SLID is blank  	// Never expires, but not written to disk, so lasts until end of session.  	LLAvatarName av_name; +	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback " +							 << "agent " << agent_id << " " +							 << "full name '" << full_name << "'" +							 << ( is_group ? " [group]" : "" ) +							 << LL_ENDL;  	buildLegacyName(full_name, &av_name);  	// Don't add to cache, the data already exists in the legacy name system @@ -397,6 +421,8 @@ void LLAvatarNameCache::requestNamesViaLegacy()  		// invoked below.  This should never happen in practice.  		sPendingQueue[agent_id] = now; +		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL; +  		gCacheName->get(agent_id, false,  // legacy compatibility  			boost::bind(&LLAvatarNameCache::legacyNameCallback,  				_1, _2, _3)); @@ -435,21 +461,24 @@ void LLAvatarNameCache::importFile(std::istream& istr)  		av_name.fromLLSD( it->second );  		sCache[agent_id] = av_name;  	} -	// entries may have expired since we last ran the viewer, just -	// clean them out now -	eraseExpired(); -	llinfos << "loaded " << sCache.size() << llendl; +    LL_INFOS("AvNameCache") << "loaded " << sCache.size() << LL_ENDL; + +	// Some entries may have expired since the cache was stored, +    // but they will be flushed in the first call to eraseUnrefreshed +    // from LLAvatarNameResponder::idle  }  void LLAvatarNameCache::exportFile(std::ostream& ostr)  {  	LLSD agents; +	F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME;  	cache_t::const_iterator it = sCache.begin();  	for ( ; it != sCache.end(); ++it)  	{  		const LLUUID& agent_id = it->first;  		const LLAvatarName& av_name = it->second; -		if (!av_name.mIsDummy) +		// Do not write temporary or expired entries to the stored cache +		if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)  		{  			// key must be a string  			agents[agent_id.asString()] = av_name.asLLSD(); @@ -484,62 +513,63 @@ void LLAvatarNameCache::idle()  	//	return;  	//} -	// Must be large relative to above - -	// No longer deleting expired entries, just re-requesting in the get -	// this way first synchronous get call on an expired entry won't return -	// legacy name.  LF - -	//const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds -	//if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT)) -	//{ -	//	eraseExpired(); -	//} - -	if (sAskQueue.empty()) +	if (!sAskQueue.empty())  	{ -		return; +        if (useDisplayNames()) +        { +            requestNamesViaCapability(); +        } +        else +        { +            // ...fall back to legacy name cache system +            requestNamesViaLegacy(); +        }  	} -	if (useDisplayNames()) -	{ -		requestNamesViaCapability(); -	} -	else -	{ -		// ...fall back to legacy name cache system -		requestNamesViaLegacy(); -	} +    // erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME +    eraseUnrefreshed();  }  bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)  { +	bool isPending = false;  	const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; -	F64 now = LLFrameTimer::getTotalSeconds(); -	F64 expire_time = now - PENDING_TIMEOUT_SECS;  	pending_queue_t::const_iterator it = sPendingQueue.find(agent_id);  	if (it != sPendingQueue.end())  	{ -		bool request_expired = (it->second < expire_time); -		return !request_expired; +		// in the list of requests in flight, retry if too old +		F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; +		isPending = (it->second > expire_time);  	} -	return false; +	return isPending;  } -void LLAvatarNameCache::eraseExpired() +void LLAvatarNameCache::eraseUnrefreshed()  {  	F64 now = LLFrameTimer::getTotalSeconds(); -	cache_t::iterator it = sCache.begin(); -	while (it != sCache.end()) -	{ -		cache_t::iterator cur = it; -		++it; -		const LLAvatarName& av_name = cur->second; -		if (av_name.mExpires < now) -		{ -			sCache.erase(cur); -		} +	F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME; + +    if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed) +    { +        sLastExpireCheck = now; +        cache_t::iterator it = sCache.begin(); +        while (it != sCache.end()) +        { +            cache_t::iterator cur = it; +            ++it; +            const LLAvatarName& av_name = cur->second; +            if (av_name.mExpires < max_unrefreshed) +            { +                const LLUUID& agent_id = it->first; +                LL_DEBUGS("AvNameCache") << agent_id  +                                         << " user '" << av_name.mUsername << "' " +                                         << "expired " << now - av_name.mExpires << " secs ago" +                                         << LL_ENDL; +                sCache.erase(cur); +            } +        } +        LL_INFOS("AvNameCache") << sCache.size() << " cached avatar names" << LL_ENDL;  	}  } @@ -550,8 +580,11 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,  	av_name->mUsername = "";  	av_name->mDisplayName = full_name;  	av_name->mIsDisplayNameDefault = true; -	av_name->mIsDummy = true; -	av_name->mExpires = F64_MAX; +	av_name->mIsTemporaryName = true; +	av_name->mExpires = F64_MAX; // not used because these are not cached +	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName " +							 << full_name +							 << LL_ENDL;  }  // fills in av_name if it has it in the cache, even if expired (can check expiry time) @@ -574,6 +607,9 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)  				{  					if (!isRequestPending(agent_id))  					{ +						LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get " +												 << "refresh agent " << agent_id +												 << LL_ENDL;  						sAskQueue.insert(agent_id);  					}  				} @@ -595,6 +631,9 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)  	if (!isRequestPending(agent_id))  	{ +		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get " +								 << "queue request for agent " << agent_id +								 << LL_ENDL;  		sAskQueue.insert(agent_id);  	} @@ -627,7 +666,6 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)  				{  					// ...name already exists in cache, fire callback now  					fireSignal(agent_id, slot, av_name); -  					return;  				}  			} @@ -723,6 +761,9 @@ F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers)  bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)  { +	bool fromCacheControl = false; +	F64 now = LLFrameTimer::getTotalSeconds(); +  	// Allow the header to override the default  	LLSD cache_control_header = headers["cache-control"];  	if (cache_control_header.isDefined()) @@ -731,12 +772,16 @@ bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)  		std::string cache_control = cache_control_header.asString();  		if (max_age_from_cache_control(cache_control, &max_age))  		{ -			F64 now = LLFrameTimer::getTotalSeconds();  			*expires = now + (F64)max_age; -			return true; +			fromCacheControl = true;  		}  	} -	return false; +	LL_DEBUGS("AvNameCache") +		<< ( fromCacheControl ? "expires based on cache control " : "default expiration " ) +		<< "in " << *expires - now << " seconds" +		<< LL_ENDL; +	 +	return fromCacheControl;  } diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 8f21ace96a..59c1329ffa 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -82,6 +82,9 @@ namespace LLAvatarNameCache  	void erase(const LLUUID& agent_id); +    /// Provide some fallback for agents that return errors +	void handleAgentError(const LLUUID& agent_id); +  	// Force a re-fetch of the most recent data, but keep the current  	// data in cache  	void fetch(const LLUUID& agent_id); diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp index 3ba2dfb104..e0410906fb 100644 --- a/indra/llmessage/llcircuit.cpp +++ b/indra/llmessage/llcircuit.cpp @@ -87,6 +87,7 @@ LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id,  	mPingDelayAveraged((F32)INITIAL_PING_VALUE_MSEC),   	mUnackedPacketCount(0),  	mUnackedPacketBytes(0), +	mLastPacketInTime(0.0),  	mLocalEndPointID(),  	mPacketsOut(0),  	mPacketsIn(0),  @@ -667,6 +668,8 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)  		mHighestPacketID = llmax(mHighestPacketID, id);  	} +	// Save packet arrival time +	mLastPacketInTime = LLMessageSystem::getMessageTimeSeconds();  	// Have we received anything on this circuit yet?  	if (0 == mPacketsIn) diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h index 874c0c0bee..d1c400c6a2 100644 --- a/indra/llmessage/llcircuit.h +++ b/indra/llmessage/llcircuit.h @@ -122,7 +122,7 @@ public:  	U32			getPacketsLost() const;  	TPACKETID	getPacketOutID() const;  	BOOL		getTrusted() const; -	F32 getAgeInSeconds() const; +	F32			getAgeInSeconds() const;  	S32			getUnackedPacketCount() const	{ return mUnackedPacketCount; }  	S32			getUnackedPacketBytes() const	{ return mUnackedPacketBytes; }  	F64         getNextPingSendTime() const { return mNextPingSendTime; } @@ -130,6 +130,7 @@ public:                      { return mOutOfOrderRate.meanValue(scale); }      U32         getLastPacketGap() const { return mLastPacketGap; }      LLHost      getHost() const { return mHost; } +	F64			getLastPacketInTime() const		{ return mLastPacketInTime;	}  	LLThrottleGroup &getThrottleGroup()		{	return mThrottles; } @@ -248,6 +249,7 @@ protected:  	S32										mUnackedPacketCount;  	S32										mUnackedPacketBytes; +	F64										mLastPacketInTime;		// Time of last packet arrival  	LLUUID									mLocalEndPointID; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 6c0d47ef63..32d7be377a 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1637,6 +1637,10 @@ LLMenuScrollItem::LLMenuScrollItem(const Params& p)  	}  	LLButton::Params bparams; + +	// Disabled the Return key handling by LLMenuScrollItem instead of +	// passing the key press to the currently selected menu item. See STORM-385. +	bparams.commit_on_return(false);  	bparams.mouse_opaque(true);  	bparams.scale_image(false);  	bparams.click_callback(p.scroll_callback); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index cd0f0e36b0..cc9edfcdea 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1367,7 +1367,6 @@ LLNotifications::TemplateNames LLNotifications::getTemplateNames() const  typedef std::map<std::string, std::string> StringMap;  void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)  { -	//llwarns << "replaceSubstitutionStrings" << llendl;  	// walk the list of attributes looking for replacements  	for (LLXMLAttribList::iterator it=node->mAttributes.begin();  		 it != node->mAttributes.end(); ++it) @@ -1381,13 +1380,12 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)  			if (found != replacements.end())  			{  				replacement = found->second; -				//llwarns << "replaceSubstituionStrings: value: " << value << " repl: " << replacement << llendl; - +				lldebugs << "replaceSubstitutionStrings: value: \"" << value << "\" repl: \"" << replacement << "\"." << llendl;  				it->second->setValue(replacement);  			}  			else  			{ -				llwarns << "replaceSubstituionStrings FAILURE: value: " << value << " repl: " << replacement << llendl; +				llwarns << "replaceSubstitutionStrings FAILURE: could not find replacement \"" << value << "\"." << llendl;  			}  		}  	} diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 4f7b4be526..9db1feafd1 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -36,6 +36,7 @@  #include "llcachename.h"  #include "lltrans.h"  #include "lluicolortable.h" +#include "message.h"  #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" @@ -684,8 +685,8 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa  LLStyle::Params LLUrlEntryGroup::getStyle() const  {  	LLStyle::Params style_params = LLUrlEntryBase::getStyle(); -	style_params.color = LLUIColorTable::instance().getColor("GroupLinkColor"); -	style_params.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor"); +	style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); +	style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");  	return style_params;  } @@ -740,6 +741,13 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const  	return LLUrlEntryBase::getLocation(url);  } +// LLUrlEntryParcel statics. +LLUUID	LLUrlEntryParcel::sAgentID(LLUUID::null); +LLUUID	LLUrlEntryParcel::sSessionID(LLUUID::null); +LLHost	LLUrlEntryParcel::sRegionHost(LLHost::invalid); +bool	LLUrlEntryParcel::sDisconnected(false); +std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers; +  ///  /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,  /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about @@ -751,13 +759,88 @@ LLUrlEntryParcel::LLUrlEntryParcel()  							boost::regex::perl|boost::regex::icase);  	mMenuName = "menu_url_parcel.xml";  	mTooltip = LLTrans::getString("TooltipParcelUrl"); + +	sParcelInfoObservers.insert(this); +} + +LLUrlEntryParcel::~LLUrlEntryParcel() +{ +	sParcelInfoObservers.erase(this);  }  std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)  { +	LLSD path_array = LLURI(url).pathArray(); +	S32 path_parts = path_array.size(); + +	if (path_parts < 3) // no parcel id +	{ +		llwarns << "Failed to parse url [" << url << "]" << llendl; +		return url; +	} + +	std::string parcel_id_string = unescapeUrl(path_array[2]); // parcel id + +	// Add an observer to call LLUrlLabelCallback when we have parcel name. +	addObserver(parcel_id_string, url, cb); + +	LLUUID parcel_id(parcel_id_string); + +	sendParcelInfoRequest(parcel_id); +  	return unescapeUrl(url);  } +void LLUrlEntryParcel::sendParcelInfoRequest(const LLUUID& parcel_id) +{ +	if (sRegionHost == LLHost::invalid || sDisconnected) return; + +	LLMessageSystem *msg = gMessageSystem; +	msg->newMessage("ParcelInfoRequest"); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, sAgentID ); +	msg->addUUID("SessionID", sSessionID); +	msg->nextBlock("Data"); +	msg->addUUID("ParcelID", parcel_id); +	msg->sendReliable(sRegionHost); +} + +void LLUrlEntryParcel::onParcelInfoReceived(const std::string &id, const std::string &label) +{ +	callObservers(id, label.empty() ? LLTrans::getString("RegionInfoError") : label, mIcon); +} + +// static +void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data) +{ +	std::string label(LLStringUtil::null); +	if (!parcel_data.name.empty()) +	{ +		label = parcel_data.name; +	} +	// If parcel name is empty use Sim_name (x, y, z) for parcel label. +	else if (!parcel_data.sim_name.empty()) +	{ +		S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS; +		S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS; +		S32 region_z = llround(parcel_data.global_z); + +		label = llformat("%s (%d, %d, %d)", +				parcel_data.sim_name.c_str(), region_x, region_y, region_z); +	} + +	for (std::set<LLUrlEntryParcel*>::iterator iter = sParcelInfoObservers.begin(); +			iter != sParcelInfoObservers.end(); +			++iter) +	{ +		LLUrlEntryParcel* url_entry = *iter; +		if (url_entry) +		{ +			url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label); +		} +	} +} +  //  // LLUrlEntryPlace Describes secondlife://<location> URLs  // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 1791739061..5f82721c0f 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -31,6 +31,9 @@  #include "lluuid.h"  #include "lluicolor.h"  #include "llstyle.h" + +#include "llhost.h" // for resolving parcel name by parcel id +  #include <boost/signals2.hpp>  #include <boost/regex.hpp>  #include <string> @@ -285,8 +288,44 @@ private:  class LLUrlEntryParcel : public LLUrlEntryBase  {  public: +	struct LLParcelData +	{ +		LLUUID		parcel_id; +		std::string	name; +		std::string	sim_name; +		F32			global_x; +		F32			global_y; +		F32			global_z; +	}; +  	LLUrlEntryParcel(); +	~LLUrlEntryParcel();  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + +	// Sends a parcel info request to sim. +	void sendParcelInfoRequest(const LLUUID& parcel_id); + +	// Calls observers of certain parcel id providing them with parcel label. +	void onParcelInfoReceived(const std::string &id, const std::string &label); + +	// Processes parcel label and triggers notifying observers. +	static void processParcelInfo(const LLParcelData& parcel_data); + +	// Next 4 setters are used to update agent and viewer connection information +	// upon events like user login, viewer disconnect and user changing region host. +	// These setters are made public to be accessible from newview and should not be +	// used in other cases. +	static void setAgentID(const LLUUID& id) { sAgentID = id; } +	static void setSessionID(const LLUUID& id) { sSessionID = id; } +	static void setRegionHost(const LLHost& host) { sRegionHost = host; } +	static void setDisconnected(bool disconnected) { sDisconnected = disconnected; } + +private: +	static LLUUID						sAgentID; +	static LLUUID						sSessionID; +	static LLHost						sRegionHost; +	static bool							sDisconnected; +	static std::set<LLUrlEntryParcel*>	sParcelInfoObservers;  };  /// diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index f30704cb22..96ebe83826 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -30,6 +30,7 @@  #include "llavatarnamecache.h"  #include "llcachename.h"  #include "lluuid.h" +#include "message.h"  #include <string> @@ -191,3 +192,20 @@ LLFontGL* LLFontGL::getFontDefault()  {  	return NULL;   } + +char* _PREHASH_AgentData = "AgentData"; +char* _PREHASH_AgentID = "AgentID"; + +LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS); + +LLMessageSystem* gMessageSystem = NULL; + +// +// Stub implementation for LLMessageSystem +// +void LLMessageSystem::newMessage(const char *name) { } +void LLMessageSystem::nextBlockFast(const char *blockname) { } +void LLMessageSystem::nextBlock(const char *blockname) { } +void LLMessageSystem::addUUIDFast( const char *varname, const LLUUID& uuid) { } +void LLMessageSystem::addUUID( const char *varname, const LLUUID& uuid) { } +S32 LLMessageSystem::sendReliable(const LLHost &host) { return 0; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a61c35abd2..5d2342e925 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -530,6 +530,7 @@ set(viewer_SOURCE_FILES      llviewerregion.cpp      llviewershadermgr.cpp      llviewerstats.cpp +    llviewerstatsrecorder.cpp      llviewertexteditor.cpp      llviewertexture.cpp      llviewertextureanim.cpp @@ -1063,6 +1064,7 @@ set(viewer_HEADER_FILES      llviewerregion.h      llviewershadermgr.h      llviewerstats.h +    llviewerstatsrecorder.h      llviewertexteditor.h      llviewertexture.h      llviewertextureanim.h diff --git a/indra/newview/app_settings/lindenlab.pem b/indra/newview/app_settings/lindenlab.pem index cf88d0e047..eddae0426d 100644 --- a/indra/newview/app_settings/lindenlab.pem +++ b/indra/newview/app_settings/lindenlab.pem @@ -24,4 +24,74 @@ xA39CIJ65Zozs28Eg1aV9/Y+Of7TnWhW+U3J3/wD/GghaAGiKK6vMn9gJBIdBX/9  e6ef37VGyiOEFFjnUIbuk0RWty0orN76q/lI/xjCi15XSA/VSq2j4vmnwfZcPTDu  glmQ1A==  -----END CERTIFICATE----- - +-----BEGIN CERTIFICATE----- +MIIEkDCCA3igAwIBAgICTSUwDQYJKoZIhvcNAQEFBQAwQDELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDkdlb1RydXN0LCBJbmMuMRgwFgYDVQQDEw9HZW9UcnVzdCBTU0wg +Q0EwHhcNMTAxMjIwMTkxMTI2WhcNMTIwMjIxMTI1NDAzWjCBnzEpMCcGA1UEBRMg +UkMteW9jbXIwdXRmRTdOMVBlaHJHQXdqL0lNc2hJZS0xCzAJBgNVBAYTAlVTMRMw +EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMR0wGwYD +VQQKExRMaW5kZW4gUmVzZWFyY2ggSW5jLjEZMBcGA1UEAwwQKi5zZWNvbmRsaWZl +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN/VCCu1SZ5x4vNp +XZZ8r3lzqeLwjxVZfMSQCKM4lV5DFbqiZMMBto4Y/ib7i0audzuTDnImCLsfzlTu +7iZLoJNy42/43Rq4xtaDZ7joxALFmzXUKEipgHiTTbAbLQNCS4wPXts3tScODVZY +/mhlmXdlLuGxJbqoyOEP6NEQbgXWDCKDERnAEG/FJBVHKyBfg3abrrIuQNwYCKCS +2OZ5Z5MveGmY4tSKUOOi/c0vV9HsanQn/ymybZjxR5Kmb1CvQr7VVtbpR1MhlGkc +sfJz1NFIFxdXkUggIny+XSG1dAAJRFFumyRM+X/eh0NHNmAI14JJ43hB6Zw3dzzl +An9BSeECAwEAAaOCATIwggEuMB8GA1UdIwQYMBaAFEJ5VBthzVUrPmPVPEhX9Z/7 +Rc5KMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH +AwIwKwYDVR0RBCQwIoIQKi5zZWNvbmRsaWZlLmNvbYIOc2Vjb25kbGlmZS5jb20w +PQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2d0c3NsLWNybC5nZW90cnVzdC5jb20v +Y3Jscy9ndHNzbC5jcmwwHQYDVR0OBBYEFK9UTMkc4Fh/Ug4fVs6UVhxP6my0MAwG +A1UdEwEB/wQCMAAwQwYIKwYBBQUHAQEENzA1MDMGCCsGAQUFBzAChidodHRwOi8v +Z3Rzc2wtYWlhLmdlb3RydXN0LmNvbS9ndHNzbC5jcnQwDQYJKoZIhvcNAQEFBQAD +ggEBACIR9yggGHDcZ60AMNdFmZ8XJeahTuv6q2X/It2JxqSQp5BVQUei0NGIYYOt +yg0JFBZn5KqXiQ5Zz84K4hdvh/6grCEAn4v37sozSbkeZ92Lec8NOZR42HfYIOCo +Hx9q7CNRxdhv6ehV4LekaRBxrtp5etVsIDaWvRZEswCWl46VuLrfjcpauj6DAdOQ +FfPVAW+4nPgLr8KapZMnXYnabIwrj9DQLQ88w/D7durenu/SYJEahWW9mb++n9is +eMjyuyzYW0PTUBTaDsj+2ZmHJtoR1tBiLqh0Q62UQnmDgsf5SK5PTb8jnta/1SvN +3pirsuvjMPV19zuH6b9NpJfXfd0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT +MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0 +aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw +WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE +AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m +OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu +T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c +JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR +Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz +PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm +aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM +TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g +LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO +BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv +dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB +AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL +NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W +b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID2TCCAsGgAwIBAgIDAjbQMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTAwMjE5MjIzOTI2WhcNMjAwMjE4MjIzOTI2WjBAMQswCQYDVQQG +EwJVUzEXMBUGA1UEChMOR2VvVHJ1c3QsIEluYy4xGDAWBgNVBAMTD0dlb1RydXN0 +IFNTTCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJCzgMHk5Uat +cGA9uuUU3Z6KXot1WubKbUGlI+g5hSZ6p1V3mkihkn46HhrxJ6ujTDnMyz1Hr4Gu +FmpcN+9FQf37mpc8oEOdxt8XIdGKolbCA0mEEoE+yQpUYGa5jFTk+eb5lPHgX3UR +8im55IaisYmtph6DKWOy8FQchQt65+EuDa+kvc3nsVrXjAVaDktzKIt1XTTYdwvh +dGLicTBi2LyKBeUxY0pUiWozeKdOVSQdl+8a5BLGDzAYtDRN4dgjOyFbLTAZJQ50 +96QhS6CkIMlszZhWwPKoXz4mdaAN+DaIiixafWcwqQ/RmXAueOFRJq9VeiS+jDkN +d53eAsMMvR8CAwEAAaOB2TCB1jAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFEJ5 +VBthzVUrPmPVPEhX9Z/7Rc5KMB8GA1UdIwQYMBaAFMB6mGiNifurBWQMEX2qfWW4 +ysxOMBIGA1UdEwEB/wQIMAYBAf8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDov +L2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYBBQUHAQEE +KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20wDQYJKoZI +hvcNAQEFBQADggEBANTvU4ToGr2hiwTAqfVfoRB4RV2yV2pOJMtlTjGXkZrUJPji +J2ZwMZzBYlQG55cdOprApClICq8kx6jEmlTBfEx4TCtoLF0XplR4TEbigMMfOHES +0tdT41SFULgCy+5jOvhWiU1Vuy7AyBh3hjELC3DwfjWDpCoTZFZnNF0WX3OsewYk +2k9QbSqr0E1TQcKOu3EDSSmGGM8hQkx0YlEVxW+o78Qn5Rsz3VqI138S0adhJR/V +4NwdzxoQ2KDLX4z6DOW/cf/lXUQdpj6HR/oaToODEj+IZpWYeZqF6wJHzSXj8gYE +TpnKXKBuervdo5AaRTPvvz7SBMS24CqFZUE+ENQ= +-----END CERTIFICATE----- diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ef6f8fd3ee..85238cacdd 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -950,39 +950,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>BulkChangeIncludeAnimations</key> -    <map> -      <key>Comment</key> -      <string>Bulk permission changes affect animations</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map> -    <key>BulkChangeIncludeAnimations</key> -    <map> -      <key>Comment</key> -      <string>Bulk permission changes affect animations</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map> -    <key>BulkChangeIncludeAnimations</key> -    <map> -      <key>Comment</key> -      <string>Bulk permission changes affect animations</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>BulkChangeIncludeBodyParts</key>      <map>        <key>Comment</key> @@ -1195,18 +1162,7 @@      <key>CacheLocationTopFolder</key>      <map>        <key>Comment</key> -      <string>Controls the top folder location of the local disk cache</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string /> -    </map>	 -    <key>CacheLocationTopFolder</key> -    <map> -      <key>Comment</key> -      <string>Controls the location of the local disk cache</string> +      <string>Controls the top folder location of the the local disk cache</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -3119,17 +3075,6 @@          <string>http://viewer-settings.secondlife.com</string>      </map>      <key>FPSLogFrequency</key> -    <map> -      <key>Comment</key> -      <string>Seconds between display of FPS in log (0 for never)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>60.0</real> -    </map> -    <key>FPSLogFrequency</key>          <map>          <key>Comment</key>              <string>Seconds between display of FPS in log (0 for never)</string> @@ -6084,17 +6029,6 @@      <key>OutBandwidth</key>      <map>        <key>Comment</key> -      <string>Expand render stats display</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map> -    <key>OutBandwidth</key> -    <map> -      <key>Comment</key>        <string>Outgoing bandwidth throttle (bps)</string>        <key>Persist</key>        <integer>1</integer> @@ -11452,8 +11386,6 @@        <key>Type</key>        <string>LLSD</string>        <key>Value</key> -      <map> -      </map>      </map>      <key>VFSOldSize</key>      <map> @@ -11609,17 +11541,6 @@        <key>Value</key>        <string></string>      </map> -    <key>VivoxDebugSIPURIHostName</key> -    <map> -      <key>Comment</key> -      <string>Hostname portion of vivox SIP URIs (empty string for the default).</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string></string> -    </map>      <key>VivoxDebugVoiceAccountServerURI</key>      <map>        <key>Comment</key> @@ -12445,16 +12366,5 @@        <key>Value</key>        <string>name</string>      </map> -    <key>ReleaseNotesURL</key> -    <map> -      <key>Comment</key> -      <string>Release notes URL template</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>String</string> -      <key>Value</key> -      <string>http://secondlife.com/app/releasenotes/?channel=[CHANNEL]&version=[VERSION]</string> -    </map>  </map>  </llsd> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 77552663ab..7d908df5ce 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -64,6 +64,7 @@  #include "lltool.h"  #include "lltoolmgr.h"  #include "lltrans.h" +#include "llurlentry.h"  #include "llviewercontrol.h"  #include "llviewerdisplay.h"  #include "llviewerjoystick.h" @@ -649,6 +650,10 @@ void LLAgent::setRegion(LLViewerRegion *regionp)  	}  	mRegionp = regionp; +	// Pass the region host to LLUrlEntryParcel to resolve parcel name +	// with a server request. +	LLUrlEntryParcel::setRegionHost(getRegionHost()); +  	// Must shift hole-covering water object locations because local  	// coordinate frame changed.  	LLWorld::getInstance()->updateWaterObjects(); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 80734b0d41..f40fed5ad3 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1300,8 +1300,16 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)  		return false;  	} -	// Check whether the outfit contains the full set of body parts (shape+skin+hair+eyes). -	return getCanMakeFolderIntoOutfit(outfit_cat_id); +	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702). +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true); +	gInventory.collectDescendentsIf(outfit_cat_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		is_worn); +	return items.size() > 0;  }  void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3a98c23e05..6a9dfaf21b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -44,6 +44,7 @@  #include "llagentwearables.h"  #include "llwindow.h"  #include "llviewerstats.h" +#include "llviewerstatsrecorder.h"  #include "llmd5.h"  #include "llpumpio.h"  #include "llmimetypes.h" @@ -93,6 +94,7 @@  #include "llmemory.h"  #include "llprimitive.h"  #include "llurlaction.h" +#include "llurlentry.h"  #include "llvfile.h"  #include "llvfsthread.h"  #include "llvolumemgr.h" @@ -471,8 +473,6 @@ static void settings_to_globals()  	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");  	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");  	LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); - -	LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");  }  static void settings_modify() @@ -666,6 +666,10 @@ bool LLAppViewer::init()      mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::initClass(); +#endif +      // *NOTE:Mani - LLCurl::initClass is not thread safe.       // Called before threads are created.      LLCurl::initClass(); @@ -848,6 +852,9 @@ bool LLAppViewer::init()  	gGLActive = TRUE;  	initWindow(); +	// initWindow also initializes the Feature List, so now we can initialize this global. +	LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); +  	// call all self-registered classes  	LLInitClassList::instance().fireCallbacks(); @@ -989,6 +996,8 @@ bool LLAppViewer::init()  	LLAgentLanguage::init(); + +  	return true;  } @@ -1389,16 +1398,6 @@ bool LLAppViewer::cleanup()  	}  	mPlugins.clear(); -	//---------------------------------------------- -	//this test code will be removed after the test -	//test manual call stack tracer -	if(gSavedSettings.getBOOL("QAMode")) -	{ -		LLError::LLCallStacks::print() ; -	} -	//end of the test code -	//---------------------------------------------- -  	//flag all elements as needing to be destroyed immediately  	// to ensure shutdown order  	LLMortician::setZealous(TRUE); @@ -1709,6 +1708,10 @@ bool LLAppViewer::cleanup()  	}  	LLMetricPerformanceTesterBasic::cleanClass() ; +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::cleanupClass(); +#endif +  	llinfos << "Cleaning up Media and Textures" << llendflush;  	//Note: @@ -3064,35 +3067,32 @@ void LLAppViewer::initMarkerFile()  	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);  	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); -	  	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())  	{  		gLastExecEvent = LAST_EXEC_FROZE;  		LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;  	}     -      	if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))  	{ -		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << LAST_EXEC_LLERROR_CRASH << LL_ENDL;  		gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; +		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		LLAPRFile::remove(logout_marker_file);  	}  	if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))  	{ -		llinfos << "Last exec LLError crashed, setting LastExecEvent to " << LAST_EXEC_LLERROR_CRASH << llendl;  		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;  		else gLastExecEvent = LAST_EXEC_LLERROR_CRASH; +		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		LLAPRFile::remove(llerror_marker_file);  	}  	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))  	{ -		LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << LAST_EXEC_OTHER_CRASH << LL_ENDL;  		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;  		else gLastExecEvent = LAST_EXEC_OTHER_CRASH; +		LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +		LLAPRFile::remove(error_marker_file);  	} -	 -	LLAPRFile::remove(logout_marker_file); -	LLAPRFile::remove(llerror_marker_file); -	LLAPRFile::remove(error_marker_file); -	 +  	// No new markers if another instance is running.  	if(anotherInstanceRunning())   	{ @@ -3734,6 +3734,7 @@ void LLAppViewer::loadNameCache()  	// display names cache  	std::string filename =  		gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); +	LL_INFOS("AvNameCache") << filename << LL_ENDL;  	llifstream name_cache_stream(filename);  	if(name_cache_stream.is_open())  	{ @@ -4567,6 +4568,10 @@ void LLAppViewer::disconnectViewer()  	cleanup_xfer_manager();  	gDisconnected = TRUE; + +	// Pass the connection state to LLUrlEntryParcel not to attempt +	// parcel info requests while disconnected. +	LLUrlEntryParcel::setDisconnected(gDisconnected);  }  void LLAppViewer::forceErrorLLError() diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 4a1ba6f1b5..6f02192d0a 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -319,7 +319,7 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )  // This is called when the main floatercustomize panel is closed.  // Since this class has pointers up to its parents, we need to cleanup  // this class first in order to avoid a crash. -void LLColorSwatchCtrl::onParentFloaterClosed() +void LLColorSwatchCtrl::closeFloaterColorPicker()  {  	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();  	if (pickerp) diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h index cd859ea128..5bdd1712d2 100644 --- a/indra/newview/llcolorswatch.h +++ b/indra/newview/llcolorswatch.h @@ -100,7 +100,7 @@ public:  	/*virtual*/ void	setEnabled( BOOL enabled );  	static void		onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE ); -	void			onParentFloaterClosed(); +	void			closeFloaterColorPicker();  protected:  	BOOL			mValid; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ca2ef5f5b8..4e16cc4217 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -290,11 +290,9 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)  	mTableVersion = version;  	LLFeatureList *flp = NULL; -	while (!file.eof() && file.good()) +	while (file >> name)  	{  		char buffer[MAX_STRING];		 /*Flawfinder: ignore*/ - -		file >> name;  		if (name.substr(0,2) == "//")  		{ @@ -303,13 +301,6 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)  			continue;  		} -		if (name.empty()) -		{ -			// This is a blank line -			file.getline(buffer, MAX_STRING); -			continue; -		} -  		if (name == "list")  		{  			if (flp) diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 71882fbb83..07f5220ab7 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -178,7 +178,7 @@ void LLFloaterSettingsDebug::onClickDefault()  	if (controlp)  	{ -		controlp->resetToDefault(); +		controlp->resetToDefault(true);  		updateControl(controlp);  	}  } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index afd565bb26..9623554200 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -279,7 +279,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&  void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)  { -	if (av_name.mIsDummy) +	if (av_name.mIsTemporaryName)  	{  		S32 separator_index = mName.rfind(" ");  		std::string name = mName.substr(0, separator_index); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ef20869114..61d0a150b7 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -686,6 +686,12 @@ bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* it  		return false;  	} +	// Skip broken links. +	if (vitem->getIsBrokenLink()) +	{ +		return false; +	} +  	return (bool) get_is_item_worn(item->getUUID()) == mIsWorn;  } diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index eab8f187a7..570e48d526 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -181,7 +181,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  	if (mBackgroundFetchActive && gAgent.getRegion())  	{  		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important. -		std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");    +		std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2");     		if (!url.empty())   		{  			bulkFetch(url); @@ -604,7 +604,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)  		}  		if (body_lib["folders"].size())  		{ -			std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents"); +			std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2");  			LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body_lib, recursive_cats);  			LLHTTPClient::post(url_lib, body_lib, fetcher, 300.0); diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 91ff8c7867..0fd4b2bee5 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -203,8 +203,8 @@ void fetch_items_from_llsd(const LLSD& items_llsd)  {  	if (!items_llsd.size() || gDisconnected) return;  	LLSD body; -	body[0]["cap_name"] = "FetchInventory"; -	body[1]["cap_name"] = "FetchLib"; +	body[0]["cap_name"] = "FetchInventory2"; +	body[1]["cap_name"] = "FetchLib2";  	for (S32 i=0; i<items_llsd.size();i++)  	{  		if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString()) diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 1527f8f4c9..55164f6094 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -547,6 +547,10 @@ void LLLocationInputCtrl::onFocusLost()  {  	LLUICtrl::onFocusLost();  	refreshLocation(); + +	// Setting cursor to 0  to show the left edge of the text. See STORM-370. +	mTextEntry->setCursor(0); +  	if(mTextEntry->hasSelection()){  		mTextEntry->deselect();  	} diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index d866db1829..33e051bfab 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -214,6 +214,9 @@ void MandatoryUpdateMachine::start(void)  			case LLUpdaterService::CHECKING_FOR_UPDATE:  				setCurrentState(new CheckingForUpdate(*this));  				break; +			case LLUpdaterService::TEMPORARY_ERROR: +				setCurrentState(new Error(*this)); +				break;  			case LLUpdaterService::DOWNLOADING:  				setCurrentState(new WaitingForDownload(*this));  				break; @@ -289,6 +292,7 @@ bool MandatoryUpdateMachine::CheckingForUpdate::onEvent(LLSD const & event)  			case LLUpdaterService::DOWNLOADING:  				mMachine.setCurrentState(new WaitingForDownload(mMachine));  				break; +			case LLUpdaterService::TEMPORARY_ERROR:  			case LLUpdaterService::UP_TO_DATE:  			case LLUpdaterService::TERMINAL:  			case LLUpdaterService::FAILURE: @@ -324,7 +328,7 @@ MandatoryUpdateMachine::Error::Error(MandatoryUpdateMachine & machine):  void MandatoryUpdateMachine::Error::enter(void)  {  	llinfos << "entering error" << llendl; -	LLNotificationsUtil::add("FailedUpdateInstall", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::Error::onButtonClicked, this, _1, _2)); +	LLNotificationsUtil::add("FailedRequiredUpdateInstall", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::Error::onButtonClicked, this, _1, _2));  } @@ -468,7 +472,6 @@ LLLoginInstance::LLLoginInstance() :  	mLoginModule(new LLLogin()),  	mNotifications(NULL),  	mLoginState("offline"), -	mUserInteraction(true),  	mSkipOptionalUpdate(false),  	mAttemptComplete(false),  	mTransferRate(0.0f), @@ -637,64 +640,57 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	LLSD response = event["data"];  	std::string reason_response = response["reason"].asString();  	std::string message_response = response["message"].asString(); -	if(mUserInteraction) +	// For the cases of critical message or TOS agreement, +	// start the TOS dialog. The dialog response will be handled +	// by the LLLoginInstance::handleTOSResponse() callback. +	// The callback intiates the login attempt next step, either  +	// to reconnect or to end the attempt in failure. +	if(reason_response == "tos")  	{ -		// For the cases of critical message or TOS agreement, -		// start the TOS dialog. The dialog response will be handled -		// by the LLLoginInstance::handleTOSResponse() callback. -		// The callback intiates the login attempt next step, either  -		// to reconnect or to end the attempt in failure. -		if(reason_response == "tos") -		{ -			LLSD data(LLSD::emptyMap()); -			data["message"] = message_response; -			data["reply_pump"] = TOS_REPLY_PUMP; -			gViewerWindow->setShowProgress(FALSE); -			LLFloaterReg::showInstance("message_tos", data); -			LLEventPumps::instance().obtain(TOS_REPLY_PUMP) -				.listen(TOS_LISTENER_NAME, -						boost::bind(&LLLoginInstance::handleTOSResponse,  -									this, _1, "agree_to_tos")); -		} -		else if(reason_response == "critical") -		{ -			LLSD data(LLSD::emptyMap()); -			data["message"] = message_response; -			data["reply_pump"] = TOS_REPLY_PUMP; -			if(response.has("error_code")) -			{ -				data["error_code"] = response["error_code"]; -			} -			if(response.has("certificate")) -			{ -				data["certificate"] = response["certificate"]; -			} -			 -			gViewerWindow->setShowProgress(FALSE); -			LLFloaterReg::showInstance("message_critical", data); -			LLEventPumps::instance().obtain(TOS_REPLY_PUMP) -				.listen(TOS_LISTENER_NAME, -						boost::bind(&LLLoginInstance::handleTOSResponse,  -									this, _1, "read_critical")); -		} -		else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate")) +		LLSD data(LLSD::emptyMap()); +		data["message"] = message_response; +		data["reply_pump"] = TOS_REPLY_PUMP; +		gViewerWindow->setShowProgress(FALSE); +		LLFloaterReg::showInstance("message_tos", data); +		LLEventPumps::instance().obtain(TOS_REPLY_PUMP) +			.listen(TOS_LISTENER_NAME, +					boost::bind(&LLLoginInstance::handleTOSResponse,  +								this, _1, "agree_to_tos")); +	} +	else if(reason_response == "critical") +	{ +		LLSD data(LLSD::emptyMap()); +		data["message"] = message_response; +		data["reply_pump"] = TOS_REPLY_PUMP; +		if(response.has("error_code"))  		{ -			gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); -			updateApp(true, message_response); +			data["error_code"] = response["error_code"];  		} -		else if(reason_response == "optional") +		if(response.has("certificate"))  		{ -			updateApp(false, message_response); +			data["certificate"] = response["certificate"];  		} -		else -		{	 -			attemptComplete(); -		}	 +		 +		gViewerWindow->setShowProgress(FALSE); +		LLFloaterReg::showInstance("message_critical", data); +		LLEventPumps::instance().obtain(TOS_REPLY_PUMP) +			.listen(TOS_LISTENER_NAME, +					boost::bind(&LLLoginInstance::handleTOSResponse,  +								this, _1, "read_critical"));  	} -	else // no user interaction +	else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))  	{ -		attemptComplete(); +		gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); +		updateApp(true, message_response);  	} +	else if(reason_response == "optional") +	{ +		updateApp(false, message_response); +	} +	else +	{	 +		attemptComplete(); +	}	  }  void LLLoginInstance::handleLoginSuccess(const LLSD& event) diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index b872d7d1b1..8b53431219 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -61,12 +61,6 @@ public:  	// Only valid when authSuccess == true.  	const F64 getLastTransferRateBPS() { return mTransferRate; } -		// Set whether this class will drive user interaction. -	// If not, login failures like 'need tos agreement' will  -	// end the login attempt. -	void setUserInteraction(bool state) { mUserInteraction = state; }  -	bool getUserInteraction() { return mUserInteraction; } -  	// Whether to tell login to skip optional update request.  	// False by default.  	void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; } @@ -100,7 +94,6 @@ private:  	std::string mLoginState;  	LLSD mRequestData;  	LLSD mResponseData; -	bool mUserInteraction;   	bool mSkipOptionalUpdate;  	bool mAttemptComplete;  	F64 mTransferRate; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 90ed8b9e58..4a74b7925c 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -569,6 +569,7 @@ static void update_color_swatch_ctrl(LLPanelEditWearable* self, LLPanel* panel,  	if (color_swatch_ctrl)  	{  		color_swatch_ctrl->set(self->getWearable()->getClothesColor(entry->mTextureIndex)); +		color_swatch_ctrl->closeFloaterColorPicker();  	}  } diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index d1362d7922..3dbc637318 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1843,7 +1843,8 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg)  {  	lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl; -	saveRoleChanges(); +	saveRoleChanges(true); +  	LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID);  	notifyObservers(); @@ -2022,7 +2023,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()  		return;  	} -	saveRoleChanges(); +	saveRoleChanges(false);  	// Check if there is anything selected.  	LLScrollListItem* item = mRolesList->getFirstSelected(); @@ -2385,7 +2386,7 @@ void LLPanelGroupRolesSubTab::handleDeleteRole()  	notifyObservers();  } -void LLPanelGroupRolesSubTab::saveRoleChanges() +void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role)  {  	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); @@ -2400,13 +2401,23 @@ void LLPanelGroupRolesSubTab::saveRoleChanges()  		rd.mRoleDescription = mRoleDescription->getText();  		rd.mRoleTitle = mRoleTitle->getText(); +		S32 role_members_count = 0; +		if (mSelectedRole.isNull()) +		{ +			role_members_count = gdatap->mMemberCount; +		} +		else if(LLGroupRoleData* grd = get_ptr_in_map(gdatap->mRoles, mSelectedRole)) +		{ +			role_members_count = grd->getTotalMembersInRole(); +		} +  		gdatap->setRoleData(mSelectedRole,rd);  		mRolesList->deleteSingleItem(mRolesList->getItemIndex(mSelectedRole)); -		LLSD row = createRoleItem(mSelectedRole,rd.mRoleName,rd.mRoleTitle,0); +		LLSD row = createRoleItem(mSelectedRole,rd.mRoleName,rd.mRoleTitle,role_members_count);  		LLScrollListItem* item = mRolesList->addElement(row, ADD_BOTTOM, this); -		item->setSelected(TRUE); +		item->setSelected(select_saved_role);  		mHasRoleChange = FALSE;  	} diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 270259c16f..a55e264150 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -257,7 +257,7 @@ public:  	static void onDeleteRole(void*);  	void handleDeleteRole(); -	void saveRoleChanges(); +	void saveRoleChanges(bool select_saved_role);  	virtual void setGroupID(const LLUUID& id);  protected: diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index e8c8273a9d..80f6862169 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -71,6 +71,7 @@ static void collapse_all_folders(LLFolderView* root_folder);  static void expand_all_folders(LLFolderView* root_folder);  static bool has_expanded_folders(LLFolderView* root_folder);  static bool has_collapsed_folders(LLFolderView* root_folder); +static void toggle_restore_menu(LLMenuGL* menu, BOOL visible, BOOL enabled);  /**   * Functor counting expanded and collapsed folders in folder view tree to know @@ -708,6 +709,9 @@ void LLLandmarksPanel::initListCommandsHandlers()  	mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());  	mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mGearLandmarkMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); +	mGearFolderMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); +  	mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME));  } @@ -1079,6 +1083,60 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)  	{  		doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1));  	} +	else if ("restore" == command_name && mCurrentSelectedList) +	{ +		mCurrentSelectedList->doToSelected(userdata); +	} +} + +void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param) +{ +	bool new_visibility = param["visibility"].asBoolean(); + +	// We don't have to update items visibility if the menu is hiding. +	if (!new_visibility) return; + +	BOOL are_any_items_in_trash = FALSE; +	BOOL are_all_items_in_trash = TRUE; + +	LLFolderView* root_folder_view = mCurrentSelectedList ? mCurrentSelectedList->getRootFolder() : NULL; +	if(root_folder_view) +	{ +		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + +		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); + +		// Iterate through selected items to find out if any of these items are in Trash +		// or all the items are in Trash category. +		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) +		{ +			LLFolderViewItem* item = root_folder_view->getItemByID(*iter); + +			// If no item is found it might be a folder id. +			if (!item) +			{ +				item = root_folder_view->getFolderByID(*iter); +			} +			if (!item) continue; + +			LLFolderViewEventListener* listenerp = item->getListener(); +			if(!listenerp) continue; + +			// Trash category itself should not be included because it can't be +			// actually restored from trash. +			are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id; + +			// If there are any selected items in Trash including the Trash category itself +			// we show "Restore Item" in context menu and hide other irrelevant items. +			are_any_items_in_trash |= listenerp->isItemInTrash(); +		} +	} + +	// Display "Restore Item" menu entry if at least one of the selected items +	// is in Trash or the Trash category itself is among selected items. +	// Hide other menu entries in this case. +	// Enable this menu entry only if all selected items are in the Trash category. +	toggle_restore_menu((LLMenuGL*)ctrl, are_any_items_in_trash, are_all_items_in_trash);  }  /* @@ -1414,4 +1472,31 @@ static bool has_collapsed_folders(LLFolderView* root_folder)  	return true;  } + +// Displays "Restore Item" context menu entry while hiding +// all other entries or vice versa. +// Sets "Restore Item" enabled state. +void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled) +{ +	if (!menu) return; + +	const LLView::child_list_t *list = menu->getChildList(); +	for (LLView::child_list_t::const_iterator itor = list->begin(); +		 itor != list->end(); +		 ++itor) +	{ +		LLView *menu_item = (*itor); +		std::string name = menu_item->getName(); + +		if ("restore_item" == name) +		{ +			menu_item->setVisible(visible); +			menu_item->setEnabled(enabled); +		} +		else +		{ +			menu_item->setVisible(!visible); +		} +	} +}  // EOF diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 8dcbca0440..b2f4e92473 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -129,6 +129,14 @@ private:  	void onCustomAction(const LLSD& command_name);  	/** +	 * Updates context menu depending on the selected items location. +	 * +	 * For items in Trash category the menu includes the "Restore Item" +	 * context menu entry. +	 */ +	void onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param); + +	/**  	 * Determines if an item can be modified via context/gear menu.  	 *  	 * It validates Places Landmarks rules first. And then LLFolderView permissions. diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index c143aff2d4..8d3b1fd7a0 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -35,6 +35,7 @@  #include "llsecondlifeurls.h"  #include "v4color.h" +#include "llappviewer.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcommandhandler.h"		// for secondlife:///app/login/ @@ -859,6 +860,13 @@ void LLPanelLogin::loadLoginPage()  	char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLabel().c_str(), 0);  	oStr << "&grid=" << curl_grid;  	curl_free(curl_grid); +	 +	// add OS info +	char * os_info = curl_escape(LLAppViewer::instance()->getOSInfo().getOSStringSimple().c_str(), 0); +	oStr << "&os=" << os_info; +	curl_free(os_info); +	 +	  	gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());  	gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor()); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 211b9cf4b1..0b6267c9e6 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -766,22 +766,12 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const  		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());  		if(object)  		{ -			const LLInventoryItem *inv = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID)); -			if (inv) +			const LLInventoryObject* cat = object->getInventoryObject(mUUID); +			if ( (cat) && (move_inv_category_world_to_agent(mUUID, LLUUID::null, FALSE)) )  			{ -				const LLPermissions& perm = inv->getPermissions(); -				bool can_copy = gAgent.allowOperation(PERM_COPY, perm, -														GP_OBJECT_MANIPULATE); -				if((can_copy && perm.allowTransferTo(gAgent.getID())) -				   || object->permYouOwner()) -//				   || gAgent.isGodlike()) - -				{ -					*type = LLViewerAssetType::lookupDragAndDropType(inv->getType()); - -					*id = inv->getUUID(); -					return TRUE; -				} +				*type = LLViewerAssetType::lookupDragAndDropType(cat->getType()); +				*id = mUUID; +				return TRUE;  			}  		}  	} diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index e5ef51bdd1..3862dac340 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -33,6 +33,7 @@  #include "llpanel.h"  #include "llhttpclient.h"  #include "llsdserialize.h" +#include "llurlentry.h"  #include "llviewerregion.h"  #include "llview.h" @@ -168,6 +169,18 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v  	{  		observers.erase(*i);  	} + +	LLUrlEntryParcel::LLParcelData url_data; +	url_data.parcel_id = parcel_data.parcel_id; +	url_data.name = parcel_data.name; +	url_data.sim_name = parcel_data.sim_name; +	url_data.global_x = parcel_data.global_x; +	url_data.global_y = parcel_data.global_y; +	url_data.global_z = parcel_data.global_z; + +	// Pass the parcel data to LLUrlEntryParcel to render +	// human readable parcel name. +	LLUrlEntryParcel::processParcelInfo(url_data);  }  void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 7478ed5f9a..65a9a493f6 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -235,7 +235,7 @@ public:  	{  		bool operator()(LLSelectNode* node);  	}; -	typedef boost::filter_iterator<is_root, list_t::iterator > valid_root_iterator; +	typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator;  	valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); }  	valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index b316171604..363fe5f12b 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -185,7 +185,7 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)  {  	LLSD visibility;  	visibility["visible"] = new_visibility.asBoolean(); -	visibility["reset_accordion"] = true; +	visibility["reset_accordion"] = false;  	updateToVisibility(visibility);  } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index aef665a35c..19d1bdee86 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -498,8 +498,8 @@ private:  LLSideTray::Params::Params()  :	collapsed("collapsed",false), -	tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("sidebar_tab_left.tga")), -	tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("button_enabled_selected_32x128.tga")), +	tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("taskpanel/TaskPanel_Tab_Off.png")), +	tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("taskpanel/TaskPanel_Tab_Selected.png")),  	default_button_width("tab_btn_width",32),  	default_button_height("tab_btn_height",32),  	default_button_margin("tab_btn_margin",0) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 960e72ee42..8adb8c30e0 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2578,6 +2578,49 @@ void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)  	gGL.end();  } +void renderUpdateType(LLDrawable* drawablep) +{ +	LLViewerObject* vobj = drawablep->getVObj(); +	if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType()) +	{ +		return; +	} +	LLGLEnable blend(GL_BLEND); +	switch (vobj->getLastUpdateType()) +	{ +	case OUT_FULL: +		glColor4f(0,1,0,0.5f); +		break; +	case OUT_TERSE_IMPROVED: +		glColor4f(0,1,1,0.5f); +		break; +	case OUT_FULL_COMPRESSED: +		if (vobj->getLastUpdateCached()) +		{ +			glColor4f(1,0,0,0.5f); +		} +		else +		{ +			glColor4f(1,1,0,0.5f); +		} +		break; +	case OUT_FULL_CACHED: +		glColor4f(0,0,1,0.5f); +		break; +	default: +		llwarns << "Unknown update_type " << vobj->getLastUpdateType() << llendl; +		break; +	}; +	S32 num_faces = drawablep->getNumFaces(); +	if (num_faces) +	{ +		for (S32 i = 0; i < num_faces; ++i) +		{ +			pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); +		} +	} +} +  void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)  { @@ -3018,6 +3061,10 @@ public:  			{  				renderRaycast(drawable);  			} +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_UPDATE_TYPE)) +			{ +				renderUpdateType(drawable); +			}  			LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); @@ -3180,6 +3227,7 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_OCCLUSION |  									  LLPipeline::RENDER_DEBUG_LIGHTS |  									  LLPipeline::RENDER_DEBUG_BATCH_SIZE | +									  LLPipeline::RENDER_DEBUG_UPDATE_TYPE |  									  LLPipeline::RENDER_DEBUG_BBOXES |  									  LLPipeline::RENDER_DEBUG_POINTS |  									  LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 611f9de2e6..0eac7d5e2a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -139,6 +139,7 @@  #include "lltrans.h"  #include "llui.h"  #include "llurldispatcher.h" +#include "llurlentry.h"  #include "llslurl.h"  #include "llurlhistory.h"  #include "llurlwhitelist.h" @@ -980,7 +981,6 @@ bool idle_startup()  			login->setSkipOptionalUpdate(true);  		} -		login->setUserInteraction(show_connect_box);  		login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());  		login->setLastExecEvent(gLastExecEvent);  		login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance())); @@ -2882,9 +2882,17 @@ bool process_login_success_response()  	if(!text.empty()) gAgentID.set(text);  	gDebugInfo["AgentID"] = text; +	// Agent id needed for parcel info request in LLUrlEntryParcel +	// to resolve parcel name. +	LLUrlEntryParcel::setAgentID(gAgentID); +  	text = response["session_id"].asString();  	if(!text.empty()) gAgentSessionID.set(text);  	gDebugInfo["SessionID"] = text; + +	// Session id needed for parcel info request in LLUrlEntryParcel +	// to resolve parcel name. +	LLUrlEntryParcel::setSessionID(gAgentSessionID);  	text = response["secure_session_id"].asString();  	if(!text.empty()) gAgent.mSecureSessionID.set(text); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 6a213309a0..92080d1fd7 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1858,8 +1858,22 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)  //called after mHeaderMutex is locked.  void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)  { + 	bool file_maybe_exists = true;	// Always attempt to remove when idx is invalid. +  	if(idx >= 0) //valid entry  	{ +		if (entry.mBodySize == 0)	// Always attempt to remove when mBodySize > 0. +		{ +		  if (LLAPRFile::isExist(filename, getLocalAPRFilePool()))		// Sanity check. Shouldn't exist when body size is 0. +		  { +			  LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL; +		  } +		  else +		  { +			  file_maybe_exists = false; +		  } +		} +  		entry.mImageSize = -1;  		entry.mBodySize = 0;  		mHeaderIDMap.erase(entry.mID); @@ -1869,7 +1883,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)  		mFreeList.insert(idx);	  	} -	LLAPRFile::remove(filename, getLocalAPRFilePool());		 +	if (file_maybe_exists) +	{ +		LLAPRFile::remove(filename, getLocalAPRFilePool());		 +	}  }  bool LLTextureCache::removeFromCache(const LLUUID& id) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b3642a2c1e..cc851e676b 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -366,11 +366,11 @@ void LLViewerInventoryItem::fetchFromServer(void) const  		{  		  if(gAgent.getID() != mPermissions.getOwner())  		    { -		      url = region->getCapability("FetchLib"); +		      url = region->getCapability("FetchLib2");  		    }  		  else  		    {	 -		      url = region->getCapability("FetchInventory"); +		      url = region->getCapability("FetchInventory2");  		    }  		}  		else @@ -648,7 +648,7 @@ bool LLViewerInventoryCategory::fetch()  		std::string url;  		if (gAgent.getRegion())  		{ -			url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents"); +			url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2");  		}  		else  		{ @@ -660,7 +660,7 @@ bool LLViewerInventoryCategory::fetch()  		}  		else  		{	//Deprecated, but if we don't have a capability, use the old system. -			llinfos << "WebFetchInventoryDescendents capability not found.  Using deprecated UDP message." << llendl; +			llinfos << "FetchInventoryDescendents2 capability not found.  Using deprecated UDP message." << llendl;  			LLMessageSystem* msg = gMessageSystem;  			msg->newMessage("FetchInventoryDescendents");  			msg->nextBlock("AgentData"); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 60b118284b..7cc04e0338 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -906,6 +906,10 @@ U32 info_display_from_string(std::string info_display)  	{  		return LLPipeline::RENDER_DEBUG_BATCH_SIZE;  	} +	else if ("update type" == info_display) +	{ +		return LLPipeline::RENDER_DEBUG_UPDATE_TYPE; +	}  	else if ("texture anim" == info_display)  	{  		return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 7dc5d96689..6fc85a3944 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -171,31 +171,6 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =  	FALSE	// ControlYourCamera  }; -// Extract channel and version from a string like "SL Web Viewer Beta 10.11.29.215604". -// (channel: "SL Web Viewer Beta", version: "10.11.29.215604") -static bool parse_version_info(const std::string& version_info, std::string& channel, std::string& ver) -{ -	size_t last_space = version_info.rfind(" "); -	channel = version_info; - -	if (last_space != std::string::npos) -	{ -		try -		{ -			ver = version_info.substr(last_space + 1); -			channel.replace(last_space, ver.length() + 1, ""); // strip version -		} -		catch (std::out_of_range) -		{ -			return false; -		} - -		return true; -	} - -	return false; -} -  bool friendship_offer_callback(const LLSD& notification, const LLSD& response)  {  	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -3848,31 +3823,6 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)  		return;  	} -	if (!gLastVersionChannel.empty()) -	{ -		std::string url = regionp->getCapability("ServerReleaseNotes"); -		if (url.empty()) -		{ -			// The capability hasn't arrived yet or is not supported, -			// fall back to parsing server version channel. -			std::string channel, ver; -			if (!parse_version_info(version_channel, channel, ver)) -			{ -				llwarns << "Failed to parse server version channel (" << version_channel << ")" << llendl; -			} - -			url = gSavedSettings.getString("ReleaseNotesURL"); -			LLSD args; -			args["CHANNEL"] = LLWeb::escapeURL(channel); -			args["VERSION"] = LLWeb::escapeURL(ver); -			LLStringUtil::format(url, args); -		} - -		LLSD args; -		args["URL"] = url; -		LLNotificationsUtil::add("ServerVersionChanged", args); -	} -  	gLastVersionChannel = version_channel;  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 18d6e4c8c8..090d3cadd4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -210,7 +210,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mLastInterpUpdateSecs(0.f),  	mLastMessageUpdateSecs(0.f),  	mLatestRecvPacketID(0), -	mCircuitPacketCount(0),  	mData(NULL),  	mAudioSourcep(NULL),  	mAudioGain(1.f), @@ -234,7 +233,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mState(0),  	mMedia(NULL),  	mClickAction(0), -	mAttachmentItemID(LLUUID::null) +	mAttachmentItemID(LLUUID::null), +	mLastUpdateType(OUT_UNKNOWN), +	mLastUpdateCached(FALSE)  {  	if (!is_global)  	{ @@ -1882,7 +1883,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	}  	mLatestRecvPacketID = packet_id; -	mCircuitPacketCount = 0;  	// Set the change flags for scale  	if (new_scale != getScale()) @@ -2205,7 +2205,8 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)  		LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	  		LLVector3 new_v = accel * dt; -		if (time_since_last_update > sPhaseOutUpdateInterpolationTime) +		if (time_since_last_update > sPhaseOutUpdateInterpolationTime && +			sPhaseOutUpdateInterpolationTime > 0.0)  		{	// Haven't seen a viewer update in a while, check to see if the ciruit is still active  			if (mRegionp)  			{	// The simulator will NOT send updates if the object continues normally on the path @@ -2214,9 +2215,12 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)  				LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );  				if (cdp)  				{ +					// Find out how many seconds since last packet arrived on the circuit +					F64 time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime(); +  					if (!cdp->isAlive() ||		// Circuit is dead or blocked  						 cdp->isBlocked() ||	// or doesn't seem to be getting any packets -						 (mCircuitPacketCount > 0 && mCircuitPacketCount == cdp->getPacketsIn())) +						 (time_since_last_packet > sPhaseOutUpdateInterpolationTime))  					{  						// Start to reduce motion interpolation since we haven't seen a server update in a while  						F64 time_since_last_interpolation = time - mLastInterpUpdateSecs; @@ -2247,9 +2251,6 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)  						new_pos = new_pos * ((F32) phase_out);  						new_v = new_v * ((F32) phase_out);  					} - -					// Save current circuit packet count to see if it changes  -					mCircuitPacketCount = cdp->getPacketsIn();  				}  			}  		} @@ -5103,7 +5104,6 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)  	}  	mLatestRecvPacketID = 0; -	mCircuitPacketCount = 0;  	mRegionp = regionp;  	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i) @@ -5403,6 +5403,26 @@ void LLViewerObject::setAttachmentItemID(const LLUUID &id)  	mAttachmentItemID = id;  } +EObjectUpdateType LLViewerObject::getLastUpdateType() const +{ +	return mLastUpdateType; +} + +void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type) +{ +	mLastUpdateType = last_update_type; +} + +BOOL LLViewerObject::getLastUpdateCached() const +{ +	return mLastUpdateCached; +} + +void LLViewerObject::setLastUpdateCached(BOOL last_update_cached) +{ +	mLastUpdateCached = last_update_cached; +} +  const LLUUID &LLViewerObject::extractAttachmentItemID()  {  	LLUUID item_id = LLUUID::null; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 5c1a34d555..7afb7f464b 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -77,6 +77,7 @@ typedef enum e_object_update_type  	OUT_TERSE_IMPROVED,  	OUT_FULL_COMPRESSED,  	OUT_FULL_CACHED, +	OUT_UNKNOWN,  } EObjectUpdateType; @@ -612,7 +613,6 @@ protected:  	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation  	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator  	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator -	U32				mCircuitPacketCount;			// Packet tracking for early detection of a stopped simulator circuit  	// extra data sent from the sim...currently only used for tree species info  	U8* mData; @@ -693,8 +693,15 @@ public:  	const LLUUID &getAttachmentItemID() const;  	void setAttachmentItemID(const LLUUID &id);  	const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object +	EObjectUpdateType getLastUpdateType() const; +	void setLastUpdateType(EObjectUpdateType last_update_type); +	BOOL getLastUpdateCached() const; +	void setLastUpdateCached(BOOL last_update_cached); +  private:  	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. +	EObjectUpdateType	mLastUpdateType; +	BOOL	mLastUpdateCached;  };  /////////////////// diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index f5a32438cf..5849ab4307 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -56,6 +56,7 @@  #include "llresmgr.h"  #include "llviewerregion.h"  #include "llviewerstats.h" +#include "llviewerstatsrecorder.h"  #include "llvoavatarself.h"  #include "lltoolmgr.h"  #include "lltoolpie.h" @@ -302,8 +303,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	// have to transform to absolute coordinates.  	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); +	// I don't think this case is ever hit.  TODO* Test this.  	if (!cached && !compressed && update_type != OUT_FULL)  	{ +		//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;  		gTerseObjectUpdates += num_objects;  		S32 size;  		if (mesgsys->getReceiveCompressedSize()) @@ -314,7 +317,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		{  			size = mesgsys->getReceiveSize();  		} -		// llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; +		//llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;  	}  	else  	{ @@ -345,9 +348,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	U8 compressed_dpbuffer[2048];  	LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);  	LLDataPacker *cached_dpp = NULL; -	 + +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(regionp); +#endif +  	for (i = 0; i < num_objects; i++)  	{ +		// timer is unused?  		LLTimer update_timer;  		BOOL justCreated = FALSE; @@ -359,9 +367,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);  			// Lookup data packer and add this id to cache miss lists if necessary. -			cached_dpp = regionp->getDP(id, crc); +			U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; +			cached_dpp = regionp->getDP(id, crc, cache_miss_type);  			if (cached_dpp)  			{ +				// Cache Hit.  				cached_dpp->reset();  				cached_dpp->unpackUUID(fullid, "ID");  				cached_dpp->unpackU32(local_id, "LocalID"); @@ -369,6 +379,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			}  			else  			{ +				// Cache Miss. +				#if LL_RECORD_VIEWER_STATS +				LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type); +				#endif +  				continue; // no data packer, skip this object  			}  		} @@ -380,13 +395,15 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			compressed_dp.reset();  			U32 flags = 0; -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{  				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);  			} +			// I don't think we ever use this flag from the server.  DK 2010/12/09  			if (flags & FLAGS_ZLIB_COMPRESSED)  			{ +				//llinfos << "TEST: flags & FLAGS_ZLIB_COMPRESSED" << llendl;  				compressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);  				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compbuffer, 0, i);  				uncompressed_length = 2048; @@ -402,7 +419,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			} -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{  				compressed_dp.unpackUUID(fullid, "ID");  				compressed_dp.unpackU32(local_id, "LocalID"); @@ -422,7 +439,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				}  			}  		} -		else if (update_type != OUT_FULL) +		else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only?  		{  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);  			getUUIDFromLocal(fullid, @@ -435,7 +452,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				mNumUnknownUpdates++;  			}  		} -		else +		else // OUT_FULL only?  		{  			mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); @@ -467,12 +484,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  							gMessageSystem->getSenderPort());  			if (objectp->mLocalID != local_id) -			{    // Update local ID in object with the one sent from the region +			{	// Update local ID in object with the one sent from the region  				objectp->mLocalID = local_id;  			}  			if (objectp->getRegion() != regionp) -			{    // Object changed region, so update it +			{	// Object changed region, so update it  				objectp->updateRegion(regionp); // for LLVOAvatar  			}  		} @@ -483,18 +500,24 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			{  				if (update_type == OUT_TERSE_IMPROVED)  				{ -					// llinfos << "terse update for an unknown object:" << fullid << llendl; +					// llinfos << "terse update for an unknown object (compressed):" << fullid << llendl; +					#if LL_RECORD_VIEWER_STATS +					LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +					#endif  					continue;  				}  			} -			else if (cached) +			else if (cached) // Cache hit only?  			{  			}  			else  			{  				if (update_type != OUT_FULL)  				{ -					// llinfos << "terse update for an unknown object:" << fullid << llendl; +					//llinfos << "terse update for an unknown object:" << fullid << llendl; +					#if LL_RECORD_VIEWER_STATS +					LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +					#endif  					continue;  				} @@ -504,7 +527,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			if (mDeadObjects.find(fullid) != mDeadObjects.end())  			{  				mNumDeadObjectUpdates++; -				// llinfos << "update for a dead object:" << fullid << llendl; +				//llinfos << "update for a dead object:" << fullid << llendl; +				#if LL_RECORD_VIEWER_STATS +				LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +				#endif  				continue;  			}  #endif @@ -512,6 +538,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());  			if (!objectp)  			{ +				llinfos << "createObject failure for object: " << fullid << llendl; +				#if LL_RECORD_VIEWER_STATS +				LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); +				#endif  				continue;  			}  			justCreated = TRUE; @@ -524,19 +554,26 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;  		} +		bool bCached = false;  		if (compressed)  		{ -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{  				objectp->mLocalID = local_id;  			}  			processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); -			if (update_type != OUT_TERSE_IMPROVED) +			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{ +				bCached = true; +				#if LL_RECORD_VIEWER_STATS +				LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); +				LLViewerStatsRecorder::instance()->recordCacheFullUpdate(local_id, update_type, result, objectp); +				#else  				objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); +				#endif  			}  		} -		else if (cached) +		else if (cached) // Cache hit only?  		{  			objectp->mLocalID = local_id;  			processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated); @@ -549,8 +586,17 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			}  			processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);  		} +		#if LL_RECORD_VIEWER_STATS +		LLViewerStatsRecorder::instance()->recordObjectUpdateEvent(local_id, update_type, objectp); +		#endif +		objectp->setLastUpdateType(update_type); +		objectp->setLastUpdateCached(bCached);  	} +#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); +#endif +  	LLVOAvatar::cullAvatarsByPixelArea();  } @@ -681,12 +727,12 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	// update global timer  	F32 last_time = gFrameTimeSeconds; -	U64 time = totalTime();                 // this will become the new gFrameTime when the update is done +	U64 time = totalTime();				 // this will become the new gFrameTime when the update is done  	// Time _can_ go backwards, for example if the user changes the system clock.  	// It doesn't cause any fatal problems (just some oddness with stats), so we shouldn't assert here.  //	llassert(time > gFrameTime);  	F64 time_diff = U64_to_F64(time - gFrameTime)/(F64)SEC_TO_MICROSEC; -	gFrameTime    = time; +	gFrameTime	= time;  	F64 time_since_start = U64_to_F64(gFrameTime - gStartTime)/(F64)SEC_TO_MICROSEC;  	gFrameTimeSeconds = (F32)time_since_start; @@ -788,7 +834,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  		{  			std::string id_str;  			objectp->mID.toString(id_str); -			std::string tmpstr = std::string("Par:    ") + id_str; +			std::string tmpstr = std::string("Par:	") + id_str;  			addDebugBeacon(objectp->getPositionAgent(),  							tmpstr,  							LLColor4(1.f,0.f,0.f,1.f), @@ -808,12 +854,12 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  			std::string tmpstr;  			if (objectp->getParent())  			{ -				tmpstr = std::string("ChP:    ") + id_str; +				tmpstr = std::string("ChP:	") + id_str;  				text_color = LLColor4(0.f, 1.f, 0.f, 1.f);  			}  			else  			{ -				tmpstr = std::string("ChNoP:    ") + id_str; +				tmpstr = std::string("ChNoP:	") + id_str;  				text_color = LLColor4(1.f, 0.f, 0.f, 1.f);  			}  			id = sIndexAndLocalIDToUUID[oi.mParentInfo]; @@ -1519,8 +1565,8 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)  			llinfos << "Agent: " << objectp->getPositionAgent() << llendl;  			addDebugBeacon(objectp->getPositionAgent(),"");  #endif -            gPipeline.markMoved(objectp->mDrawable);                 -            objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE); +			gPipeline.markMoved(objectp->mDrawable);				 +			objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE);  			// Flag the object as no longer orphaned  			childp->mOrphaned = FALSE; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 2a67d12b64..c7649001c5 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -59,6 +59,7 @@  #include "llurldispatcher.h"  #include "llviewerobjectlist.h"  #include "llviewerparceloverlay.h" +#include "llviewerstatsrecorder.h"  #include "llvlmanager.h"  #include "llvlcomposition.h"  #include "llvocache.h" @@ -1032,7 +1033,7 @@ void LLViewerRegion::getInfo(LLSD& info)  	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;  } -void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)  {  	U32 local_id = objectp->getLocalID();  	U32 crc = objectp->getCRC(); @@ -1046,35 +1047,36 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary  		{  			// Record a hit  			entry->recordDupe(); +			return CACHE_UPDATE_DUPE;  		} -		else -		{ -			// Update the cache entry -			mCacheMap.erase(local_id); -			delete entry; -			entry = new LLVOCacheEntry(local_id, crc, dp); -			mCacheMap[local_id] = entry; -		} -	} -	else -	{ -		// we haven't seen this object before -		// Create new entry and add to map -		if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) -		{ -			mCacheMap.erase(mCacheMap.begin()); -		} +		// Update the cache entry +		mCacheMap.erase(local_id); +		delete entry;  		entry = new LLVOCacheEntry(local_id, crc, dp); -  		mCacheMap[local_id] = entry; +		return CACHE_UPDATE_CHANGED;  	} -	return ; + +	// we haven't seen this object before + +	// Create new entry and add to map +	eCacheUpdateResult result = CACHE_UPDATE_ADDED; +	if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) +	{ +		mCacheMap.erase(mCacheMap.begin()); +		result = CACHE_UPDATE_REPLACED; +		 +	} +	entry = new LLVOCacheEntry(local_id, crc, dp); + +	mCacheMap[local_id] = entry; +	return result;  }  // Get data packer for this object, if we have cached data  // AND the CRC matches. JC -LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc) +LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)  {  	llassert(mCacheLoaded); @@ -1087,17 +1089,20 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc)  		{  			// Record a hit  			entry->recordHit(); +			cache_miss_type = CACHE_MISS_TYPE_NONE;  			return entry->getDP(crc);  		}  		else  		{  			// llinfos << "CRC miss for " << local_id << llendl; +			cache_miss_type = CACHE_MISS_TYPE_CRC;  			mCacheMissCRC.put(local_id);  		}  	}  	else  	{  		// llinfos << "Cache miss for " << local_id << llendl; +		cache_miss_type = CACHE_MISS_TYPE_FULL;  		mCacheMissFull.put(local_id);  	}  	return NULL; @@ -1119,9 +1124,6 @@ void LLViewerRegion::requestCacheMisses()  	S32 blocks = 0;  	S32 i; -	const U8 CACHE_MISS_TYPE_FULL = 0; -	const U8 CACHE_MISS_TYPE_CRC  = 1; -  	// Send full cache miss updates.  For these, we KNOW we don't  	// have a viewer object.  	for (i = 0; i < full_count; i++) @@ -1184,6 +1186,11 @@ void LLViewerRegion::requestCacheMisses()  	mCacheDirty = TRUE ;  	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; +	#if LL_RECORD_VIEWER_STATS +	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this); +	LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count); +	LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); +	#endif  }  void LLViewerRegion::dumpCache() @@ -1372,11 +1379,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("DispatchRegionInfo");  	capabilityNames.append("EstateChangeInfo");  	capabilityNames.append("EventQueueGet"); -	capabilityNames.append("FetchInventory");  	capabilityNames.append("ObjectMedia");  	capabilityNames.append("ObjectMediaNavigate"); -	capabilityNames.append("FetchLib"); -	capabilityNames.append("FetchLibDescendents"); +	capabilityNames.append("FetchLib2"); +	capabilityNames.append("FetchLibDescendents2"); +	capabilityNames.append("FetchInventory2"); +	capabilityNames.append("FetchInventoryDescendents2");  	capabilityNames.append("GetDisplayNames");  	capabilityNames.append("GetTexture");  	capabilityNames.append("GroupProposalBallot"); @@ -1416,7 +1424,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); -	capabilityNames.append("WebFetchInventoryDescendents");  	// Please add new capabilities alphabetically to reduce  	// merge conflicts. diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 3d3f1d62a6..7c6559203e 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -51,7 +51,7 @@  // Surface id's  #define LAND  1  #define WATER 2 -const U32	MAX_OBJECT_CACHE_ENTRIES = 10000; +const U32	MAX_OBJECT_CACHE_ENTRIES = 50000;  class LLEventPoll; @@ -275,9 +275,24 @@ public:  	void getInfo(LLSD& info); +	typedef enum +	{ +		CACHE_MISS_TYPE_FULL = 0, +		CACHE_MISS_TYPE_CRC, +		CACHE_MISS_TYPE_NONE +	} eCacheMissType; + +	typedef enum +	{ +		CACHE_UPDATE_DUPE = 0, +		CACHE_UPDATE_CHANGED, +		CACHE_UPDATE_ADDED, +		CACHE_UPDATE_REPLACED +	} eCacheUpdateResult; +  	// handle a full update message -	void cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); -	LLDataPacker *getDP(U32 local_id, U32 crc); +	eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); +	LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type);  	void requestCacheMisses();  	void addCacheMissFull(const U32 local_id); diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp new file mode 100644 index 0000000000..e9d21b4848 --- /dev/null +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -0,0 +1,258 @@ +/** + * @file llviewerstatsrecorder.cpp + * @brief record info about viewer events to a metrics log file + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llviewerstatsrecorder.h" + +#if LL_RECORD_VIEWER_STATS + +#include "llfile.h" +#include "llviewerregion.h" +#include "llviewerobject.h" + + +// To do - something using region name or global position +#if LL_WINDOWS +	static const std::string STATS_FILE_NAME("C:\\ViewerObjectCacheStats.csv"); +#else +	static const std::string STATS_FILE_NAME("/tmp/viewerstats.csv"); +#endif + +LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL; +LLViewerStatsRecorder::LLViewerStatsRecorder() : +	mObjectCacheFile(NULL), +	mTimer(), +	mRegionp(NULL), +	mStartTime(0.f), +	mProcessingTime(0.f) +{ +	if (NULL != sInstance) +	{ +		llerrs << "Attempted to create multiple instances of LLViewerStatsRecorder!" << llendl; +	} +	sInstance = this; +	clearStats(); +} + +LLViewerStatsRecorder::~LLViewerStatsRecorder() +{ +	if (mObjectCacheFile != NULL) +	{ +		LLFile::close(mObjectCacheFile); +		mObjectCacheFile = NULL; +	} +} + +// static +void LLViewerStatsRecorder::initClass() +{ +	sInstance = new LLViewerStatsRecorder(); +} + +// static +void LLViewerStatsRecorder::cleanupClass() +{ +	delete sInstance; +	sInstance = NULL; +} + + +void LLViewerStatsRecorder::initStatsRecorder(LLViewerRegion *regionp) +{ +	if (mObjectCacheFile == NULL) +	{ +		mStartTime = LLTimer::getTotalTime(); +		mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); +		if (mObjectCacheFile) +		{	// Write column headers +			std::ostringstream data_msg; +			data_msg << "EventTime, " +				<< "ProcessingTime, " +				<< "CacheHits, " +				<< "CacheFullMisses, " +				<< "CacheCrcMisses, " +				<< "FullUpdates, " +				<< "TerseUpdates, " +				<< "CacheMissRequests, " +				<< "CacheMissResponses, " +				<< "CacheUpdateDupes, " +				<< "CacheUpdateChanges, " +				<< "CacheUpdateAdds, " +				<< "CacheUpdateReplacements, " +				<< "UpdateFailures" +				<< "\n"; + +			fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); +		} +	} +} + +void LLViewerStatsRecorder::beginObjectUpdateEvents(LLViewerRegion *regionp) +{ +	initStatsRecorder(regionp); +	mRegionp = regionp; +	mProcessingTime = LLTimer::getTotalTime(); +	clearStats(); +} + +void LLViewerStatsRecorder::clearStats() +{ +	mObjectCacheHitCount = 0; +	mObjectCacheMissFullCount = 0; +	mObjectCacheMissCrcCount = 0; +	mObjectFullUpdates = 0; +	mObjectTerseUpdates = 0; +	mObjectCacheMissRequests = 0; +	mObjectCacheMissResponses = 0; +	mObjectCacheUpdateDupes = 0; +	mObjectCacheUpdateChanges = 0; +	mObjectCacheUpdateAdds = 0; +	mObjectCacheUpdateReplacements = 0; +	mObjectUpdateFailures = 0; +} + + +void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type) +{ +	mObjectUpdateFailures++; +} + +void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type) +{ +	if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type) +	{ +		mObjectCacheMissFullCount++; +	} +	else +	{ +		mObjectCacheMissCrcCount++; +	} +} + +void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp) +{ +	switch (update_type) +	{ +	case OUT_FULL: +		mObjectFullUpdates++; +		break; +	case OUT_TERSE_IMPROVED: +		mObjectTerseUpdates++; +		break; +	case OUT_FULL_COMPRESSED: +		mObjectCacheMissResponses++; +		break; +	case OUT_FULL_CACHED: +		mObjectCacheHitCount++; +		break; +	default: +		llwarns << "Unknown update_type" << llendl; +		break; +	}; +} + +void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp) +{ +	switch (update_result) +	{ +		case LLViewerRegion::CACHE_UPDATE_DUPE: +			mObjectCacheUpdateDupes++; +			break; +		case LLViewerRegion::CACHE_UPDATE_CHANGED: +			mObjectCacheUpdateChanges++; +			break; +		case LLViewerRegion::CACHE_UPDATE_ADDED: +			mObjectCacheUpdateAdds++; +			break; +		case LLViewerRegion::CACHE_UPDATE_REPLACED: +			mObjectCacheUpdateReplacements++; +			break; +		default: +			llwarns << "Unknown update_result type" << llendl; +			break; +	}; +} + +void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count) +{ +	mObjectCacheMissRequests += count; +} + +void LLViewerStatsRecorder::endObjectUpdateEvents() +{ +	llinfos << "ILX: "  +		<< mObjectCacheHitCount << " hits, "  +		<< mObjectCacheMissFullCount << " full misses, " +		<< mObjectCacheMissCrcCount << " crc misses, " +		<< mObjectFullUpdates << " full updates, " +		<< mObjectTerseUpdates << " terse updates, " +		<< mObjectCacheMissRequests << " cache miss requests, " +		<< mObjectCacheMissResponses << " cache miss responses, " +		<< mObjectCacheUpdateDupes << " cache update dupes, " +		<< mObjectCacheUpdateChanges << " cache update changes, " +		<< mObjectCacheUpdateAdds << " cache update adds, " +		<< mObjectCacheUpdateReplacements << " cache update replacements, " +		<< mObjectUpdateFailures << " update failures" +		<< llendl; + +	S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; +	if (mObjectCacheFile != NULL && +		total_objects > 0) +	{ +		std::ostringstream data_msg; +		F32 processing32 = (F32) ((LLTimer::getTotalTime() - mProcessingTime) / 1000.0); + +		data_msg << getTimeSinceStart() +			<< ", " << processing32 +			<< ", " << mObjectCacheHitCount +			<< ", " << mObjectCacheMissFullCount +			<< ", " << mObjectCacheMissCrcCount +			<< ", " << mObjectFullUpdates +			<< ", " << mObjectTerseUpdates +			<< ", " << mObjectCacheMissRequests +			<< ", " << mObjectCacheMissResponses +			<< ", " << mObjectCacheUpdateDupes +			<< ", " << mObjectCacheUpdateChanges +			<< ", " << mObjectCacheUpdateAdds +			<< ", " << mObjectCacheUpdateReplacements +			<< ", " << mObjectUpdateFailures +			<< "\n"; + +		fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); +	} + +	clearStats(); +} + +F32 LLViewerStatsRecorder::getTimeSinceStart() +{ +	return (F32) ((LLTimer::getTotalTime() - mStartTime) / 1000.0); +} + +#endif + + + diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h new file mode 100644 index 0000000000..612ac380f7 --- /dev/null +++ b/indra/newview/llviewerstatsrecorder.h @@ -0,0 +1,97 @@ +/** + * @file llviewerstatsrecorder.h + * @brief record info about viewer events to a metrics log file + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LLVIEWERSTATSRECORDER_H +#define LLVIEWERSTATSRECORDER_H + + +// This is a diagnostic class used to record information from the viewer +// for analysis. + +// This is normally 0.  Set to 1 to enable viewer stats recording +#define LL_RECORD_VIEWER_STATS	0 + + +#if LL_RECORD_VIEWER_STATS +#include "llframetimer.h" +#include "llviewerobject.h" +#include "llviewerregion.h" + +class LLMutex; +class LLViewerRegion; +class LLViewerObject; + +class LLViewerStatsRecorder +{ + public: +	LLViewerStatsRecorder(); +	~LLViewerStatsRecorder(); + +	static void initClass(); +	static void cleanupClass(); +	static LLViewerStatsRecorder* instance() {return sInstance; } + +	void initStatsRecorder(LLViewerRegion *regionp); + +	void beginObjectUpdateEvents(LLViewerRegion *regionp); +	void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type); +	void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type); +	void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp); +	void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp); +	void recordRequestCacheMissesEvent(S32 count); +	void endObjectUpdateEvents(); + +	F32 getTimeSinceStart(); + +private: +	static LLViewerStatsRecorder* sInstance; + +	LLFILE *	mObjectCacheFile;		// File to write data into +	LLFrameTimer	mTimer; +	LLViewerRegion*	mRegionp; +	F64			mStartTime; +	F64			mProcessingTime; + +	S32			mObjectCacheHitCount; +	S32			mObjectCacheMissFullCount; +	S32			mObjectCacheMissCrcCount; +	S32			mObjectFullUpdates; +	S32			mObjectTerseUpdates; +	S32			mObjectCacheMissRequests; +	S32			mObjectCacheMissResponses; +	S32			mObjectCacheUpdateDupes; +	S32			mObjectCacheUpdateChanges; +	S32			mObjectCacheUpdateAdds; +	S32			mObjectCacheUpdateReplacements; +	S32			mObjectUpdateFailures; + + +	void	clearStats(); +}; +#endif	// LL_RECORD_VIEWER_STATS + +#endif // LLVIEWERSTATSRECORDER_H + diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 145ee31260..c26008d640 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -40,6 +40,7 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)  	return apr_file->write(src, n_bytes) == n_bytes ;  } +  //---------------------------------------------------------------------------  // LLVOCacheEntry  //--------------------------------------------------------------------------- @@ -212,8 +213,8 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  		if(success)  		{  			success = check_write(apr_file, (void*)mBuffer, size); +		}  	} -}  	return success ;  } @@ -224,7 +225,8 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  // Format string used to construct filename for the object cache  static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; -const U32 NUM_ENTRIES_TO_PURGE = 16 ; +// Throw out 1/20 (5%) of our cache entries if we run out of room. +const U32 ENTRIES_PURGE_FACTOR = 20;  const char* object_cache_dirname = "objectcache";  const char* header_filename = "object.cache"; @@ -259,7 +261,6 @@ void LLVOCache::destroyClass()  LLVOCache::LLVOCache():  	mInitialized(FALSE),  	mReadOnly(TRUE), -	mNumEntries(0),  	mCacheSize(1)  {  	mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled"); @@ -286,8 +287,15 @@ void LLVOCache::setDirNames(ELLPath location)  void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)  { -	if(mInitialized || !mEnabled) +	if(!mEnabled)  	{ +		llwarns << "Not initializing cache: Cache is currently disabled." << llendl; +		return ; +	} + +	if(mInitialized) +	{ +		llwarns << "Cache already initialized." << llendl;  		return ;  	} @@ -299,7 +307,6 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)  	mCacheSize = size; -	mMetaInfo.mVersion = cache_version;  	readCacheHeader();  	mInitialized = TRUE ; @@ -321,12 +328,14 @@ void LLVOCache::removeCache(ELLPath location)  {  	if(mReadOnly)  	{ +		llwarns << "Not removing cache at " << location << ": Cache is currently in read-only mode." << llendl;  		return ;  	}  	std::string delem = gDirUtilp->getDirDelimiter();  	std::string mask = delem + "*";  	std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname); +	llinfos << "Removing cache at " << cache_dir << llendl;  	gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files  	LLFile::rmdir(cache_dir); @@ -339,11 +348,13 @@ void LLVOCache::removeCache()  	llassert_always(mInitialized) ;  	if(mReadOnly)  	{ +		llwarns << "Not clearing object cache: Cache is currently in read-only mode." << llendl;  		return ;  	}  	std::string delem = gDirUtilp->getDirDelimiter();  	std::string mask = delem + "*"; +	llinfos << "Removing cache at " << mObjectCacheDirName << llendl;  	gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);   	clearCacheInMemory() ; @@ -352,16 +363,8 @@ void LLVOCache::removeCache()  void LLVOCache::clearCacheInMemory()  { -	if(!mHeaderEntryQueue.empty())  -	{ -		for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter) -		{ -			delete *iter ; -		} -		mHeaderEntryQueue.clear(); -		mHandleEntryMap.clear(); -		mNumEntries = 0 ; -	} +	std::for_each(mHandleEntryMap.begin(), mHandleEntryMap.end(), DeletePairedPointer()); +	mHandleEntryMap.clear();  }  void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)  @@ -379,6 +382,7 @@ void LLVOCache::removeFromCache(U64 handle)  {  	if(mReadOnly)  	{ +		llwarns << "Not removing cache for handle " << handle << ": Cache is currently in read-only mode." << llendl;  		return ;  	} @@ -387,24 +391,28 @@ void LLVOCache::removeFromCache(U64 handle)  	LLAPRFile::remove(filename, mLocalAPRFilePoolp);	  } -BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes)  +BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error)  {  	if(!check_read(apr_file, src, n_bytes))  	{ -		delete apr_file ; -		removeCache() ; +		if (remove_cache_on_error) +		{ +			removeCache() ; +		}  		return FALSE ;  	}  	return TRUE ;  } -BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes)  +BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error)   {  	if(!check_write(apr_file, src, n_bytes))  	{ -		delete apr_file ; -		removeCache() ; +		if (remove_cache_on_error) +		{ +			removeCache() ; +		}  		return FALSE ;  	} @@ -415,7 +423,8 @@ void LLVOCache::readCacheHeader()  {  	if(!mEnabled)  	{ -		return ; +		llwarns << "Not reading cache header: Cache is currently disabled." << llendl; +		return;  	}  	//clear stale info. @@ -423,33 +432,35 @@ void LLVOCache::readCacheHeader()  	if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))  	{ -		LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);		 +		LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_FOPEN_READ|APR_FOPEN_BINARY, mLocalAPRFilePoolp);		  		//read the meta element -		if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo))) +		bool remove_cache_on_error = false; +		if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo), remove_cache_on_error))  		{ -			return ; +			llwarns << "Error reading meta information from cache header." << llendl; +			delete apr_file; +			return;  		}  		HeaderEntryInfo* entry ; -		mNumEntries = 0 ; -		while(mNumEntries < mCacheSize) +		for(U32 entry_index = 0; entry_index < mCacheSize; ++entry_index)  		{  			entry = new HeaderEntryInfo() ; -			if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo))) +			if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo), remove_cache_on_error))  			{ +				llwarns << "Error reading cache header entry. (entry_index=" << entry_index << ")" << llendl;  				delete entry ;			 -				return ; +				break;  			}  			else if(!entry->mTime) //end of the cache.  			{  				delete entry ; -				return ; +				break;  			} -			entry->mIndex = mNumEntries++ ; -			mHeaderEntryQueue.insert(entry) ; -			mHandleEntryMap[entry->mHandle] = entry ; +			entry->mIndex = entry_index; +			mHandleEntryMap[entry->mHandle] = entry;  		}  		delete apr_file ; @@ -462,40 +473,57 @@ void LLVOCache::readCacheHeader()  void LLVOCache::writeCacheHeader()  { -	if(mReadOnly || !mEnabled) +	if (!mEnabled)  	{ -		return ; -	}	 +		llwarns << "Not writing cache header: Cache is currently disabled." << llendl; +		return; +	} + +	if(mReadOnly) +	{ +		llwarns << "Not writing cache header: Cache is currently in read-only mode." << llendl; +		return; +	} -	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BINARY|APR_FOPEN_TRUNCATE, mLocalAPRFilePoolp);  	//write the meta element  	if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))  	{ -		return ; +		llwarns << "Error writing meta information to cache header." << llendl; +		delete apr_file; +		return;  	} -	mNumEntries = 0 ; -	for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; iter != mHeaderEntryQueue.end(); ++iter) +	U32 entry_index = 0; +	handle_entry_map_t::iterator iter_end = mHandleEntryMap.end(); +	for(handle_entry_map_t::iterator iter = mHandleEntryMap.begin(); +		iter != iter_end; +		++iter)  	{ -		(*iter)->mIndex = mNumEntries++ ; -		if(!checkWrite(apr_file, (void*)*iter, sizeof(HeaderEntryInfo))) +		HeaderEntryInfo* entry = iter->second; +		entry->mIndex = entry_index++; +		if(!checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)))  		{ -			return ; +			llwarns << "Failed to write cache header for entry " << entry->mHandle << " (entry_index = " << entry_index << ")" << llendl; +			delete apr_file; +			return;  		}  	} -	mNumEntries = mHeaderEntryQueue.size() ; -	if(mNumEntries < mCacheSize) +	// Why do we need to fill the cache header with default entries?  DK 2010-12-14 +	// It looks like we currently rely on the file being pre-allocated so we can seek during updateEntry(). +	if(entry_index < mCacheSize)  	{  		HeaderEntryInfo* entry = new HeaderEntryInfo() ; -		for(U32 i = mNumEntries ; i < mCacheSize; i++) +		for(; entry_index < mCacheSize; ++entry_index)  		{  			//fill the cache with the default entry.  			if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo)))  			{ +				llwarns << "Failed to fill cache header with default entries (entry_index = " << entry_index << ").  Switching to read-only mode." << llendl;  				mReadOnly = TRUE ; //disable the cache. -				return ; +				break;  			}  		}  		delete entry ; @@ -505,16 +533,19 @@ void LLVOCache::writeCacheHeader()  BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)  { -	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_FOPEN_WRITE|APR_FOPEN_BINARY, mLocalAPRFilePoolp);  	apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; -	return checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; +	BOOL result = checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; +	delete apr_file; +	return result;  }  void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)   {  	if(!mEnabled)  	{ +		llwarns << "Not reading cache for handle " << handle << "): Cache is currently disabled." << llendl;  		return ;  	}  	llassert_always(mInitialized); @@ -522,22 +553,24 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;  	if(iter == mHandleEntryMap.end()) //no cache  	{ +		llwarns << "No handle map entry for " << handle << llendl;  		return ;  	}  	std::string filename;  	getObjectCacheFilename(handle, filename); -	LLAPRFile* apr_file = new LLAPRFile(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); +	LLAPRFile* apr_file = new LLAPRFile(filename, APR_FOPEN_READ|APR_FOPEN_BINARY, mLocalAPRFilePoolp);  	LLUUID cache_id ;  	if(!checkRead(apr_file, cache_id.mData, UUID_BYTES))  	{ +		llwarns << "Error reading cache_id from " << filename << llendl; +		delete apr_file;  		return ;  	}  	if(cache_id != id)  	{ -		llinfos << "Cache ID doesn't match for this region, discarding"<< llendl; - +		llwarns << "Cache ID (" << cache_id << ") doesn't match id for this region (" << id << "), discarding.  handle = " << handle << llendl;  		delete apr_file ;  		return ;  	} @@ -545,6 +578,8 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  	S32 num_entries;  	if(!checkRead(apr_file, &num_entries, sizeof(S32)))  	{ +		llwarns << "Error reading num_entries from " << filename << llendl; +		delete apr_file;  		return ;  	} @@ -553,13 +588,12 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  		LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);  		if (!entry->getLocalID())  		{ -			llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; +			llwarns << "Aborting cache file load for " << filename << ", cache file corruption! (entry number = " << i << ")" << llendl;  			delete entry ;  			break;  		}  		cache_entry_map[entry->getLocalID()] = entry;  	} -	num_entries = cache_entry_map.size() ;  	delete apr_file ;  	return ; @@ -567,86 +601,104 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  void LLVOCache::purgeEntries()  { -	U32 limit = mCacheSize - NUM_ENTRIES_TO_PURGE ; -	while(mHeaderEntryQueue.size() > limit) -	{ -		header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; -		HeaderEntryInfo* entry = *iter ; +	U32 limit = mCacheSize - (mCacheSize / ENTRIES_PURGE_FACTOR); +	limit = llclamp(limit, (U32)1, mCacheSize); +	// Construct a vector of entries out of the map so we can sort by time. +	std::vector<HeaderEntryInfo*> header_vector; +	handle_entry_map_t::iterator iter_end = mHandleEntryMap.end(); +	for (handle_entry_map_t::iterator iter = mHandleEntryMap.begin(); +		iter != iter_end; +		++iter) +	{ +		header_vector.push_back(iter->second); +	} +	// Sort by time, oldest first. +	std::sort(header_vector.begin(), header_vector.end(), header_entry_less()); +	while(header_vector.size() > limit) +	{ +		HeaderEntryInfo* entry = header_vector.front(); -		removeFromCache(entry->mHandle) ; -		mHandleEntryMap.erase(entry->mHandle) ;		 -		mHeaderEntryQueue.erase(iter) ; -		delete entry ; +		removeFromCache(entry->mHandle); +		mHandleEntryMap.erase(entry->mHandle); +		header_vector.erase(header_vector.begin()); +		delete entry;  	}  	writeCacheHeader() ; +	// *TODO: Verify that we can avoid re-reading the cache header.  DK 2010-12-14  	readCacheHeader() ; -	mNumEntries = mHandleEntryMap.size() ;  }  void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache)   {  	if(!mEnabled)  	{ +		llwarns << "Not writing cache for handle " << handle << "): Cache is currently disabled." << llendl;  		return ;  	}  	llassert_always(mInitialized);  	if(mReadOnly)  	{ +		llwarns << "Not writing cache for handle " << handle << "): Cache is currently in read-only mode." << llendl;  		return ;  	} +	U32 num_handle_entries = mHandleEntryMap.size(); +	  	HeaderEntryInfo* entry;  	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;  	if(iter == mHandleEntryMap.end()) //new entry -	{		 -		if(mNumEntries >= mCacheSize) +	{ +		if(num_handle_entries >= mCacheSize)  		{  			purgeEntries() ; +			num_handle_entries = mHandleEntryMap.size();  		}  		entry = new HeaderEntryInfo();  		entry->mHandle = handle ;  		entry->mTime = time(NULL) ; -		entry->mIndex = mNumEntries++ ; -		mHeaderEntryQueue.insert(entry) ; +		entry->mIndex = num_handle_entries++;  		mHandleEntryMap[handle] = entry ;  	}  	else  	{ +		// Update access time.  		entry = iter->second ;  		entry->mTime = time(NULL) ; - -		//resort -		mHeaderEntryQueue.erase(entry) ; -		mHeaderEntryQueue.insert(entry) ;  	}  	//update cache header  	if(!updateEntry(entry))  	{ +		llwarns << "Failed to update cache header index " << entry->mIndex << ". handle = " << handle << llendl;  		return ; //update failed.  	}  	if(!dirty_cache)  	{ +		llwarns << "Skipping write to cache for handle " << handle << ": cache not dirty" << llendl;  		return ; //nothing changed, no need to update.  	}  	//write to cache file  	std::string filename;  	getObjectCacheFilename(handle, filename); -	LLAPRFile* apr_file = new LLAPRFile(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +	LLAPRFile* apr_file = new LLAPRFile(filename, APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BINARY|APR_FOPEN_TRUNCATE, mLocalAPRFilePoolp);  	if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES))  	{ +		llwarns << "Error writing id to " << filename << llendl; +		delete apr_file;  		return ;  	}  	S32 num_entries = cache_entry_map.size() ;  	if(!checkWrite(apr_file, &num_entries, sizeof(S32)))  	{ +		llwarns << "Error writing num_entries to " << filename << llendl; +		delete apr_file;  		return ;  	} @@ -654,10 +706,10 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:  	{  		if(!iter->second->writeToFile(apr_file))  		{ +			llwarns << "Aborting cache file write for " << filename << ", error writing to file!" << llendl;  			//failed -			delete apr_file ;  			removeCache() ; -			return ; +			break;  		}  	} diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index ed2bc8bafe..e103007979 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -95,10 +95,13 @@ private:  	{  		bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const  		{ -			return lhs->mTime < rhs->mTime; // older entry in front of queue (set) +			if (lhs->mTime == rhs->mTime) +			{ +				return lhs->mHandle < rhs->mHandle; +			} +			return lhs->mTime < rhs->mTime; // older entry in front  		}  	}; -	typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;  	typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;  private:  	LLVOCache() ; @@ -125,8 +128,8 @@ private:  	void removeCache() ;  	void purgeEntries();  	BOOL updateEntry(const HeaderEntryInfo* entry); -	BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) ; -	BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) ; +	BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error = true) ; +	BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error = true) ;  private:  	BOOL                 mEnabled; @@ -134,11 +137,9 @@ private:  	BOOL                 mReadOnly ;  	HeaderMetaInfo       mMetaInfo;  	U32                  mCacheSize; -	U32                  mNumEntries;  	std::string          mHeaderFileName ;  	std::string          mObjectCacheDirName;  	LLVolatileAPRPool*   mLocalAPRFilePoolp ; 	 -	header_entry_queue_t mHeaderEntryQueue;  	handle_entry_map_t   mHandleEntryMap;	  	static LLVOCache* sInstance ; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 3f785a99fe..cef3d87f36 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -424,6 +424,7 @@ public:  		RENDER_DEBUG_AVATAR_VOLUME      = 0x0100000,  		RENDER_DEBUG_BUILD_QUEUE		= 0x0200000,  		RENDER_DEBUG_AGENT_TARGET       = 0x0400000, +		RENDER_DEBUG_UPDATE_TYPE		= 0x0800000,  	};  public: diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 62441fd984..75aec21f93 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -115,9 +115,6 @@       name="AlertCautionTextColor"       reference="LtYellow" />      <color -     name="AgentLinkColor" -     reference="EmphasisColor" /> -    <color       name="AlertTextColor"       value="0.58 0.66 0.84 1" />      <color @@ -349,9 +346,6 @@       name="GridlineShadowColor"       value="0 0 0 0.31" />      <color -     name="GroupLinkColor" -     reference="White" /> -    <color       name="GroupNotifyBoxColor"       value="0.3344 0.5456 0.5159 1" />      <color diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 70299c61b4..27024f4eaa 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1580,9 +1580,6 @@ Klik på Acceptér for at deltage eller Afvis for at afvise invitationen. Klik p  	<notification name="VoiceCallGenericError">  		En fejl er opstået under forsøget på at koble sig på stemme chatten [VOICE_CHANNEL_NAME].  Pråv venligst senere.  	</notification> -	<notification name="ServerVersionChanged"> -		Du er netop ankommet til en region der benytter en anden server version, hvilket kan influere på hastigheden. [[URL] For at se yderligere.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Den SLurl du klikkede på understøttes ikke.  	</notification> @@ -1636,7 +1633,7 @@ Knappen vil blive vist når der er nok plads til den.  	<notification name="ShareItemsConfirmation">  		Er du sikker på at du vil dele følgende genstande: -[ITEMS] +<nolink>[ITEMS]</nolink>  Med følgende beboere: diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 06cc02cd84..c26b02ec8f 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -2691,9 +2691,6 @@ Klicken Sie auf  'Akzeptieren ', um dem Chat beizutreten, oder auf  &a  	<notification name="VoiceCallGenericError">  		Fehler beim Versuch, eine Voice-Chat-Verbindung zu [VOICE_CHANNEL_NAME] herzustellen.  Bitte versuchen Sie es erneut.  	</notification> -	<notification name="ServerVersionChanged"> -		Sie haben eine Region betreten, die eine andere Server-Version verwendet. Dies kann sich auf die Leistung auswirken. [[URL] Versionshinweise anzeigen.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Die SLurl, auf die Sie geklickt haben, wird nicht unterstützt.  	</notification> @@ -2747,7 +2744,7 @@ Die Schaltfläche wird angezeigt, wenn genügend Platz vorhanden ist.  	<notification name="ShareItemsConfirmation">  		Möchten Sie diese Objekte wirklich für andere freigeben: -[ITEMS] +<nolink>[ITEMS]</nolink>  Für folgende Einwohner: diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index e70e1eb61b..1808fea445 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -872,12 +872,13 @@               length="1"               follows="left|top"               left_pad="0" -             height="30" +             height="20"               layout="topleft"               name="Creator Name"               top_delta="0"               width="190" -             word_wrap="true"> +             word_wrap="true" +             use_ellipses="ture">                  Mrs. Esbee Linden (esbee.linden)              </text>              <text @@ -888,7 +889,7 @@               height="19"               layout="topleft"               name="Owner:" -             top_pad="3" +             top_pad="13"               width="90">                  Owner:              </text> @@ -897,13 +898,14 @@               type="string"               length="1"               follows="left|top" -             height="30" +             height="20"               layout="topleft"               name="Owner Name"               left_pad="0"               top_delta="0"               width="190" -             word_wrap="true"> +             word_wrap="true" +             use_ellipses="true">                  Mrs. Erica "Moose" Linden (erica.linden)              </text>             <text @@ -914,7 +916,7 @@               left="10"               height="18"               name="Group:" -             top_pad="7" +             top_pad="17"               width="75">                  Group:              </text> diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index d90d0feda9..6ec063cd26 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -2,26 +2,26 @@  <floater    legacy_header_height="18"    can_resize="true" -  height="440" +  height="775"    layout="topleft" -  min_height="140" -  min_width="467" +  min_height="400" +  min_width="500"    name="floater_web_content"    help_topic="floater_web_content"    save_rect="true"    auto_tile="true"    title=""    initial_mime_type="text/html" -  width="820"> +  width="735">    <layout_stack -    bottom="440" +    bottom="775"      follows="left|right|top|bottom"      layout="topleft"      left="5"      name="stack1"      orientation="vertical"      top="20" -    width="810"> +    width="725">      <layout_panel        auto_resize="false"        default_tab_group="1" @@ -32,14 +32,14 @@        name="nav_controls"        top="400"        user_resize="false" -      width="800"> +      width="725">        <button          image_overlay="Arrow_Left_Off" -        image_disabled="PushButton_Disabled" -        image_disabled_selected="PushButton_Disabled" -        image_selected="PushButton_Selected" -        image_unselected="PushButton_Off" -        hover_glow_amount="0.15" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off" +		    hover_glow_amount="0.15"          tool_tip="Navigate back"          follows="left|top"          height="22" @@ -53,10 +53,10 @@        </button>        <button          image_overlay="Arrow_Right_Off" -        image_disabled="PushButton_Disabled" -        image_disabled_selected="PushButton_Disabled" -        image_selected="PushButton_Selected" -        image_unselected="PushButton_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off"          tool_tip="Navigate forward"          follows="left|top"          height="22" @@ -70,10 +70,10 @@        </button>        <button          image_overlay="Stop_Off" -        image_disabled="PushButton_Disabled" -        image_disabled_selected="PushButton_Disabled" -        image_selected="PushButton_Selected" -        image_unselected="PushButton_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off"          tool_tip="Stop navigation"          enabled="true"          follows="left|top" @@ -88,10 +88,10 @@        </button>        <button          image_overlay="Refresh_Off" -        image_disabled="PushButton_Disabled" -        image_disabled_selected="PushButton_Disabled" -        image_selected="PushButton_Selected" -        image_unselected="PushButton_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off"          tool_tip="Reload page"          follows="left|top"          height="22" @@ -115,7 +115,7 @@          combo_editor.select_on_focus="true"          tool_tip="Enter URL here"          top_delta="0" -        width="702"> +        width="627">          <combo_box.commit_callback            function="WebContent.EnterAddress" />        </combo_box> @@ -125,24 +125,24 @@          follows="top|right"          image_name="Lock2"          layout="topleft" -        left_delta="656" +        left_delta="575"          top_delta="2"          visible="false"           tool_tip="Secured Browsing"          width="16" />        <button          image_overlay="ExternalBrowser_Off" -        image_disabled="PushButton_Disabled" -        image_disabled_selected="PushButton_Disabled" -        image_selected="PushButton_Selected" -        image_unselected="PushButton_Off" +		    image_disabled="PushButton_Disabled" +		    image_disabled_selected="PushButton_Disabled" +		    image_selected="PushButton_Selected" +		    image_unselected="PushButton_Off"          tool_tip="Open current URL in your desktop browser"          follows="right|top"          enabled="true"           height="22"          layout="topleft"          name="popexternal" -        right="800" +        right="725"          top_delta="-2"          width="22">          <button.commit_callback @@ -166,16 +166,16 @@          top="0"/>        <text          type="string" -        length="100" +        length="200"          follows="bottom|left"          height="20"          layout="topleft"          left_delta="0"          name="statusbartext"          parse_urls="false" -        text_color="0.4 0.4 0.4 1"  +        text_color="0.4 0.4 0.4 1"          top_pad="5" -        width="452"/> +        width="520"/>        <progress_bar          color_bar="0.3 1.0 0.3 1"          follows="bottom|right" diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index c751aa4e0c..719509301b 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -100,7 +100,7 @@           name="Object Attach HUD" />     </context_menu>     <context_menu -         label="Remove" +         label="Manage"           name="Remove">     <menu_item_call           enabled="false" @@ -129,15 +129,6 @@           <menu_item_call.on_enable            function="Object.EnableReturn" />       </menu_item_call> -     <menu_item_call -   enabled="false" -   label="Delete" -   name="Delete"> -      <menu_item_call.on_click -       function="Object.Delete" /> -      <menu_item_call.on_enable -       function="Object.EnableDelete" /> -    </menu_item_call>      </context_menu>     <menu_item_separator layout="topleft" />     <menu_item_call @@ -176,4 +167,13 @@        <menu_item_call.on_enable         function="Object.EnableBuy" />     </menu_item_call> +   <menu_item_call +     enabled="false" +     label="Delete" +     name="Delete"> +      <menu_item_call.on_click +       function="Object.Delete" /> +      <menu_item_call.on_enable +       function="Object.EnableDelete" /> +  </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml index 6f46165883..1aeb166e01 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -25,6 +25,14 @@           function="Places.LandmarksGear.Enable"           parameter="category" />      </menu_item_call> +    <menu_item_call +     label="Restore Item" +     layout="topleft" +     name="restore_item"> +        <menu_item_call.on_click +         function="Places.LandmarksGear.Custom.Action" +         parameter="restore" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" />      <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml index 121e7cc07a..ff5fdd3795 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -60,6 +60,14 @@           function="Places.LandmarksGear.Enable"           parameter="category" />      </menu_item_call> +    <menu_item_call +     label="Restore Item" +     layout="topleft" +     name="restore_item"> +        <menu_item_call.on_click +         function="Places.LandmarksGear.Custom.Action" +         parameter="restore" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" />      <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 3d500c2371..2207e418c8 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2153,6 +2153,16 @@             parameter="render batches" />          </menu_item_check>          <menu_item_check +         label="Update Type" +         name="Update Type"> +          <menu_item_check.on_check +           function="Advanced.CheckInfoDisplay" +           parameter="update type" /> +          <menu_item_check.on_click +           function="Advanced.ToggleInfoDisplay" +           parameter="update type" /> +        </menu_item_check> +        <menu_item_check           label="Texture Anim"           name="Texture Anim">            <menu_item_check.on_check diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3df53ac442..f008042a81 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6304,15 +6304,6 @@ An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_N    </notification>    <notification -   duration="10" -   icon="notifytip.tga" -   name="ServerVersionChanged" -   priority="high" -   type="notifytip"> -You just entered a region using a different server version, which may affect performance. [[URL] View the release notes.] -  </notification> - -  <notification     icon="notifytip.tga"     name="UnsupportedCommandSLURL"     priority="high" @@ -6431,7 +6422,7 @@ Select residents to share with.     type="alertmodal">  Are you sure you want to share the following items: -[ITEMS] +<nolink>[ITEMS]</nolink>  With the following Residents: diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 61d6cbb2d0..eff674c628 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -67,23 +67,23 @@          <scroll_list.columns           label="Parcel"           name="name" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Region"           name="location" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Type"           name="type" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Area"           name="area" -         width="47" /> +         relative_width="0.2" />          <scroll_list.columns           label="Hidden"           name="hidden" -         width="47" /> +         relative_width="0.2" />      </scroll_list>      <text       type="string" diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 2dd7a6b0f5..1c31066962 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -2678,9 +2678,6 @@ Pulsa Aceptar o Rehusar para coger o no la llamada. Pulsa Ignorar para ignorar a  	<notification name="VoiceCallGenericError">  		Se ha producido un error al intentar conectarte al [VOICE_CHANNEL_NAME]. Por favor, inténtalo más tarde.  	</notification> -	<notification name="ServerVersionChanged"> -		Acabas de entrar en una región que usa un servidor con una versión distinta, y esto puede influir en el funcionamiento. [[URL] Ver las notas de desarrollo]. -	</notification>  	<notification name="UnsupportedCommandSLURL">  		No se admite el formato de la SLurl que has pulsado.  	</notification> @@ -2734,7 +2731,7 @@ Se mostrará cuando haya suficiente espacio.  	<notification name="ShareItemsConfirmation">  		¿Estás seguro de que quieres compartir los elementos siguientes? -[ITEMS] +<nolink>[ITEMS]</nolink>  Con los siguientes residentes: diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index ec362d7f22..2ccac5c19a 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2674,9 +2674,6 @@ Pour y participer, cliquez sur Accepter. Sinon, cliquez sur Refuser. Pour ignore  	<notification name="VoiceCallGenericError">  		Une erreur est survenue pendant la connexion au chat vocal pour [VOICE_CHANNEL_NAME]. Veuillez réessayer ultérieurement.  	</notification> -	<notification name="ServerVersionChanged"> -		La région dans laquelle vous avez pénétré utilise une version de serveur différente, ce qui peut avoir un impact sur votre performance. [[URL] Consultez les notes de version.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		La SLurl que vous avez saisie n'est pas prise en charge.  	</notification> @@ -2730,7 +2727,7 @@ Le bouton sera affiché quand il y aura suffisamment de place.  	<notification name="ShareItemsConfirmation">  		Voulez-vous vraiment partager les articles suivants : -[ITEMS] +<nolink>[ITEMS]</nolink>  avec les résidents suivants : diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 32483881b2..cce5888598 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -2623,9 +2623,6 @@ Clicca su Accetta per unirti alla chat oppure su Declina per declinare l'in  	<notification name="VoiceCallGenericError">  		Si è verificato un errore durante il tentativo di collegarti a una voice chat con [VOICE_CHANNEL_NAME].  Riprova più tardi.  	</notification> -	<notification name="ServerVersionChanged"> -		Sei appena entrato in una regione che usa una versione differente del server: ciò potrebbe incidere sule prestazioni. [[URL] Visualizza le note sulla versione.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Lo SLurl su cui hai cliccato non è valido.  	</notification> @@ -2679,7 +2676,7 @@ Il pulsante verrà visualizzato quando lo spazio sarà sufficiente.  	<notification name="ShareItemsConfirmation">  		Sei sicuro di volere condividere gli oggetti -[ITEMS] +<nolink>[ITEMS]</nolink>  Con i seguenti residenti? diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index c0af0e03ff..baec8c073c 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -2675,9 +2675,6 @@ M キーを押して変更します。  	<notification name="VoiceCallGenericError">  		[VOICE_CHANNEL_NAME] のボイスチャットに接続中に、エラーが発生しました。後でもう一度お試しください。  	</notification> -	<notification name="ServerVersionChanged"> -		サーバーのバージョンが異なるリージョンに来ました。パフォーマンスに影響することがあります。 [[URL] リリースノートを確認] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		クリックした SLurl はサポートされていません。  	</notification> @@ -2731,7 +2728,7 @@ M キーを押して変更します。  	<notification name="ShareItemsConfirmation">  		次のアイテムを共有しますか: -[ITEMS] +<nolink>[ITEMS]</nolink>  次の住人と共有しますか: diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml index be0c17d2ff..f27b83d3f9 100644 --- a/indra/newview/skins/default/xui/nl/notifications.xml +++ b/indra/newview/skins/default/xui/nl/notifications.xml @@ -3012,9 +3012,6 @@ Klik Accepteren om deel te nemen aan de chat of Afwijzen om de uitnodiging af te  	<notification name="VoiceCallGenericError">  		Er is een fout opgetreden tijdens het verbinden met voice chat voor [VOICE_CHANNEL_NAME]. Probeert u het later alstublieft opnieuw.  	</notification> -	<notification name="ServerVersionChanged"> -		De regio die u bent binnengetreden wordt onder een andere simulatorversie uitgevoerd. Klik dit bericht voor meer details. -	</notification>  	<notification name="UnableToOpenCommandURL">  		De URL die u heeft geklikt kan niet binnen deze webbrowser worden geopend.  	</notification> diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index 8151c7eb93..138125ff0b 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -2635,9 +2635,6 @@ Wybierz Zaakceptuj żeby zacząć czat albo Odmów żeby nie przyjąć zaproszen  	<notification name="VoiceCallGenericError">  		Błąd podczas łączenia z rozmową [VOICE_CHANNEL_NAME]. Spróbuj póżniej.  	</notification> -	<notification name="ServerVersionChanged"> -		Ten region używa innej wersji symulatora. Kliknij na tą wiadomość żeby uzyskać więcej informacji: [[URL] View the release notes.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		Nie można otworzyć wybranego SLurl.  	</notification> @@ -2691,7 +2688,7 @@ Przycisk zostanie wyświetlony w przypadku dostatecznej ilości przestrzeni.  	<notification name="ShareItemsConfirmation">  		Jesteś pewien/pewna, że chcesz udostępnić następujące obiekty: -[ITEMS] +<nolink>[ITEMS]</nolink>  następującym Rezydentom: diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index dc38b740aa..9c3b9386e0 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -477,7 +477,7 @@ Para aumentar a qualidade do vídeo, vá para Preferências > Vídeo.  	</notification>  	<notification name="CannotCopyWarning">  		Você não tem autorização para copiar os itens abaixo: -[ITENS] +[ITEMS]  ao dá-los, você ficará sem eles no seu inventário. Deseja realmente dar estes itens?  		<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>  	</notification> @@ -2658,9 +2658,6 @@ Clique em Aceitar para atender ou em Recusar para recusar este convite.  Clique  	<notification name="VoiceCallGenericError">  		Ocorreu um erro enquanto você tentava se conectar à conversa de voz de [VOICE_CHANNEL_NAME].  Favor tentar novamente mais tarde.  	</notification> -	<notification name="ServerVersionChanged"> -		Você chegou a uma região com uma versão diferente de servidor, que pode afetar o desempenho.  [[URL] Consultar notas da versão.] -	</notification>  	<notification name="UnsupportedCommandSLURL">  		O SLurl no qual você clicou não é suportado.  	</notification> @@ -2714,7 +2711,7 @@ O botão será exibido quando houver espaço suficente.  	<notification name="ShareItemsConfirmation">  		Tem certeza de que quer compartilhar os items abaixo? -[ITENS] +<nolink>[ITEMS]</nolink>  Com os seguintes residentes: diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp index dae22521bb..7862cce3a1 100644 --- a/indra/newview/tests/llremoteparcelrequest_test.cpp +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -32,6 +32,7 @@  #include "../llagent.h"  #include "message.h" +#include "llurlentry.h"  namespace {  	LLControlGroup s_saved_settings("dummy_settings"); @@ -72,6 +73,7 @@ LLUIColor::LLUIColor(void) { }  LLAgentAccess::LLAgentAccess(LLControlGroup & settings) : mSavedSettings(settings) { }  LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }  LLControlGroup::~LLControlGroup(void) { } +void LLUrlEntryParcel::processParcelInfo(const LLUrlEntryParcel::LLParcelData& parcel_data) { }  namespace tut  { diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index aa4983a3b6..ea242f45cd 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -361,6 +361,7 @@ void LLUpdaterServiceImpl::error(std::string const & message)  {  	if(mIsChecking)  	{ +		setState(LLUpdaterService::TEMPORARY_ERROR);  		restartTimer(mCheckPeriod);  	}  } diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 421481bc43..450f19c1c6 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -59,6 +59,7 @@ public:  	enum eUpdaterState {  		INITIAL,  		CHECKING_FOR_UPDATE, +		TEMPORARY_ERROR,  		DOWNLOADING,  		INSTALLING,  		UP_TO_DATE, | 
