summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2015-03-18 21:41:47 -0400
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2015-03-18 21:41:47 -0400
commit090d3097d569922b7c3b681cb77ff14a29a60b07 (patch)
tree0b01041e2ad9e6c42a9930803901a3f0e087e617
parent8169cde890f70320340a08cbfa29d16033572a9b (diff)
MAINT-4917 WIP - Attachment deferred bulk COF linking WIP
-rwxr-xr-xindra/newview/llagentwearables.cpp56
-rwxr-xr-xindra/newview/llappearancemgr.cpp21
-rwxr-xr-xindra/newview/llappearancemgr.h6
-rwxr-xr-xindra/newview/llattachmentsmgr.cpp133
-rwxr-xr-xindra/newview/llattachmentsmgr.h25
-rwxr-xr-xindra/newview/llinventorybridge.cpp12
-rwxr-xr-xindra/newview/llvoavatarself.cpp41
-rwxr-xr-xindra/newview/llvoavatarself.h7
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
//--------------------------------------------------------------------