summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Linden <eli@lindenlab.com>2010-08-04 12:52:06 -0700
committerEli Linden <eli@lindenlab.com>2010-08-04 12:52:06 -0700
commitb4b503d4ac3fb43aea61a9c0b7adb0ae50b096ab (patch)
tree987739481f5baf68605705c3cfba3e1e8ff6bf19
parentb3fd508cff74da6b8620dc440482e41fabc9337a (diff)
parentaaa41211c83a9dcc9ff3db84c7e4b9de985be692 (diff)
Merge
-rw-r--r--indra/llcommon/llversionviewer.h2
-rw-r--r--indra/newview/llappearancemgr.cpp31
-rw-r--r--indra/newview/llappearancemgr.h3
-rw-r--r--indra/newview/llcofwearables.cpp8
-rw-r--r--indra/newview/lloutfitslist.cpp10
-rw-r--r--indra/newview/llpaneloutfitedit.cpp4
-rw-r--r--indra/newview/llpaneloutfitedit.h2
-rw-r--r--indra/newview/lltexlayer.cpp6
-rw-r--r--indra/newview/lltexturefetch.cpp74
-rw-r--r--indra/newview/lltexturefetch.h13
-rw-r--r--indra/newview/llviewerregion.cpp32
-rw-r--r--indra/newview/llviewerregion.h10
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml1
14 files changed, 166 insertions, 42 deletions
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 6e341b83a1..c430a60ff0 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -35,7 +35,7 @@
const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 1;
-const S32 LL_VERSION_PATCH = 0;
+const S32 LL_VERSION_PATCH = 1;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";
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, &region_x, &region_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"