diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 31 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 3 | ||||
| -rw-r--r-- | indra/newview/llcofwearables.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/lloutfitslist.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitedit.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitedit.h | 2 | ||||
| -rw-r--r-- | indra/newview/lltexlayer.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 74 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.h | 13 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.h | 10 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 12 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_login.xml | 1 | 
13 files changed, 165 insertions, 41 deletions
| diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 78edcb3e25..2729053390 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1275,6 +1275,11 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)  // static  bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)  { +	if (gAgentWearables.isCOFChangeInProgress()) +	{ +		return false; +	} +  	LLInventoryModel::cat_array_t cats;  	LLInventoryModel::item_array_t items;  	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); @@ -1286,6 +1291,32 @@ bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)  	return items.size() > 0;  } +bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) +{ +	// Don't allow wearing anything while we're changing appearance. +	if (gAgentWearables.isCOFChangeInProgress()) +	{ +		return false; +	} + +	// Check whether it's the base outfit. +	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID()) +	{ +		return false; +	} + +	// Check whether the outfit contains any non-worn wearables. +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ true); +	gInventory.collectDescendentsIf(outfit_cat_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		not_worn); +	return items.size() > 0; +} +  void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)  {  	LLInventoryModel::cat_array_t cats; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 9f554dbdef..eb495bd274 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -84,6 +84,9 @@ public:  	// Determine whether we can add anything (but body parts) from the outfit contents to COF.  	static bool getCanAddToCOF(const LLUUID& outfit_cat_id); +	// Determine whether we can replace current outfit with the given one. +	bool getCanReplaceCOF(const LLUUID& outfit_cat_id); +  	// Copy all items in a category.  	void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,  									 LLPointer<LLInventoryCallback> cb); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 893400185c..eb950bf6c1 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -163,7 +163,7 @@ public:  	}  protected: -	static void replaceWearable() +	static void replaceWearable(const LLUUID& item_id)  	{  		// *TODO: Most probable that accessing to LLPanelOutfitEdit instance should be:  		// LLSideTray::getInstance()->getSidepanelAppearance()->getPanelOutfitEdit() @@ -175,7 +175,7 @@ protected:  								"panel_outfit_edit"));  		if (panel_outfit_edit != NULL)  		{ -			panel_outfit_edit->showAddWearablesPanel(true); +			panel_outfit_edit->onReplaceMenuItemClicked(item_id);  		}  	} @@ -187,7 +187,7 @@ protected:  		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);  		registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs)); -		registrar.add("Clothing.Replace", boost::bind(replaceWearable)); +		registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));  		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));  		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id)); @@ -244,7 +244,7 @@ protected:  		// *HACK* need to pass pointer to LLPanelOutfitEdit instead of LLSideTray::getInstance()->getPanel().  		// LLSideTray::getInstance()->getPanel() is rather slow variant  		LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit")); -		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id)); +		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceMenuItemClicked, panel_oe, selected_id));  		registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));  		registrar.add("BodyPart.Create", boost::bind(&CofBodyPartContextMenu::createNew, this, selected_id)); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 8147a97317..f921bca623 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -275,11 +275,10 @@ protected:  		}  		else if ("wear_replace" == param)  		{ -			return !gAgentWearables.isCOFChangeInProgress(); +			return LLAppearanceMgr::instance().getCanReplaceCOF(outfit_cat_id);  		}  		else if ("wear_add" == param)  		{ -			if (gAgentWearables.isCOFChangeInProgress()) return false;  			return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id);  		}  		else if ("take_off" == param) @@ -676,7 +675,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)  		}  		// outfit selected -		return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID); +		return LLAppearanceMgr::instance().getCanReplaceCOF(mSelectedOutfitUUID);  	}  	if (command_name == "take_off")  	{ @@ -689,11 +688,6 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)  	if (command_name == "wear_add")  	{  		// *TODO: do we ever get here? -		if (gAgentWearables.isCOFChangeInProgress()) -		{ -			return false; -		} -  		return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);  	} diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 8b9baef54a..c12f1fbe99 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -609,11 +609,11 @@ void LLPanelOutfitEdit::onAddWearableClicked(void)  	}  } -void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id) +void LLPanelOutfitEdit::onReplaceMenuItemClicked(LLUUID selected_item_id)  {  	LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id); -	if (item && item->getType() == LLAssetType::AT_BODYPART) +	if (item)  	{  		showFilteredWearablesListView(item->getWearableType());  	} diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 0efc6dc189..5ce707e6eb 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -164,7 +164,7 @@ public:  	void onRemoveFromOutfitClicked(void);  	void onEditWearableClicked(void);  	void onAddWearableClicked(void); -	void onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id); +	void onReplaceMenuItemClicked(LLUUID selected_item_id);  	void onShopButtonClicked();  	void displayCurrentOutfit(); diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index f4f8241b99..1feb987682 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -542,8 +542,7 @@ void LLTexLayerSetBuffer::doUpload()  					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());  					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();  					args["RESOLUTION"] = lod_str; -					args["ACTION"] = "uploaded"; -					LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args); +					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);  					llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;  				}  			} @@ -593,8 +592,7 @@ void LLTexLayerSetBuffer::doUpdate()  		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());  		args["BODYREGION"] = mTexLayerSet->getBodyRegionName();  		args["RESOLUTION"] = lod_str; -		args["ACTION"] = "locally updated"; -		LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args); +		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);  		llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl;  	}  } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index dddfed097d..65a40a5b3a 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -850,15 +850,14 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if(mCanUseHTTP)  		{ -			const S32 HTTP_QUEUE_MAX_SIZE = 8;  			// *TODO: Integrate this with llviewerthrottle  			// Note: LLViewerThrottle uses dynamic throttling which makes sense for UDP,  			// but probably not for Textures.  			// Set the throttle to the entire bandwidth, assuming UDP packets will get priority  			// when they are needed  			F32 max_bandwidth = mFetcher->mMaxBandwidth; -			if ((mFetcher->getHTTPQueueSize() >= HTTP_QUEUE_MAX_SIZE) || -				(mFetcher->getTextureBandwidth() > max_bandwidth)) +			if (mFetcher->isHTTPThrottled(mDesiredSize) || +				mFetcher->getTextureBandwidth() > max_bandwidth)  			{  				// Make normal priority and return (i.e. wait until there is room in the queue)  				setPriority(LLWorkerThread::PRIORITY_NORMAL | mWorkPriority); @@ -1250,7 +1249,7 @@ bool LLTextureFetchWorker::deleteOK()  	if ((haveWork() &&  		 // not ok to delete from these states -		 ((mState >= SEND_HTTP_REQ && mState <= WAIT_HTTP_REQ) || +		 ((mState == WAIT_HTTP_REQ) ||  		  (mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))  	{  		delete_ok = false; @@ -1511,6 +1510,11 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  {  	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");  	mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); +	 +	for(S32 i = 0 ; i < TOTAL_TEXTURE_TYPES; i++) +	{ +		mHTTPThrottleFlag[i] = FALSE ; +	}  }  LLTextureFetch::~LLTextureFetch() @@ -1658,6 +1662,65 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id)  	mHTTPTextureQueue.erase(id);  } +void LLTextureFetch::clearHTTPThrottleFlag() +{ +	static const F32 WAIT_TIME = 0.3f ; //seconds. +	static LLFrameTimer timer ; + +	if(timer.getElapsedTimeF32() < WAIT_TIME) //wait for WAIT_TIME +	{ +		return ; +	} +	timer.reset() ; + +	LLMutexLock lock(&mNetworkQueueMutex); +	for(S32 i = 0 ; i < TOTAL_TEXTURE_TYPES; i++)//reset the http throttle flags. +	{ +		mHTTPThrottleFlag[i] = FALSE ; +	} +} + +//check if need to throttle this fetching request. +//rule: if a request can not be inserted into the http queue due to a full queue, +//      block all future insertions of requests with larger fetching size requirement. +//because: +//      later insertions are usually at lower priorities; and +//      small textures need chance to be fetched. +bool LLTextureFetch::isHTTPThrottled(S32 requested_size) +{ +	static const S32 SMALL_TEXTURE_MAX_SIZE = 64 * 64 * 4 ; +	static const S32 MEDIUM_TEXTURE_MAX_SIZE = 256 * 256 * 4 ; +	static const U32 MAX_HTTP_QUEUE_SIZE = 8 ; + +	//determine the class of the texture: SMALL, MEDIUM, or LARGE. +	S32 type = LARGE_TEXTURE ; +	if(requested_size <= SMALL_TEXTURE_MAX_SIZE) +	{ +		type = SMALL_TEXTURE ; +	} +	else if(requested_size <= MEDIUM_TEXTURE_MAX_SIZE) +	{ +		type = MEDIUM_TEXTURE ; +	} + +	LLMutexLock lock(&mNetworkQueueMutex); + +	if(mHTTPTextureQueue.size() >= MAX_HTTP_QUEUE_SIZE)//if the http queue is full. +	{ +		if(!mHTTPThrottleFlag[type + 1]) +		{ +			for(S32 i = type + 1 ; i < TOTAL_TEXTURE_TYPES; i++) //block all requests with fetching size larger than this request.		 +			{ +				mHTTPThrottleFlag[i] = TRUE ;			 +			} +		} +		 +		return true ; +	} + +	return mHTTPThrottleFlag[type] ; //true if this request can not be inserted to the http queue. +} +  void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)  {  	lockQueue() ; @@ -1824,7 +1887,8 @@ S32 LLTextureFetch::update(U32 max_time_ms)  			lldebugs << "processed: " << processed << " messages." << llendl;  		}  	} -	 +	clearHTTPThrottleFlag(); +  	return res;  } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 634e590fe0..c31c38b04a 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -95,7 +95,8 @@ protected:  	void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);  	void addToHTTPQueue(const LLUUID& id);  	void removeFromHTTPQueue(const LLUUID& id); -	S32 getHTTPQueueSize() { return getNumHTTPRequests(); } +	bool isHTTPThrottled(S32 requested_size); +	void clearHTTPThrottleFlag();  	void removeRequest(LLTextureFetchWorker* worker, bool cancel);  	// Called from worker thread (during doWork)  	void processCurlRequests();	 @@ -134,6 +135,16 @@ private:  	F32 mTextureBandwidth;  	F32 mMaxBandwidth;  	LLTextureInfo mTextureInfo; + +	enum +	{ +		SMALL_TEXTURE = 0 , //size <= 64 * 64 +		MEDIUM_TEXTURE,     //size <= 256 * 256 +		LARGE_TEXTURE,      //size > 256 * 256 +		DUMMY, +		TOTAL_TEXTURE_TYPES +	}; +	BOOL mHTTPThrottleFlag[TOTAL_TEXTURE_TYPES];  };  #endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 004d138221..82fef1d916 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -79,6 +79,8 @@  // format changes. JC  const U32 INDRA_OBJECT_CACHE_VERSION = 14; +// Format string used to construct filename for the object cache +static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";  extern BOOL gNoRender; @@ -323,13 +325,25 @@ LLViewerRegion::~LLViewerRegion()  	delete mEventPoll;  	LLHTTPSender::clearSender(mHost); -	saveCache(); +	saveObjectCache();  	std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());  } -void LLViewerRegion::loadCache() +const std::string LLViewerRegion::getObjectCacheFilename(U64 mHandle) const +{ +	std::string filename; +	U32 region_x, region_y; + +	grid_from_region_handle(mHandle, ®ion_x, ®ion_y); +	filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, +			   llformat(OBJECT_CACHE_FILENAME, region_x, region_y)); + +	return filename; +} + +void LLViewerRegion::loadObjectCache()  {  	if (mCacheLoaded)  	{ @@ -341,9 +355,8 @@ void LLViewerRegion::loadCache()  	LLVOCacheEntry *entry; -	std::string filename; -	filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() + -		llformat("objects_%d_%d.slc",U32(mHandle>>32)/REGION_WIDTH_UNITS, U32(mHandle)/REGION_WIDTH_UNITS ); +	std::string filename = getObjectCacheFilename(mHandle); +	LL_DEBUGS("ObjectCache") << filename << LL_ENDL;  	LLFILE* fp = LLFile::fopen(filename, "rb");		/* Flawfinder: ignore */  	if (!fp) @@ -414,7 +427,7 @@ void LLViewerRegion::loadCache()  } -void LLViewerRegion::saveCache() +void LLViewerRegion::saveObjectCache()  {  	if (!mCacheLoaded)  	{ @@ -427,9 +440,8 @@ void LLViewerRegion::saveCache()  		return;  	} -	std::string filename; -	filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() + -		llformat("objects_%d_%d.slc", U32(mHandle>>32)/REGION_WIDTH_UNITS, U32(mHandle)/REGION_WIDTH_UNITS ); +	std::string filename = getObjectCacheFilename(mHandle); +	LL_DEBUGS("ObjectCache") << filename << LL_ENDL;  	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */  	if (!fp) @@ -1454,7 +1466,7 @@ void LLViewerRegion::unpackRegionHandshake()  	// Now that we have the name, we can load the cache file  	// off disk. -	loadCache(); +	loadObjectCache();  	// After loading cache, signal that simulator can start  	// sending data. diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index a9e7ef771c..8254cf1cad 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -99,9 +99,8 @@ public:  	~LLViewerRegion();  	// Call this after you have the region name and handle. -	void loadCache(); - -	void saveCache(); +	void loadObjectCache(); +	void saveObjectCache();  	void sendMessage(); // Send the current message to this region's simulator  	void sendReliableMessage(); // Send the current message to this region's simulator @@ -330,6 +329,9 @@ public:  	LLDynamicArray<LLUUID> mMapAvatarIDs;  private: +	// determine the cache filename for the region from the region handle +	const std::string getObjectCacheFilename(U64 mHandle) const; +  	// The surfaces and other layers  	LLSurface*	mLandp; @@ -404,7 +406,7 @@ private:  	// Cache ID is unique per-region, across renames, moving locations,  	// etc.  	LLUUID mCacheID; -	 +  	typedef std::map<std::string, std::string> CapabilityMap;  	CapabilityMap mCapabilities; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 95ee374e39..3576462cca 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6340,10 +6340,18 @@ Avatar '[NAME]' left as fully loaded.    <notification     icon="notifytip.tga" -   name="AvatarRezSelfBakeNotification" +   name="AvatarRezSelfBakedTextureUploadNotification"     type="notifytip">  ( [EXISTENCE] seconds alive ) -You [ACTION] a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. +You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. +  </notification> + +  <notification +   icon="notifytip.tga" +   name="AvatarRezSelfBakedTextureUpdateNotification" +   type="notifytip"> +( [EXISTENCE] seconds alive ) +You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.    </notification>    <notification diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 185e458a85..0499873fb0 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -156,6 +156,7 @@ width="135"    visible="false" />  </layout_panel>  <layout_panel +tab_stop="false"  follows="right|bottom"  name="links"  width="200" | 
