merge
commit
d77c3e3600
|
|
@ -1305,16 +1305,8 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
|
|||
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;
|
||||
// Check whether the outfit contains the full set of body parts (shape+skin+hair+eyes).
|
||||
return getCanMakeFolderIntoOutfit(outfit_cat_id);
|
||||
}
|
||||
|
||||
void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
|
||||
|
|
@ -2514,29 +2506,17 @@ void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
|
|||
|
||||
switch (item_to_remove->getType())
|
||||
{
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
if (get_is_item_worn(id_to_remove))
|
||||
{
|
||||
//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
|
||||
LLWearableBridge::removeItemFromAvatar(item_to_remove);
|
||||
}
|
||||
break;
|
||||
case LLAssetType::AT_OBJECT:
|
||||
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_to_remove->getLinkedUUID());
|
||||
gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
|
||||
|
||||
{
|
||||
// this object might have been selected, so let the selection manager know it's gone now
|
||||
LLViewerObject *found_obj = gObjectList.findObject(item_to_remove->getLinkedUUID());
|
||||
if (found_obj)
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
if (get_is_item_worn(id_to_remove))
|
||||
{
|
||||
LLSelectMgr::getInstance()->remove(found_obj);
|
||||
};
|
||||
}
|
||||
default: break;
|
||||
//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
|
||||
LLWearableBridge::removeItemFromAvatar(item_to_remove);
|
||||
}
|
||||
break;
|
||||
case LLAssetType::AT_OBJECT:
|
||||
LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// *HACK: Force to remove garbage from COF.
|
||||
|
|
@ -2676,7 +2656,6 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
|
|||
mAttachmentInvLinkEnabled = val;
|
||||
}
|
||||
|
||||
// BAP TODO - mRegisteredAttachments is currently maintained but not used for anything. Consider yanking.
|
||||
void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
|
||||
{
|
||||
llinfos << msg << llendl;
|
||||
|
|
@ -2696,7 +2675,6 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
|
|||
|
||||
void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
|
||||
{
|
||||
mRegisteredAttachments.insert(item_id);
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
|
||||
|
||||
if (mAttachmentInvLinkEnabled)
|
||||
|
|
@ -2714,7 +2692,6 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
|
|||
|
||||
void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
|
||||
{
|
||||
mRegisteredAttachments.erase(item_id);
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
|
||||
|
||||
if (mAttachmentInvLinkEnabled)
|
||||
|
|
@ -2727,18 +2704,6 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
|
|||
}
|
||||
}
|
||||
|
||||
void LLAppearanceMgr::linkRegisteredAttachments()
|
||||
{
|
||||
for (std::set<LLUUID>::iterator it = mRegisteredAttachments.begin();
|
||||
it != mRegisteredAttachments.end();
|
||||
++it)
|
||||
{
|
||||
LLUUID item_id = *it;
|
||||
addCOFItemLink(item_id, false);
|
||||
}
|
||||
mRegisteredAttachments.clear();
|
||||
}
|
||||
|
||||
BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
|
||||
{
|
||||
return gInventory.isObjectDescendentOf(obj_id, getCOF());
|
||||
|
|
|
|||
|
|
@ -123,7 +123,6 @@ public:
|
|||
void unregisterAttachment(const LLUUID& item_id);
|
||||
void registerAttachment(const LLUUID& item_id);
|
||||
void setAttachmentInvLinkEnable(bool val);
|
||||
void linkRegisteredAttachments();
|
||||
|
||||
// utility function for bulk linking.
|
||||
void linkAll(const LLUUID& category,
|
||||
|
|
@ -210,7 +209,6 @@ private:
|
|||
|
||||
void setOutfitLocked(bool locked);
|
||||
|
||||
std::set<LLUUID> mRegisteredAttachments;
|
||||
bool mAttachmentInvLinkEnabled;
|
||||
bool mOutfitIsDirty;
|
||||
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include "llbutton.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lltrans.h"
|
||||
|
|
@ -90,8 +89,6 @@ BOOL LLFloaterGroupPicker::postBuild()
|
|||
list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP);
|
||||
}
|
||||
|
||||
LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterGroupPicker::onBtnCancel, this));
|
||||
|
||||
childSetAction("OK", onBtnOK, this);
|
||||
|
||||
childSetAction("Cancel", onBtnCancel, this);
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ void copy_selected_item(void* user_data);
|
|||
void open_selected_items(void* user_data);
|
||||
void properties_selected_items(void* user_data);
|
||||
void paste_items(void* user_data);
|
||||
void renamer_focus_lost( LLFocusableElement* handler, void* user_data );
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -275,6 +274,8 @@ LLFolderView::LLFolderView(const Params& p)
|
|||
// Destroys the object
|
||||
LLFolderView::~LLFolderView( void )
|
||||
{
|
||||
closeRenamer();
|
||||
|
||||
// The release focus call can potentially call the
|
||||
// scrollcontainer, which can potentially be called with a partly
|
||||
// destroyed scollcontainer. Just null it out here, and no worries
|
||||
|
|
@ -290,8 +291,6 @@ LLFolderView::~LLFolderView( void )
|
|||
|
||||
LLView::deleteViewByHandle(mPopupMenuHandle);
|
||||
|
||||
gViewerWindow->removePopup(mRenamer);
|
||||
|
||||
mAutoOpenItems.removeAllNodes();
|
||||
clearSelection();
|
||||
mItems.clear();
|
||||
|
|
@ -998,12 +997,7 @@ void LLFolderView::finishRenamingItem( void )
|
|||
mRenameItem->rename( mRenamer->getText() );
|
||||
}
|
||||
|
||||
gViewerWindow->removePopup(mRenamer);
|
||||
|
||||
if( mRenameItem )
|
||||
{
|
||||
setSelectionFromRoot( mRenameItem, TRUE );
|
||||
}
|
||||
closeRenamer();
|
||||
|
||||
// List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
|
||||
scrollToShowSelection();
|
||||
|
|
@ -1011,15 +1005,10 @@ void LLFolderView::finishRenamingItem( void )
|
|||
|
||||
void LLFolderView::closeRenamer( void )
|
||||
{
|
||||
// will commit current name (which could be same as original name)
|
||||
mRenamer->setFocus( FALSE );
|
||||
mRenamer->setVisible( FALSE );
|
||||
gViewerWindow->removePopup(mRenamer);
|
||||
|
||||
if( mRenameItem )
|
||||
if (mRenamer && mRenamer->getVisible())
|
||||
{
|
||||
setSelectionFromRoot( mRenameItem, TRUE );
|
||||
mRenameItem = NULL;
|
||||
// Triggers onRenamerLost() that actually closes the renamer.
|
||||
gViewerWindow->removePopup(mRenamer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1444,8 +1433,7 @@ void LLFolderView::startRenamingSelectedItem( void )
|
|||
mRenamer->setVisible( TRUE );
|
||||
// set focus will fail unless item is visible
|
||||
mRenamer->setFocus( TRUE );
|
||||
mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this, _1));
|
||||
mRenamer->setFocusLostCallback(boost::bind(&LLFolderView::onRenamerLost, this, _1));
|
||||
mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
|
||||
gViewerWindow->addPopup(mRenamer);
|
||||
}
|
||||
}
|
||||
|
|
@ -1966,10 +1954,7 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||
|
||||
void LLFolderView::deleteAllChildren()
|
||||
{
|
||||
if(mRenamer == gFocusMgr.getTopCtrl())
|
||||
{
|
||||
gViewerWindow->removePopup(mRenamer);
|
||||
}
|
||||
closeRenamer();
|
||||
LLView::deleteViewByHandle(mPopupMenuHandle);
|
||||
mPopupMenuHandle = LLHandle<LLView>();
|
||||
mRenamer = NULL;
|
||||
|
|
@ -2452,13 +2437,20 @@ S32 LLFolderView::notify(const LLSD& info)
|
|||
/// Local function definitions
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
void LLFolderView::onRenamerLost( LLFocusableElement* renamer)
|
||||
void LLFolderView::onRenamerLost()
|
||||
{
|
||||
mRenameItem = NULL;
|
||||
LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer);
|
||||
if (uictrl)
|
||||
if (mRenamer && mRenamer->getVisible())
|
||||
{
|
||||
uictrl->setVisible(FALSE);
|
||||
mRenamer->setVisible(FALSE);
|
||||
|
||||
// will commit current name (which could be same as original name)
|
||||
mRenamer->setFocus(FALSE);
|
||||
}
|
||||
|
||||
if( mRenameItem )
|
||||
{
|
||||
setSelectionFromRoot( mRenameItem, TRUE );
|
||||
mRenameItem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ protected:
|
|||
LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
|
||||
|
||||
void commitRename( const LLSD& data );
|
||||
void onRenamerLost( LLFocusableElement* renamer);
|
||||
void onRenamerLost();
|
||||
|
||||
void finishRenamingItem( void );
|
||||
void closeRenamer( void );
|
||||
|
|
|
|||
|
|
@ -3957,18 +3957,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
LLInventoryItem* item = gInventory.getItem(mUUID);
|
||||
if(item)
|
||||
{
|
||||
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
|
||||
gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
|
||||
|
||||
// this object might have been selected, so let the selection manager know it's gone now
|
||||
LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID());
|
||||
if (found_obj)
|
||||
{
|
||||
LLSelectMgr::getInstance()->remove(found_obj);
|
||||
}
|
||||
LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID());
|
||||
}
|
||||
}
|
||||
else LLItemBridge::performAction(model, action);
|
||||
|
|
@ -3985,6 +3974,11 @@ std::string LLObjectBridge::getLabelSuffix() const
|
|||
{
|
||||
if (get_is_item_worn(mUUID))
|
||||
{
|
||||
if (!isAgentAvatarValid())
|
||||
{
|
||||
return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
|
||||
}
|
||||
|
||||
std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID);
|
||||
|
||||
// e.g. "(worn on ...)" / "(attached to ...)"
|
||||
|
|
@ -4329,19 +4323,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
|
|||
LLViewerInventoryItem *obj_item = obj_item_array.get(i);
|
||||
if (get_is_item_worn(obj_item->getUUID()))
|
||||
{
|
||||
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() );
|
||||
|
||||
gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
|
||||
|
||||
// this object might have been selected, so let the selection manager know it's gone now
|
||||
LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID());
|
||||
if (found_obj)
|
||||
{
|
||||
LLSelectMgr::getInstance()->remove(found_obj);
|
||||
}
|
||||
LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,12 +386,26 @@ BOOL LLPanelOutfitEdit::postBuild()
|
|||
|
||||
childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
|
||||
|
||||
/*
|
||||
* By default AT_CLOTHING are sorted by (in in MY OUTFITS):
|
||||
* - by type (types order determined in LLWearableType::EType)
|
||||
* - each LLWearableType::EType by outer layer on top
|
||||
*
|
||||
* In Add More panel AT_CLOTHING should be sorted in a such way:
|
||||
* - by type (types order determined in LLWearableType::EType)
|
||||
* - each LLWearableType::EType by name (EXT-8205)
|
||||
*/
|
||||
mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator();
|
||||
mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANG_1, false, true);
|
||||
|
||||
mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel");
|
||||
mWearableItemsList = getChild<LLInventoryItemsList>("list_view");
|
||||
mWearableItemsList->setCommitOnSelectionChange(true);
|
||||
mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));
|
||||
mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
|
||||
|
||||
mWearableItemsList->setComparator(mWearableListViewItemsComparator);
|
||||
|
||||
mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class LLMenuGL;
|
|||
class LLFindNonLinksByMask;
|
||||
class LLFindWearablesOfType;
|
||||
class LLSaveOutfitComboBtn;
|
||||
class LLWearableItemTypeNameComparator;
|
||||
|
||||
class LLPanelOutfitEdit : public LLPanel
|
||||
{
|
||||
|
|
@ -222,6 +223,7 @@ private:
|
|||
LLFilteredWearableListManager* mWearableListManager;
|
||||
LLInventoryItemsList* mWearableItemsList;
|
||||
LLPanel* mWearablesListViewPanel;
|
||||
LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;
|
||||
|
||||
LLCOFDragAndDropObserver* mCOFDragAndDropObserver;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "llviewertexturelist.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llworld.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -150,7 +151,7 @@ public:
|
|||
~LLTextureFetchWorker();
|
||||
void relese() { --mActiveCount; }
|
||||
|
||||
void callbackHttpGet(const LLChannelDescriptors& channels,
|
||||
S32 callbackHttpGet(const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer,
|
||||
bool partial, bool success);
|
||||
void callbackCacheRead(bool success, LLImageFormatted* image,
|
||||
|
|
@ -335,8 +336,9 @@ public:
|
|||
worker->setGetStatus(status, reason);
|
||||
// llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl;
|
||||
}
|
||||
mFetcher->removeFromHTTPQueue(mID);
|
||||
worker->callbackHttpGet(channels, buffer, partial, success);
|
||||
|
||||
S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success);
|
||||
mFetcher->removeFromHTTPQueue(mID, data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -850,19 +852,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
{
|
||||
if(mCanUseHTTP)
|
||||
{
|
||||
// *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->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);
|
||||
return false;
|
||||
}
|
||||
//NOTE:
|
||||
//it seems ok to let sim control the UDP traffic
|
||||
//so there is no throttle for http here.
|
||||
//
|
||||
|
||||
mFetcher->removeFromNetworkQueue(this, false);
|
||||
|
||||
|
|
@ -979,6 +972,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
else
|
||||
{
|
||||
resetFormattedData();
|
||||
mState = DONE;
|
||||
return true; // failed
|
||||
}
|
||||
}
|
||||
|
|
@ -1271,8 +1265,7 @@ bool LLTextureFetchWorker::deleteOK()
|
|||
|
||||
if ((haveWork() &&
|
||||
// not ok to delete from these states
|
||||
((mState == WAIT_HTTP_REQ) ||
|
||||
(mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))
|
||||
((mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))
|
||||
{
|
||||
delete_ok = false;
|
||||
}
|
||||
|
|
@ -1351,29 +1344,29 @@ bool LLTextureFetchWorker::processSimulatorPackets()
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
|
||||
S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer,
|
||||
bool partial, bool success)
|
||||
{
|
||||
S32 data_size = 0 ;
|
||||
|
||||
LLMutexLock lock(&mWorkMutex);
|
||||
|
||||
if (mState != WAIT_HTTP_REQ)
|
||||
{
|
||||
llwarns << "callbackHttpGet for unrequested fetch worker: " << mID
|
||||
<< " req=" << mSentRequest << " state= " << mState << llendl;
|
||||
return;
|
||||
return data_size;
|
||||
}
|
||||
if (mLoaded)
|
||||
{
|
||||
llwarns << "Duplicate callback for " << mID.asString() << llendl;
|
||||
return; // ignore duplicate callback
|
||||
return data_size ; // ignore duplicate callback
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
// get length of stream:
|
||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||
|
||||
gTextureList.sTextureBits += data_size * 8; // Approximate - does not include header bits
|
||||
data_size = buffer->countAfter(channels.in(), NULL);
|
||||
|
||||
LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL;
|
||||
if (data_size > 0)
|
||||
|
|
@ -1410,6 +1403,8 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
|
|||
}
|
||||
mLoaded = TRUE;
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||
|
||||
return data_size ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1528,15 +1523,11 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mTextureCache(cache),
|
||||
mImageDecodeThread(imagedecodethread),
|
||||
mTextureBandwidth(0),
|
||||
mHTTPTextureBits(0),
|
||||
mCurlGetRequest(NULL)
|
||||
{
|
||||
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()
|
||||
|
|
@ -1678,69 +1669,11 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
|
|||
mHTTPTextureQueue.insert(id);
|
||||
}
|
||||
|
||||
void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id)
|
||||
void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size)
|
||||
{
|
||||
LLMutexLock lock(&mNetworkQueueMutex);
|
||||
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.
|
||||
mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits
|
||||
}
|
||||
|
||||
void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
|
||||
|
|
@ -1888,12 +1821,19 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
|
|||
//virtual
|
||||
S32 LLTextureFetch::update(U32 max_time_ms)
|
||||
{
|
||||
S32 res;
|
||||
|
||||
static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS");
|
||||
mMaxBandwidth = band_width ;
|
||||
|
||||
res = LLWorkerThread::update(max_time_ms);
|
||||
|
||||
{
|
||||
mNetworkQueueMutex.lock() ;
|
||||
mMaxBandwidth = band_width ;
|
||||
|
||||
gTextureList.sTextureBits += mHTTPTextureBits ;
|
||||
mHTTPTextureBits = 0 ;
|
||||
|
||||
mNetworkQueueMutex.unlock() ;
|
||||
}
|
||||
|
||||
S32 res = LLWorkerThread::update(max_time_ms);
|
||||
|
||||
if (!mDebugPause)
|
||||
{
|
||||
|
|
@ -1909,7 +1849,6 @@ S32 LLTextureFetch::update(U32 max_time_ms)
|
|||
lldebugs << "processed: " << processed << " messages." << llendl;
|
||||
}
|
||||
}
|
||||
clearHTTPThrottleFlag();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,9 +94,7 @@ protected:
|
|||
void addToNetworkQueue(LLTextureFetchWorker* worker);
|
||||
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
|
||||
void addToHTTPQueue(const LLUUID& id);
|
||||
void removeFromHTTPQueue(const LLUUID& id);
|
||||
bool isHTTPThrottled(S32 requested_size);
|
||||
void clearHTTPThrottleFlag();
|
||||
void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);
|
||||
void removeRequest(LLTextureFetchWorker* worker, bool cancel);
|
||||
// Called from worker thread (during doWork)
|
||||
void processCurlRequests();
|
||||
|
|
@ -136,15 +134,7 @@ private:
|
|||
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];
|
||||
U32 mHTTPTextureBits;
|
||||
};
|
||||
|
||||
#endif // LL_LLTEXTUREFETCH_H
|
||||
|
|
|
|||
|
|
@ -35,12 +35,11 @@
|
|||
#include "llviewerjointattachment.h"
|
||||
|
||||
#include "llagentconstants.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llgl.h"
|
||||
#include "llrender.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvolume.h"
|
||||
#include "pipeline.h"
|
||||
#include "llspatialpartition.h"
|
||||
|
|
@ -164,6 +163,9 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
|
|||
//-----------------------------------------------------------------------------
|
||||
BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
|
||||
{
|
||||
object->extractAttachmentItemID();
|
||||
|
||||
// Same object reattached
|
||||
if (isObjectAttached(object))
|
||||
{
|
||||
llinfos << "(same object re-attached)" << llendl;
|
||||
|
|
@ -171,8 +173,19 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
|
|||
// Pass through anyway to let setupDrawable()
|
||||
// re-connect object to the joint correctly
|
||||
}
|
||||
|
||||
// Two instances of the same inventory item attached --
|
||||
// Request detach, and kill the object in the meantime.
|
||||
if (getAttachedObject(object->getAttachmentItemID()))
|
||||
{
|
||||
llinfos << "(same object re-attached)" << llendl;
|
||||
object->markDead();
|
||||
|
||||
// If this happens to be attached to self, then detach.
|
||||
LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
object->extractAttachmentItemID();
|
||||
mAttachedObjects.push_back(object);
|
||||
setupDrawable(object);
|
||||
|
||||
|
|
@ -195,7 +208,7 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
|
|||
}
|
||||
calcLOD();
|
||||
mUpdateXform = TRUE;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ void LLViewerTexture::generateGLTexture()
|
|||
LLImageGL* LLViewerTexture::getGLTexture() const
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
|
||||
return mGLTexturep ;
|
||||
}
|
||||
|
||||
|
|
@ -1489,8 +1489,13 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
|
|||
//virtual
|
||||
void LLViewerFetchedTexture::processTextureStats()
|
||||
{
|
||||
if(mFullyLoaded)
|
||||
if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
|
||||
{
|
||||
mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ;
|
||||
}
|
||||
|
||||
if(mFullyLoaded)
|
||||
{
|
||||
if(mDesiredDiscardLevel <= mMinDesiredDiscardLevel)//already loaded
|
||||
{
|
||||
return ;
|
||||
|
|
|
|||
|
|
@ -1155,6 +1155,29 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
|
||||
{
|
||||
LLInventoryItem* item = gInventory.getItem(item_id);
|
||||
if (item)
|
||||
{
|
||||
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
|
||||
gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
|
||||
|
||||
// this object might have been selected, so let the selection manager know it's gone now
|
||||
LLViewerObject *found_obj = gObjectList.findObject(item_id);
|
||||
if (found_obj)
|
||||
{
|
||||
LLSelectMgr::getInstance()->remove(found_obj);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
|
||||
{
|
||||
LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
|
||||
|
|
|
|||
|
|
@ -298,6 +298,7 @@ public:
|
|||
const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
|
||||
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
|
||||
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
|
||||
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
|
||||
|
||||
private:
|
||||
// Track attachments that have been requested but have not arrived yet.
|
||||
|
|
|
|||
|
|
@ -478,9 +478,9 @@ LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
|
|||
// 1. CLOTHING - sorted by name
|
||||
// 2. OBJECT - sorted by type
|
||||
// 3. BODYPART - sorted by name
|
||||
mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
|
||||
mWearableOrder[LLAssetType::AT_OBJECT] = LLWearableTypeOrder(ORDER_RANK_2, true, true);
|
||||
mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
|
||||
mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANG_1, false, false);
|
||||
mWearableOrder[LLAssetType::AT_OBJECT] = LLWearableTypeOrder(ORDER_RANG_2, true, true);
|
||||
mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANG_3, false, true);
|
||||
}
|
||||
|
||||
void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type, LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
|
||||
|
|
@ -527,6 +527,8 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
|
|||
const LLWearableType::EType item_wearable_type2 = wearable_item2->getWearableType();
|
||||
|
||||
if (item_wearable_type1 != item_wearable_type2)
|
||||
// If items are of different LLWearableType::EType types they are compared
|
||||
// by LLWearableType::EType. types order determined in LLWearableType::EType.
|
||||
{
|
||||
// If items are of different LLWearableType::EType types they are compared
|
||||
// by LLWearableType::EType. types order determined in LLWearableType::EType.
|
||||
|
|
@ -549,10 +551,11 @@ LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparato
|
|||
{
|
||||
wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
|
||||
|
||||
|
||||
if(const_it == mWearableOrder.end())
|
||||
{
|
||||
llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
|
||||
return ORDER_RANK_UNKNOWN;
|
||||
return ORDER_RANG_UNKNOWN;
|
||||
}
|
||||
|
||||
return const_it->second.mOrderPriority;
|
||||
|
|
@ -562,25 +565,30 @@ bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType it
|
|||
{
|
||||
wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
|
||||
|
||||
|
||||
if(const_it == mWearableOrder.end())
|
||||
{
|
||||
llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return const_it->second.mSortAssetTypeByName;
|
||||
}
|
||||
|
||||
|
||||
bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const
|
||||
{
|
||||
wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
|
||||
|
||||
|
||||
if(const_it == mWearableOrder.end())
|
||||
{
|
||||
llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return const_it->second.mSortWearableTypeByName;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -313,10 +313,10 @@ public:
|
|||
|
||||
enum ETypeListOrder
|
||||
{
|
||||
ORDER_RANK_1 = 1,
|
||||
ORDER_RANK_2,
|
||||
ORDER_RANK_3,
|
||||
ORDER_RANK_UNKNOWN
|
||||
ORDER_RANG_1 = 1,
|
||||
ORDER_RANG_2,
|
||||
ORDER_RANG_3,
|
||||
ORDER_RANG_UNKNOWN
|
||||
};
|
||||
|
||||
void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name);
|
||||
|
|
@ -325,15 +325,15 @@ protected:
|
|||
/**
|
||||
* All information about sort order is stored in mWearableOrder map
|
||||
*
|
||||
* mWearableOrder : KYES VALUES
|
||||
* mWearableOrder : KEYES VALUES
|
||||
* [LLAssetType] [struct LLWearableTypeOrder]
|
||||
*
|
||||
*---------------------------------------------------------------------------------------------
|
||||
* I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list.
|
||||
* I. Determines order (ORDER_RANG) in which items of LLAssetType should be displayed in list.
|
||||
* For example by spec in MY OUTFITS the order is:
|
||||
* 1. AT_CLOTHING (ORDER_RANK_1)
|
||||
* 2. AT_OBJECT (ORDER_RANK_2)
|
||||
* 3. AT_BODYPART (ORDER_RANK_3)
|
||||
* 1. AT_CLOTHING (ORDER_RANG_1)
|
||||
* 2. AT_OBJECT (ORDER_RANG_2)
|
||||
* 3. AT_BODYPART (ORDER_RANG_3)
|
||||
*
|
||||
* II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType)
|
||||
* For example by spec in MY OUTFITS the order within each items type(LLAssetType) is:
|
||||
|
|
@ -346,7 +346,7 @@ protected:
|
|||
*
|
||||
* For each LLAssetType (KEYS in mWearableOrder) the information about:
|
||||
*
|
||||
* I. ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority)
|
||||
* I. ORDER_RANG (the flag is LLWearableTypeOrder::mOrderPriority)
|
||||
*
|
||||
* II. whether items of this LLAssetType type should be ordered
|
||||
* by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName)
|
||||
|
|
|
|||
Loading…
Reference in New Issue