Auto-scaling amortisation of dynamic BB calcs (#2226)

* Auto-scaling amortisation of dynamic BB calcs

This fix limits the overhead of the dynamic BB calcs to
AvatarExtentRefreshMaxPerBatch per AvatarExtentRefreshPeriodBatch frames
default is 5 avatar per 4 frames. Thus a standard busy region 25 avatars would
 take 20 frames to refresh the BBs.

* Add comments to give context to the amortised BB recalcs

explain the frequency of updates given the number of avatars present as to how that limits the impact on frame rate in busy scenes
meow-7.2.2
Beq Janus 2024-08-08 17:10:03 +01:00 committed by GitHub
parent 77d50cad49
commit fe0f1be17b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 6 deletions

View File

@ -1874,6 +1874,28 @@
<key>Value</key>
<real>64.0</real>
</map>
<key>AvatarExtentRefreshPeriodBatch</key>
<map>
<key>Comment</key>
<string>how many frames do we spread over by default when refreshing extents (default is 4)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>AvatarExtentRefreshMaxPerBatch</key>
<map>
<key>Comment</key>
<string>how many avatars do we want to handle in total per batch (default is 5)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>5</integer>
</map>
<key>DebugAvatarAppearanceMessage</key>
<map>
<key>Comment</key>

View File

@ -889,6 +889,7 @@ void LLViewerObjectList::update(LLAgent &agent)
static std::vector<LLViewerObject*> idle_list;
U32 idle_count = 0;
mNumAvatars = 0;
{
for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
@ -906,6 +907,10 @@ void LLViewerObjectList::update(LLAgent &agent)
idle_list[idle_count] = objectp;
}
++idle_count;
if (objectp->isAvatar())
{
mNumAvatars++;
}
}
else
{ // There shouldn't be any NULL pointers in the list, but they have caused

View File

@ -145,6 +145,7 @@ public:
S32 getOrphanParentCount() const { return (S32) mOrphanParents.size(); }
S32 getOrphanCount() const { return mNumOrphans; }
S32 getAvatarCount() const { return mNumAvatars; }
void orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port);
void findOrphans(LLViewerObject* objectp, U32 ip, U32 port);
@ -191,6 +192,7 @@ protected:
std::vector<U64> mOrphanParents; // LocalID/ip,port of orphaned objects
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
S32 mNumOrphans;
S32 mNumAvatars;
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;

View File

@ -2631,6 +2631,29 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
}
// Update should be happening max once per frame.
static LLCachedControl<S32> refreshPeriod(gSavedSettings, "AvatarExtentRefreshPeriodBatch");
static LLCachedControl<S32> refreshMaxPerPeriod(gSavedSettings, "AvatarExtentRefreshMaxPerBatch");
static S32 upd_freq = refreshPeriod; // initialise to a reasonable default of 1 batch
static S32 lastRecalibrationFrame{ 0 };
const S32 thisFrame = LLDrawable::getCurrentFrame();
if (thisFrame - lastRecalibrationFrame >= upd_freq)
{
// Only update at the start of a cycle. .
// update frequency = ((Num_Avatars -1 / NumberPerPeriod) + 1 ) * Periodicity
// Given NumberPerPeriod = 5 and Periodicity = 4
// | NumAvatars | frequency |
// +-------------+-----------+
// | 1 | 4 |
// | 2 | 4 |
// | 5 | 4 |
// | 10 | 8 |
// | 25 | 20 |
upd_freq = (((gObjectList.getAvatarCount() - 1) / refreshMaxPerPeriod) + 1)*refreshPeriod;
lastRecalibrationFrame = thisFrame;
}
if ((mLastAnimExtents[0]==LLVector3())||
(mLastAnimExtents[1])==LLVector3())
{
@ -2638,8 +2661,9 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
}
else
{
const S32 upd_freq = 4; // force update every upd_freq frames.
mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0);
// Update extent if necessary.
// if the frame counnter + the first byte of the UUID % upd_freq = 0 then update the extent.
mNeedsExtentUpdate = ((thisFrame + mID.mData[0]) % upd_freq == 0);
}
LLScopedContextString str("avatar_idle_update " + getFullname());
@ -10725,10 +10749,11 @@ void LLVOAvatar::updateRiggingInfo()
}
//LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL;
LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL;
S32 joint_count, box_count;
showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count);
LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL;
// Remove debug only stuff on hot path
// LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL;
// S32 joint_count, box_count;
// showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count);
// LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL;
}
// virtual