diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2015-03-18 21:41:47 -0400 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2015-03-18 21:41:47 -0400 |
commit | 090d3097d569922b7c3b681cb77ff14a29a60b07 (patch) | |
tree | 0b01041e2ad9e6c42a9930803901a3f0e087e617 | |
parent | 8169cde890f70320340a08cbfa29d16033572a9b (diff) |
MAINT-4917 WIP - Attachment deferred bulk COF linking WIP
-rwxr-xr-x | indra/newview/llagentwearables.cpp | 56 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.cpp | 21 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.h | 6 | ||||
-rwxr-xr-x | indra/newview/llattachmentsmgr.cpp | 133 | ||||
-rwxr-xr-x | indra/newview/llattachmentsmgr.h | 25 | ||||
-rwxr-xr-x | indra/newview/llinventorybridge.cpp | 12 | ||||
-rwxr-xr-x | indra/newview/llvoavatarself.cpp | 41 | ||||
-rwxr-xr-x | indra/newview/llvoavatarself.h | 7 |
8 files changed, 141 insertions, 160 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 69eb478cd8..4a395f547a 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llagentwearables.h" +#include "llattachmentsmgr.h" #include "llaccordionctrltab.h" #include "llagent.h" #include "llagentcamera.h" @@ -1373,55 +1374,16 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra S32 obj_count = obj_item_array.size(); if (obj_count > 0) { - LL_DEBUGS("Avatar") << "ATT [RezMultipleAttachmentsFromInv] attaching multiple, total obj_count " << obj_count << LL_ENDL; + LL_DEBUGS("Avatar") << "ATT attaching multiple, total obj_count " << obj_count << LL_ENDL; } - // Limit number of packets to send - const S32 MAX_PACKETS_TO_SEND = 10; - const S32 OBJECTS_PER_PACKET = 4; - const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET; - if( obj_count > MAX_OBJECTS_TO_SEND ) - { - obj_count = MAX_OBJECTS_TO_SEND; - } - - // Create an id to keep the parts of the compound message together - LLUUID compound_msg_id; - compound_msg_id.generate(); - LLMessageSystem* msg = gMessageSystem; - - for(S32 i = 0; i < obj_count; ++i) - { - if( 0 == (i % OBJECTS_PER_PACKET) ) - { - // Start a new message chunk - msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_HeaderData); - msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); - msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); - msg->addBOOLFast(_PREHASH_FirstDetachAll, false ); - } - - const LLInventoryItem* item = obj_item_array.at(i).get(); - LL_DEBUGS("Avatar") << "ATT requesting " << item->getName() - << " " << item->getLinkedUUID() << LL_ENDL; - msg->nextBlockFast(_PREHASH_ObjectData ); - msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); - msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); - msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD); // Wear at the previous or default attachment point - pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); - msg->addStringFast(_PREHASH_Name, item->getName()); - msg->addStringFast(_PREHASH_Description, item->getDescription()); - - if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) ) - { - // End of message chunk - msg->sendReliable( gAgent.getRegion()->getHost() ); - } - } + for(LLInventoryModel::item_array_t::const_iterator it = obj_item_array.begin(); + it != obj_item_array.end(); + ++it) + { + const LLInventoryItem* item = *it; + LLAttachmentsMgr::instance().addAttachmentRequest(item->getLinkedUUID(), 0, TRUE); + } } // Returns false if the given wearable is already topmost/bottommost diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 24169c152b..258d69d546 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -525,7 +525,7 @@ LLUpdateAppearanceAndEditWearableOnDestroy::LLUpdateAppearanceAndEditWearableOnD { } -LLRequestAppearanceUpdateOnDestroy::~LLRequestAppearanceUpdateOnDestroy() +LLRequestServerAppearanceUpdateOnDestroy::~LLRequestServerAppearanceUpdateOnDestroy() { LL_DEBUGS("Avatar") << "ATT requesting server appearance update" << LL_ENDL; LLAppearanceMgr::instance().requestServerAppearanceUpdate(); @@ -3925,24 +3925,7 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - if (mAttachmentInvLinkEnabled) - { - // we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF. - // it will trigger gAgentWariables.notifyLoadingFinished() - // But it is not acceptable solution. See EXT-7777 - if (!isLinkedInCOF(item_id)) - { - LL_DEBUGS("Avatar") << "ATT adding COF link for attachment " - << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; - // FIXME replace with just a call to request bake update? - LLPointer<LLInventoryCallback> cb = new LLRequestAppearanceUpdateOnDestroy(); - LLAppearanceMgr::addCOFItemLink(item_id, cb); // Add COF link for item. - } - } - else - { - //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL; - } + LLAttachmentsMgr::instance().onAttachmentArrived(item_id); } void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index e6094d4b53..dfe392e3b7 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -306,11 +306,11 @@ private: LLUUID mItemID; }; -class LLRequestAppearanceUpdateOnDestroy: public LLInventoryCallback +class LLRequestServerAppearanceUpdateOnDestroy: public LLInventoryCallback { public: - LLRequestAppearanceUpdateOnDestroy() {} - ~LLRequestAppearanceUpdateOnDestroy(); + LLRequestServerAppearanceUpdateOnDestroy() {} + ~LLRequestServerAppearanceUpdateOnDestroy(); /* virtual */ void fire(const LLUUID& item_id) {} }; diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index 64dcaab6c0..cc83500491 100755 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -44,9 +44,9 @@ LLAttachmentsMgr::~LLAttachmentsMgr() { } -void LLAttachmentsMgr::addAttachment(const LLUUID& item_id, - const U8 attachment_pt, - const BOOL add) +void LLAttachmentsMgr::addAttachmentRequest(const LLUUID& item_id, + const U8 attachment_pt, + const BOOL add) { LLViewerInventoryItem *item = gInventory.getItem(item_id); LL_DEBUGS("Avatar") << "ATT adding attachment to mPendingAttachments " @@ -57,6 +57,8 @@ void LLAttachmentsMgr::addAttachment(const LLUUID& item_id, attachment.mAttachmentPt = attachment_pt; attachment.mAdd = add; mPendingAttachments.push_back(attachment); + + addAttachmentRequestTime(item_id); } // static @@ -73,7 +75,9 @@ void LLAttachmentsMgr::onIdle() return; } - linkPendingAttachments(); + requestPendingAttachments(); + + linkRecentlyArrivedAttachments(); } class LLAttachAfterLinkCallback: public LLInventoryCallback @@ -111,39 +115,58 @@ private: LLAttachmentsMgr::attachments_vec_t mToLinkAndAttach; }; -//#define COF_LINK_FIRST - -void LLAttachmentsMgr::linkPendingAttachments() +void LLAttachmentsMgr::requestPendingAttachments() { if (mPendingAttachments.size()) { -#ifdef COF_LINK_FIRST - LLPointer<LLInventoryCallback> cb = new LLAttachAfterLinkCallback(mPendingAttachments); - LLInventoryObject::const_object_list_t inv_items_to_link; - LL_DEBUGS("Avatar") << "ATT requesting COF links for " << mPendingAttachments.size() << " object(s):" << LL_ENDL; - for (attachments_vec_t::const_iterator it = mPendingAttachments.begin(); - it != mPendingAttachments.end(); ++it) - { - const AttachmentsInfo& att_info = *it; - LLViewerInventoryItem *item = gInventory.getItem(att_info.mItemID); - if (item) - { - LL_DEBUGS("Avatar") << "ATT - requesting COF link for " << item->getName() << LL_ENDL; - inv_items_to_link.push_back(item); - } - else - { - LL_WARNS() << "ATT unable to link requested attachment " << att_info.mItemID - << ", item not found in inventory" << LL_ENDL; - } - } - link_inventory_array(LLAppearanceMgr::instance().getCOF(), inv_items_to_link, cb); -#else requestAttachments(mPendingAttachments); -#endif mPendingAttachments.clear(); } +} + +void LLAttachmentsMgr::linkRecentlyArrivedAttachments() +{ + const F32 COF_LINK_BATCH_TIME = 5.0F; + + // One or more attachments have arrived but not been processed for COF links + if (mRecentlyArrivedAttachments.size()) + { + if (mAttachmentRequests.empty()) + { + // Not waiting for more + LL_DEBUGS("Avatar") << "ATT all pending attachments have arrived" << LL_ENDL; + } + else if (mCOFLinkBatchTimer.getElapsedTimeF32() > COF_LINK_BATCH_TIME) + { + LL_DEBUGS("Avatar") << mAttachmentRequests.size() + << "ATT pending attachments have not arrived but wait time exceeded" << LL_ENDL; + } + else + { + return; + } + LL_DEBUGS("Avatar") << "ATT requesting COF links for " << mRecentlyArrivedAttachments.size() << LL_ENDL; + LLInventoryObject::const_object_list_t inv_items_to_link; + for (std::set<LLUUID>::iterator it = mRecentlyArrivedAttachments.begin(); + it != mRecentlyArrivedAttachments.end(); ++it) + { + if (!LLAppearanceMgr::instance().isLinkedInCOF(*it)) + { + LLUUID item_id = *it; + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT adding COF link for attachment " + << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; + inv_items_to_link.push_back(item); + } + } + if (inv_items_to_link.size()) + { + LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy(); + link_inventory_array(LLAppearanceMgr::instance().getCOF(), inv_items_to_link, cb); + } + mRecentlyArrivedAttachments.clear(); + } } // FIXME this is basically the same code as LLAgentWearables::userAttachMultipleAttachments(), @@ -225,3 +248,53 @@ void LLAttachmentsMgr::requestAttachments(const attachments_vec_t& attachment_re i++; } } + +void LLAttachmentsMgr::addAttachmentRequestTime(const LLUUID& inv_item_id) +{ + LLInventoryItem *item = gInventory.getItem(inv_item_id); + LL_DEBUGS("Avatar") << "ATT add request time " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL; + LLTimer current_time; + mAttachmentRequests[inv_item_id] = current_time; +} + +void LLAttachmentsMgr::removeAttachmentRequestTime(const LLUUID& inv_item_id) +{ + LLInventoryItem *item = gInventory.getItem(inv_item_id); + LL_DEBUGS("Avatar") << "ATT remove request time " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL; + mAttachmentRequests.erase(inv_item_id); +} + +BOOL LLAttachmentsMgr::attachmentWasRequestedRecently(const LLUUID& inv_item_id, F32 seconds) const +{ + std::map<LLUUID,LLTimer>::const_iterator it = mAttachmentRequests.find(inv_item_id); + if (it != mAttachmentRequests.end()) + { + const LLTimer& request_time = it->second; + F32 request_time_elapsed = request_time.getElapsedTimeF32(); + if (request_time_elapsed > seconds) + { + LLInventoryItem *item = gInventory.getItem(inv_item_id); + LL_DEBUGS("Avatar") << "ATT time ignored, exceeded " << seconds + << " " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL; + return FALSE; + } + else + { + return TRUE; + } + } + else + { + return FALSE; + } +} + +void LLAttachmentsMgr::onAttachmentArrived(const LLUUID& inv_item_id) +{ + removeAttachmentRequestTime(inv_item_id); + if (mRecentlyArrivedAttachments.empty()) + { + mCOFLinkBatchTimer.reset(); + } + mRecentlyArrivedAttachments.insert(inv_item_id); +} diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h index c145fa032b..c84229475a 100755 --- a/indra/newview/llattachmentsmgr.h +++ b/indra/newview/llattachmentsmgr.h @@ -60,18 +60,31 @@ public: LLAttachmentsMgr(); virtual ~LLAttachmentsMgr(); - void addAttachment(const LLUUID& item_id, - const U8 attachment_pt, - const BOOL add); + void addAttachmentRequest(const LLUUID& item_id, + const U8 attachment_pt, + const BOOL add); void requestAttachments(const attachments_vec_t& attachment_requests); static void onIdle(void *); -protected: - void onIdle(); - void linkPendingAttachments(); + BOOL attachmentWasRequestedRecently(const LLUUID& inv_item_id, F32 seconds) const; + void addAttachmentRequestTime(const LLUUID& inv_item_id); + void onAttachmentArrived(const LLUUID& inv_item_id); private: + void removeAttachmentRequestTime(const LLUUID& inv_item_id); + void onIdle(); + void requestPendingAttachments(); + void linkRecentlyArrivedAttachments(); + + // Attachments that we are planning to rez but haven't requested from the server yet. attachments_vec_t mPendingAttachments; + + // Attachments that have been requested from server but have not arrived yet. + std::map<LLUUID,LLTimer> mAttachmentRequests; + + // Attachments that have arrived but have not been linked in the COF yet. + std::set<LLUUID> mRecentlyArrivedAttachments; + LLTimer mCOFLinkBatchTimer; }; #endif diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 32d1da434e..e44de6f91e 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -5367,17 +5367,15 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach const LLUUID& item_id = item->getLinkedUUID(); // Check for duplicate request. + const F32 MAX_TIME_SINCE_REQUEST = 5.0F; if (isAgentAvatarValid() && - (gAgentAvatarp->attachmentWasRequested(item_id) || + (LLAttachmentsMgr::instance().attachmentWasRequestedRecently(item_id, MAX_TIME_SINCE_REQUEST) || gAgentAvatarp->isWearingAttachment(item_id))) { LL_WARNS() << "ATT duplicate attachment request, ignoring" << LL_ENDL; return; } - LL_DEBUGS("Avatar") << "ATT add rez request for " << item->getName() << " id " << item_id << LL_ENDL; - gAgentAvatarp->addAttachmentRequest(item_id); - S32 attach_pt = 0; if (isAgentAvatarValid() && attachment) { @@ -5432,10 +5430,8 @@ bool confirm_attachment_rez(const LLSD& notification, const LLSD& response) U8 attachment_pt = notification["payload"]["attachment_point"].asInteger(); BOOL is_add = notification["payload"]["is_add"].asBoolean(); - LL_DEBUGS("Avatar") << "ATT calling addAttachment " << (itemp ? itemp->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; - LLAttachmentsMgr::instance().addAttachment(item_id, - attachment_pt, - is_add); + LL_DEBUGS("Avatar") << "ATT calling addAttachmentRequest " << (itemp ? itemp->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; + LLAttachmentsMgr::instance().addAttachmentRequest(item_id, attachment_pt, is_add); } } return false; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 3f3cd25f95..0859355b18 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -38,6 +38,7 @@ #include "pipeline.h" #include "llagent.h" // Get state values from here +#include "llattachmentsmgr.h" #include "llagentcamera.h" #include "llagentwearables.h" #include "llhudeffecttrail.h" @@ -1051,44 +1052,6 @@ BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const } //----------------------------------------------------------------------------- -BOOL LLVOAvatarSelf::attachmentWasRequested(const LLUUID& inv_item_id) const -{ - const F32 REQUEST_EXPIRATION_SECONDS = 5.0; // any request older than this is ignored/removed. - std::map<LLUUID,LLTimer>::iterator it = mAttachmentRequests.find(inv_item_id); - if (it != mAttachmentRequests.end()) - { - const LLTimer& request_time = it->second; - F32 request_time_elapsed = request_time.getElapsedTimeF32(); - if (request_time_elapsed > REQUEST_EXPIRATION_SECONDS) - { - mAttachmentRequests.erase(it); - return FALSE; - } - else - { - return TRUE; - } - } - else - { - return FALSE; - } -} - -//----------------------------------------------------------------------------- -void LLVOAvatarSelf::addAttachmentRequest(const LLUUID& inv_item_id) -{ - LLTimer current_time; - mAttachmentRequests[inv_item_id] = current_time; -} - -//----------------------------------------------------------------------------- -void LLVOAvatarSelf::removeAttachmentRequest(const LLUUID& inv_item_id) -{ - mAttachmentRequests.erase(inv_item_id); -} - -//----------------------------------------------------------------------------- // getWornAttachment() //----------------------------------------------------------------------------- LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id) @@ -1154,8 +1117,6 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view { const LLUUID& attachment_id = viewer_object->getAttachmentItemID(); LLAppearanceMgr::instance().registerAttachment(attachment_id); - // Clear any pending requests once the attachment arrives. - removeAttachmentRequest(attachment_id); updateLODRiggedAttachments(); } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 5f36872575..c6a038f558 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -289,19 +289,12 @@ protected: public: void updateAttachmentVisibility(U32 camera_mode); BOOL isWearingAttachment(const LLUUID& inv_item_id) const; - BOOL attachmentWasRequested(const LLUUID& inv_item_id) const; - void addAttachmentRequest(const LLUUID& inv_item_id); - void removeAttachmentRequest(const LLUUID& inv_item_id); LLViewerObject* getWornAttachment(const LLUUID& inv_item_id); bool getAttachedPointName(const LLUUID& inv_item_id, std::string& name) 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. - mutable std::map<LLUUID,LLTimer> mAttachmentRequests; - //-------------------------------------------------------------------- // HUDs //-------------------------------------------------------------------- |