diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 431a1337ae..d2c9e8ffcc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -22010,7 +22010,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type U32 Value - 30 + 15 AutoTuneFPS @@ -22147,7 +22147,7 @@ Change of this parameter will affect the layout of buttons in notification toast TuningFPSStrategy Comment - Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings. + Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings, 2=Tune only global scene. Persist 1 Type diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp index 866f5c7638..d3b549258b 100644 --- a/indra/newview/llfloateravatarrendersettings.cpp +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -91,8 +91,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild() LLFloater::postBuild(); mAvatarSettingsList = getChild("render_settings_list"); mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); - mAvatarSettingsList->setAlternateSort(); - getChild("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2)); return TRUE; } @@ -136,37 +134,13 @@ void LLFloaterAvatarRenderSettings::updateList() { item_params.value = iter->first; LLAvatarNameCache::get(iter->first, &av_name); - if(!isHiddenRow(av_name.getCompleteName())) - { - item_params.columns.add().value(av_name.getCompleteName()).column("name"); - std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render"); - item_params.columns.add().value(setting).column("setting"); - S32 mute_date = LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first); - item_params.columns.add().value(createTimestamp(mute_date)).column("timestamp").alt_value(std::to_string(mute_date)); - mAvatarSettingsList->addNameItemRow(item_params); - } + item_params.columns.add().value(av_name.getCompleteName()).column("name"); + std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render"); + item_params.columns.add().value(setting).column("setting"); + mAvatarSettingsList->addNameItemRow(item_params); } } -void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string) -{ - std::string filter_upper = search_string; - LLStringUtil::toUpper(filter_upper); - if (mNameFilter != filter_upper) - { - mNameFilter = filter_upper; - mNeedsUpdate = true; - } -} - -bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name) -{ - if (mNameFilter.empty()) return false; - std::string upper_name = av_name; - LLStringUtil::toUpper(upper_name); - return std::string::npos == upper_name.find(mNameFilter); -} - static LLVOAvatar* find_avatar(const LLUUID& id) { LLViewerObject *obj = gObjectList.findObject(id); @@ -217,6 +191,10 @@ bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const { return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY)); } + else if ("non_default" == command_name) + { + return (visual_setting != S32(LLVOAvatar::AV_RENDER_NORMALLY)); + } else if ("never" == command_name) { return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER)); diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp index fa27266d3b..2aedaf7022 100644 --- a/indra/newview/llperfstats.cpp +++ b/indra/newview/llperfstats.cpp @@ -451,7 +451,7 @@ namespace LLPerfStats // we cannnot do this by avatar adjustment alone. if((gFrameCount - LLPerfStats::lastGlobalPrefChange) > settingsChangeFrequency) // give changes a short time to take effect. { - if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS) + if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY) { // 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit. // the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later @@ -489,7 +489,7 @@ namespace LLPerfStats target_avatar_time_raw = target_frame_time_raw - non_avatar_time_raw; } - if( target_avatar_time_raw < tot_avatar_time_raw ) + if ((target_avatar_time_raw < tot_avatar_time_raw) && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY)) { // we need to spend less time drawing avatars to meet our budget auto new_render_limit_ns {LLPerfStats::raw_to_ns(av_render_max_raw)}; @@ -532,7 +532,7 @@ namespace LLPerfStats // turn off if we are not locked. tunables.updateUserAutoTuneEnabled(false); } - if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 ) + if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY) ) { // if we have more time to spare let's shift up little in the hope we'll restore an avatar. U64 up_step = LLPerfStats::tunedAvatars > 2 ? LLPerfStats::ART_MIN_ADJUST_UP_NANOS : LLPerfStats::ART_MIN_ADJUST_UP_NANOS * 2; @@ -540,7 +540,7 @@ namespace LLPerfStats tunables.updateSettingsFromRenderCostLimit(); return; } - if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS) + if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY) { if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance ) { diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h index e66a51af45..706cc94516 100644 --- a/indra/newview/llperfstats.h +++ b/indra/newview/llperfstats.h @@ -76,7 +76,7 @@ namespace LLPerfStats static constexpr U32 TUNE_AVATARS_ONLY{0}; static constexpr U32 TUNE_SCENE_AND_AVATARS{1}; - extern F64 cpu_hertz; // reinstate thread safety + static constexpr U32 TUNE_SCENE_ONLY{2}; extern F64 cpu_hertz; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b546a95f55..e76b1d073f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -227,6 +227,8 @@ const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024; const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60.f; +const S32 MIN_NONTUNED_AVS = 5; + enum ERenderName { RENDER_NAME_NEVER, @@ -637,6 +639,8 @@ F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; F32 LLVOAvatar::sGreyUpdateTime = 0.f; LLPointer LLVOAvatar::sCloudTexture = NULL; +std::vector LLVOAvatar::sAVsIgnoringARTLimit; +S32 LLVOAvatar::sAvatarsNearby = 0; //----------------------------------------------------------------------------- // Helper functions @@ -896,6 +900,7 @@ LLVOAvatar::~LLVOAvatar() LLPerfStats::tunedAvatars--; mTuned = false; } + sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), sAVsIgnoringARTLimit.end()); // only call logPendingPhases if we're still alive. Otherwise this can lead to shutdown crashes // logPendingPhases(); @@ -9318,8 +9323,23 @@ void LLVOAvatar::updateTooSlow() render_time_no_shadows_raw = mRenderTimeNoShadows; // variable name updated to refelect different meaning. } - if( (LLPerfStats::renderAvatarMaxART_ns > 0) && - (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns) ) + bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); + + bool ignore_tune = false; + if (autotune && sAVsIgnoringARTLimit.size() > 0) + { + auto it = std::find(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID); + if (it != sAVsIgnoringARTLimit.end()) + { + S32 index = it - sAVsIgnoringARTLimit.begin(); + ignore_tune = (index < (MIN_NONTUNED_AVS - sAvatarsNearby + 1 + LLPerfStats::tunedAvatars)); + } + } + + bool exceeds_max_ART = + ((LLPerfStats::renderAvatarMaxART_ns > 0) && (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns)); + + if (exceeds_max_ART && !ignore_tune) { if( !mTooSlow ) // if we were previously not slow (with or without shadows.) { @@ -9364,7 +9384,12 @@ void LLVOAvatar::updateTooSlow() } // mTooSlow = false; - mTooSlowWithoutShadows = false; + mTooSlowWithoutShadows = false; + + if (ignore_tune) + { + return; + } } if(mTooSlow && !mTuned) { @@ -11794,6 +11819,64 @@ void LLVOAvatar::idleUpdateRenderComplexity() // Render Complexity calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed + + bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); + if (autotune && !isDead()) + { + static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); + F32 radius = render_far_clip * render_far_clip; + + bool is_nearby = true; + if ((dist_vec_squared(getPositionGlobal(), gAgent.getPositionGlobal()) > radius) && + (dist_vec_squared(getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius)) + { + is_nearby = false; + } + + if (is_nearby && (sAVsIgnoringARTLimit.size() < MIN_NONTUNED_AVS)) + { + if (std::count(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID) == 0) + { + sAVsIgnoringARTLimit.push_back(mID); + } + } + else if (!is_nearby) + { + sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), + sAVsIgnoringARTLimit.end()); + } + updateNearbyAvatarCount(); + } +} + +void LLVOAvatar::updateNearbyAvatarCount() +{ + static LLFrameTimer agent_update_timer; + + if (agent_update_timer.getElapsedTimeF32() > 1.0f) + { + S32 avs_nearby = 0; + static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); + F32 radius = render_far_clip * render_far_clip; + std::vector::iterator char_iter = LLCharacter::sInstances.begin(); + while (char_iter != LLCharacter::sInstances.end()) + { + LLVOAvatar *avatar = dynamic_cast(*char_iter); + if (avatar && !avatar->isDead() && !avatar->isControlAvatar()) + { + if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) && + (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius)) + { + char_iter++; + continue; + } + avs_nearby++; + } + char_iter++; + } + sAvatarsNearby = avs_nearby; + agent_update_timer.reset(); + } } void LLVOAvatar::idleUpdateDebugInfo() diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a699b87ff7..ecc33c405c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -330,6 +330,8 @@ public: void idleUpdateBelowWater(); + static void updateNearbyAvatarCount(); + //-------------------------------------------------------------------- // Static preferences (controlled by user settings/menus) //-------------------------------------------------------------------- @@ -355,6 +357,9 @@ public: static LLPointer sCloudTexture; + static std::vector sAVsIgnoringARTLimit; + static S32 sAvatarsNearby; + //-------------------------------------------------------------------- // Region state //-------------------------------------------------------------------- diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml index 5d4ffd232b..28365595cc 100644 --- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml +++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml @@ -148,6 +148,10 @@ label="Avatars and Scene" name="av_and_scene" value="1" /> +