summaryrefslogtreecommitdiff
path: root/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r--indra/newview/llvoavatar.cpp547
1 files changed, 395 insertions, 152 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 16f2064d1b..02d0b652c1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6111,6 +6111,7 @@ const LLUUID& LLVOAvatar::getStepSound() const
//-----------------------------------------------------------------------------
void LLVOAvatar::processAnimationStateChanges()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) )
{
startMotion(ANIM_AGENT_WALK_ADJUST);
@@ -7693,7 +7694,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
updateAttachmentOverrides();
}
- updateVisualComplexity();
+ // Inform complexity logic to do partial update.
+ markAttachmentComplexityDirty(viewer_object->getID());
if (viewer_object->isSelected())
{
@@ -7997,7 +7999,7 @@ bool LLVOAvatar::detachObject(LLViewerObject *viewer_object)
if (attachment->isObjectAttached(viewer_object))
{
- updateVisualComplexity();
+ markAttachmentComplexityDirty(viewer_object->getID(), true);
bool is_animated_object = viewer_object->isAnimatedObject();
cleanupAttachedMesh(viewer_object);
@@ -8424,6 +8426,7 @@ void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status)
selfStopPhase("wear_inventory_category", false);
selfStopPhase("process_initial_wearables_update", false);
+ // Start a complexity update.
updateVisualComplexity();
}
}
@@ -8715,7 +8718,7 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)
bool LLVOAvatar::isFullyLoaded() const
{
- return (mRenderUnloadedAvatar || mFullyLoaded);
+ return (mRenderUnloadedAvatar && !isSelf()) || mFullyLoaded;
}
bool LLVOAvatar::hasFirstFullAttachmentData() const
@@ -9359,6 +9362,7 @@ void LLVOAvatar::releaseComponentTextures()
{
// Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default
setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR);
+ markBodyPartsComplexityDirty();
}
}
@@ -9376,6 +9380,7 @@ void LLVOAvatar::releaseComponentTextures()
{
const U8 te = (ETextureIndex)bakedDicEntry->mLocalTextures[texture];
setTETexture(te, IMG_DEFAULT_AVATAR);
+ markBodyPartsComplexityDirty();
}
}
}
@@ -10261,6 +10266,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( bool success, LLViewerFetchedTexture
LL_INFOS() << "unexpected image id: " << id << LL_ENDL;
}
self->dirtyMesh();
+ self->markBodyPartsComplexityDirty();
}
else
{
@@ -10315,6 +10321,7 @@ void LLVOAvatar::onBakedTextureLoaded(bool success,
if (selfp && !success)
{
selfp->removeMissingBakedTextures();
+ selfp->markBodyPartsComplexityDirty();
}
if( final || !success )
@@ -10325,6 +10332,7 @@ void LLVOAvatar::onBakedTextureLoaded(bool success,
if( selfp && success && final )
{
selfp->useBakedTexture( id );
+ selfp->markBodyPartsComplexityDirty();
}
}
@@ -11275,10 +11283,384 @@ void LLVOAvatar::idleUpdateDebugInfo()
void LLVOAvatar::updateVisualComplexity()
{
LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL;
- // Set the cache time to in the past so it's updated ASAP
+ // Trigger cache recalculation on next idle update.
+ // Will recalculate stale, missing data and control avatar.
mVisualComplexityStale = true;
}
+void LLVOAvatar::calculateAttachmentComplexity(LLViewerObject* attached_object,
+ const F32 max_attachment_complexity,
+ ComplexityComponent& cache)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ cache.reset();
+
+ if (!attached_object
+ || attached_object->isDead())
+ {
+ return;
+ }
+
+ accountRenderComplexityForObject(
+ attached_object,
+ max_attachment_complexity,
+ cache.textures,
+ cache.render_cost,
+ cache.triangle_count,
+ cache.est_triangle_count,
+ cache.surface_area,
+ cache.hud_complexity,
+ cache.object_complexity
+ );
+
+ cache.last_update_time = LLFrameTimer::getTotalSeconds();
+ cache.needs_update = false;
+}
+
+void LLVOAvatar::calculateBodyPartsComplexity(ComplexityComponent& cache)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ cache.reset();
+
+ // Body parts have a fixed cost
+ // This represents the base avatar mesh (eyes, hair, shape, skin, etc.)
+ cache.render_cost = calculateBodyPartsComplexity();
+
+ // For more accurate body part complexity, could enumerate mesh LODs here
+ // For now, using a constant cost as in the original implementation
+
+ cache.last_update_time = LLFrameTimer::getTotalSeconds();
+ cache.needs_update = false;
+}
+
+bool LLVOAvatar::shouldUpdateComplexityComponent(const ComplexityComponent& component) const
+{
+ if (component.needs_update)
+ {
+ return true;
+ }
+
+ constexpr F32 CACHE_LIFETIME_SECONDS = 30.0; // Todo: should be indefinite, until something actually changes
+ F64 current_time = LLFrameTimer::getTotalSeconds();
+ return (current_time - component.last_update_time) > CACHE_LIFETIME_SECONDS;
+}
+
+bool LLVOAvatar::calculateControlAvatarComplexity(ComplexityComponent& cache, const F32 max_attachment_complexity)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ cache.reset();
+
+ if (!isControlAvatar())
+ {
+ return false;
+ }
+
+ LLControlAvatar* control_av = dynamic_cast<LLControlAvatar*>(this);
+ if (!control_av)
+ {
+ return false;
+ }
+
+ LLVOVolume* volp = control_av->mRootVolp;
+ if (!volp || volp->isAttachment())
+ {
+ return false;
+ }
+
+ accountRenderComplexityForObject(
+ volp,
+ max_attachment_complexity,
+ cache.textures,
+ cache.render_cost,
+ cache.triangle_count,
+ cache.est_triangle_count,
+ cache.surface_area,
+ cache.hud_complexity,
+ cache.object_complexity
+ );
+
+ // todo: store 'expires' time instead or make it indefinite?
+ cache.last_update_time = LLFrameTimer::getTotalSeconds();
+ cache.needs_update = false;
+
+ return true;
+}
+
+void LLVOAvatar::accumulateComplexityComponent(const ComplexityComponent& component,
+ U32& total_cost,
+ hud_complexity_list_t& hud_list,
+ object_complexity_list_t& object_list)
+{
+ total_cost += component.render_cost;
+ mAttachmentSurfaceArea += component.surface_area;
+ mAttachmentVisibleTriangleCount += component.triangle_count;
+ mAttachmentEstTriangleCount += component.est_triangle_count;
+
+ // Add HUD/object complexity info if present
+ if (component.hud_complexity.objectId.notNull())
+ {
+ hud_list.push_back(component.hud_complexity);
+ }
+ if (component.object_complexity.objectId.notNull())
+ {
+ object_list.push_back(component.object_complexity);
+ }
+}
+
+void LLVOAvatar::markAttachmentComplexityDirty(const LLUUID& object_id, bool force_reset_attachment)
+{
+ // Mark the cache entry if it exists
+ complexity_cache_map_t::iterator it = mComplexityCache.find(object_id);
+ if (it != mComplexityCache.end())
+ {
+ if (force_reset_attachment)
+ {
+ // Object was detached.
+ // Force reset it in case it lingers in gObjectList for some reason (ex: dropped to world).
+ it->second.reset();
+ }
+ it->second.needs_update = true;
+ }
+
+ // Launch update process if not already scheduled
+ // It will add any missing attachments.
+ mVisualComplexityStale = true;
+}
+
+void LLVOAvatar::markBodyPartsComplexityDirty()
+{
+ mBodyPartsComplexity.needs_update = true;
+
+ // Launch update process if not already scheduled
+ mVisualComplexityStale = true;
+}
+
+void LLVOAvatar::performPartialComplexityUpdate(const F32 max_attachment_complexity)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ // Update any attachments marked as dirty
+ // Todo: might want to limit time or count here and defer the rest
+ // till next run. In such a case will need to make sure
+ // mVisualComplexityStale remains true.
+
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (!attachment || !attachment->getValid())
+ {
+ continue;
+ }
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end(); ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isDead())
+ {
+ LLUUID object_id = attached_object->getID();
+ ComplexityComponent& cache = mComplexityCache[object_id];
+
+ // Update if cache is stale or a new entry.
+ if (shouldUpdateComplexityComponent(cache))
+ {
+ calculateAttachmentComplexity(attached_object, max_attachment_complexity, cache);
+ }
+ }
+ }
+ }
+
+ // Update body parts if stale
+ if (shouldUpdateComplexityComponent(mBodyPartsComplexity))
+ {
+ calculateBodyPartsComplexity(mBodyPartsComplexity);
+ }
+}
+
+// Calculations for mVisualComplexity value
+// Call rate is flexible, can be once in 20, can be once in 200 frames,
+// depends on priority and known cost of an avatar in question.
+void LLVOAvatar::calculateUpdateRenderComplexity()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ // ****************************************************************
+ // This calculation should not be modified by third party viewers,
+ // since it is used to limit rendering and should be uniform for
+ // everyone. If you have suggested improvements, submit them to
+ // the official viewer for consideration.
+ // ****************************************************************
+
+ if (!mVisualComplexityStale)
+ {
+ return;
+ }
+
+ // Get the attachment complexity limit
+ static LLCachedControl<F32> max_complexity_setting(gSavedSettings, "MaxAttachmentComplexity");
+ F32 max_attachment_complexity = max_complexity_setting;
+ max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
+
+ // Update complexity for any dirty attachments or body parts.
+ //
+ // Todo: Limit this by time or count and continue later as
+ // doing everything in one go can be very expensive (multiple ms)
+ // Note that calculateUpdateRenderComplexity() can be launched once
+ // per 200 frames. Limiting it by time or count runs the risk of
+ // already checked attachments getting stale on last_update_time,
+ // thus function will keep running indefinetely.
+ performPartialComplexityUpdate(max_attachment_complexity);
+
+ // Reset per-run counters
+ mAttachmentSurfaceArea = 0.f;
+ mAttachmentVisibleTriangleCount = 0;
+ mAttachmentEstTriangleCount = 0.f;
+
+ U32 total_cost = 0;
+ hud_complexity_list_t hud_complexity_list;
+ object_complexity_list_t object_complexity_list;
+
+ // Calculate and accumulate control avatar complexity if applicable
+ // For now this is on each run.
+ // Todo: See if mControlAvatarComplexity.needs_update is applicable here.
+ if (calculateControlAvatarComplexity(mControlAvatarComplexity, max_attachment_complexity))
+ {
+ accumulateComplexityComponent(
+ mControlAvatarComplexity,
+ total_cost,
+ hud_complexity_list,
+ object_complexity_list);
+ }
+
+ // Accumulate body parts complexity
+ accumulateComplexityComponent(mBodyPartsComplexity, total_cost, hud_complexity_list, object_complexity_list);
+
+ // Accumulate all attachment complexity from cache
+ // Clean up cache entries for attachments that no longer exist
+ std::vector<LLUUID> to_remove;
+
+ for (complexity_cache_map_t::iterator cache_iter = mComplexityCache.begin();
+ cache_iter != mComplexityCache.end(); ++cache_iter)
+ {
+ const LLUUID& object_id = cache_iter->first;
+
+ // Verify object still exists
+ LLViewerObject* obj = gObjectList.findObject(object_id);
+ if (!obj
+ || obj->isDead()
+ || !obj->isAttachment())
+ {
+ to_remove.push_back(object_id);
+ continue;
+ }
+
+ // Accumulate this attachment's complexity
+ accumulateComplexityComponent(cache_iter->second, total_cost,
+ hud_complexity_list, object_complexity_list);
+ }
+
+ // Remove stale cache entries
+ for (std::vector<LLUUID>::iterator it = to_remove.begin(); it != to_remove.end(); ++it)
+ {
+ mComplexityCache.erase(*it);
+ }
+
+ if (total_cost != mVisualComplexity)
+ {
+ LL_DEBUGS("AvatarRender") << "Avatar " << getID()
+ << " complexity updated was " << mVisualComplexity << " now " << total_cost
+ << " reported " << mReportedVisualComplexity
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("AvatarRender") << "Avatar " << getID()
+ << " complexity updated no change " << mVisualComplexity
+ << " reported " << mReportedVisualComplexity
+ << LL_ENDL;
+ }
+
+ // Store results
+ mVisualComplexity = total_cost;
+
+ // Call the existing reporting function with the aggregated lists
+ processComplexityCostChange(hud_complexity_list, object_complexity_list);
+
+ // Stop processing until something changes
+ mVisualComplexityStale = false;
+}
+
+U32 LLVOAvatar::calculateBodyPartsComplexity()
+{
+ constexpr U32 COMPLEXITY_BODY_PART_COST = 200;
+ U32 cost = 0;
+ for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry* baked_dict
+ = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
+ ETextureIndex tex_index = baked_dict->mTextureIndex;
+ if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
+ {
+ // Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars
+ if (isIndexLocalTexture(tex_index))
+ {
+ if (isTextureDefined(tex_index, 0))
+ {
+ cost += COMPLEXITY_BODY_PART_COST;
+ }
+ }
+ else
+ {
+ // baked textures can use TE images directly
+ if (isTextureDefined(tex_index)
+ && (getTEImage(tex_index)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha))
+ {
+ cost += COMPLEXITY_BODY_PART_COST;
+ }
+ }
+ }
+ }
+ LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
+ return cost;
+}
+
+void LLVOAvatar::processComplexityCostChange(const hud_complexity_list_t &hud_complexity_list, const object_complexity_list_t &object_complexity_list)
+{
+ static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
+
+ if (isSelf() && show_my_complexity_changes)
+ {
+ // Avatar complexity
+ LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
+ LLAvatarRenderNotifier::getInstance()->setObjectComplexityList(object_complexity_list);
+ // HUD complexity
+ LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
+ }
+
+ //schedule an update to ART next frame if needed
+ if (LLPerfStats::tunables.userAutoTuneEnabled &&
+ LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY &&
+ !isVisuallyMuted())
+ {
+ const LLUUID id = getID(); // <== use id to make sure this avatar didn't get deleted between frames
+ LL::WorkQueue::getInstance("mainloop")->post([id]()
+ {
+ LLViewerObject* obj = gObjectList.findObject(id);
+ if (obj
+ && !obj->isDead()
+ && obj->isAvatar()
+ && obj->mDrawable)
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*)obj;
+ gPipeline.profileAvatar(avatar);
+ }
+ });
+ }
+}
// Account for the complexity of a single top-level object associated
// with an avatar. This will be either an attached object or an animated
@@ -11288,15 +11670,18 @@ void LLVOAvatar::accountRenderComplexityForObject(
const F32 max_attachment_complexity,
LLVOVolume::texture_cost_t& textures,
U32& cost,
- hud_complexity_list_t& hud_complexity_list,
- object_complexity_list_t& object_complexity_list)
+ U32& visible_triangle_count,
+ F32& est_triangle_count,
+ F32& surface_area,
+ LLHUDComplexity& hud_object_complexity,
+ LLObjectComplexity& object_complexity)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (attached_object && !attached_object->isHUDAttachment())
{
- mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount();
- mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax();
- mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
+ visible_triangle_count += attached_object->recursiveGetTriangleCount();
+ est_triangle_count += attached_object->recursiveGetEstTrianglesMax();
+ surface_area += attached_object->recursiveGetScaledSurfaceArea();
textures.clear();
const LLDrawable* drawable = attached_object->mDrawable;
@@ -11351,11 +11736,9 @@ void LLVOAvatar::accountRenderComplexityForObject(
if (isSelf())
{
- LLObjectComplexity object_complexity;
object_complexity.objectName = attached_object->getAttachmentItemName();
object_complexity.objectId = attached_object->getAttachmentItemID();
object_complexity.objectCost = (U32)attachment_total_cost;
- object_complexity_list.push_back(object_complexity);
}
}
}
@@ -11367,13 +11750,12 @@ void LLVOAvatar::accountRenderComplexityForObject(
&& attached_object->mDrawable)
{
textures.clear();
- mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
+ surface_area += attached_object->recursiveGetScaledSurfaceArea();
const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
if (volume)
{
bool is_rigged_mesh = volume->isRiggedMeshFast();
- LLHUDComplexity hud_object_complexity;
hud_object_complexity.objectName = attached_object->getAttachmentItemName();
hud_object_complexity.objectId = attached_object->getAttachmentItemID();
std::string joint_name;
@@ -11428,145 +11810,6 @@ void LLVOAvatar::accountRenderComplexityForObject(
}
}
}
- hud_complexity_list.push_back(hud_object_complexity);
- }
- }
-}
-
-// Calculations for mVisualComplexity value
-void LLVOAvatar::calculateUpdateRenderComplexity()
-{
- /*****************************************************************
- * This calculation should not be modified by third party viewers,
- * since it is used to limit rendering and should be uniform for
- * everyone. If you have suggested improvements, submit them to
- * the official viewer for consideration.
- *****************************************************************/
- if (mVisualComplexityStale)
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
-
- static const U32 COMPLEXITY_BODY_PART_COST = 200;
- static LLCachedControl<F32> max_complexity_setting(gSavedSettings, "MaxAttachmentComplexity");
- F32 max_attachment_complexity = max_complexity_setting;
- max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
-
- // Diagnostic list of all textures on our avatar
- static std::unordered_set<const LLViewerTexture*> all_textures;
-
- U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
- LLVOVolume::texture_cost_t textures;
- hud_complexity_list_t hud_complexity_list;
- object_complexity_list_t object_complexity_list;
-
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict
- = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
- ETextureIndex tex_index = baked_dict->mTextureIndex;
- if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
- {
- // Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars
- if (isIndexLocalTexture(tex_index))
- {
- if (isTextureDefined(tex_index, 0))
- {
- cost += COMPLEXITY_BODY_PART_COST;
- }
- }
- else
- {
- // baked textures can use TE images directly
- if (isTextureDefined(tex_index)
- && (getTEImage(tex_index)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha))
- {
- cost += COMPLEXITY_BODY_PART_COST;
- }
- }
- }
- }
- LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
-
- mAttachmentVisibleTriangleCount = 0;
- mAttachmentEstTriangleCount = 0.f;
- mAttachmentSurfaceArea = 0.f;
-
- // A standalone animated object needs to be accounted for
- // using its associated volume. Attached animated objects
- // will be covered by the subsequent loop over attachments.
- LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this);
- if (control_av)
- {
- LLVOVolume *volp = control_av->mRootVolp;
- if (volp && !volp->isAttachment())
- {
- accountRenderComplexityForObject(volp, max_attachment_complexity,
- textures, cost, hud_complexity_list, object_complexity_list);
- }
- }
-
- // Account for complexity of all attachments.
- for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin();
- attachment_point != mAttachmentPoints.end();
- ++attachment_point)
- {
- LLViewerJointAttachment* attachment = attachment_point->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject* attached_object = attachment_iter->get();
- accountRenderComplexityForObject(attached_object, max_attachment_complexity,
- textures, cost, hud_complexity_list, object_complexity_list);
- }
- }
-
- if ( cost != mVisualComplexity )
- {
- LL_DEBUGS("AvatarRender") << "Avatar "<< getID()
- << " complexity updated was " << mVisualComplexity << " now " << cost
- << " reported " << mReportedVisualComplexity
- << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("AvatarRender") << "Avatar "<< getID()
- << " complexity updated no change " << mVisualComplexity
- << " reported " << mReportedVisualComplexity
- << LL_ENDL;
- }
- mVisualComplexity = cost;
- mVisualComplexityStale = false;
-
- static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
-
- if (isSelf() && show_my_complexity_changes)
- {
- // Avatar complexity
- LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
- LLAvatarRenderNotifier::getInstance()->setObjectComplexityList(object_complexity_list);
- // HUD complexity
- LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
- }
-
- //schedule an update to ART next frame if needed
- if (LLPerfStats::tunables.userAutoTuneEnabled &&
- LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY &&
- !isVisuallyMuted())
- {
- const LLUUID id = getID(); // <== use id to make sure this avatar didn't get deleted between frames
- LL::WorkQueue::getInstance("mainloop")->post([id]()
- {
- LLViewerObject* obj = gObjectList.findObject(id);
- if (obj
- && !obj->isDead()
- && obj->isAvatar()
- && obj->mDrawable)
- {
- LLVOAvatar* avatar = (LLVOAvatar*)obj;
- gPipeline.profileAvatar(avatar);
- }
- });
}
}
}