SL-16627 AutoFPS first pass

master
Mnikolenko Productengine 2022-01-24 16:33:44 +02:00
parent 5b04123aec
commit d7603ffc9c
17 changed files with 337 additions and 41 deletions

View File

@ -16620,6 +16620,63 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>AutoFPS</key>
<map>
<key>Comment</key>
<string>
Allow dynamic adjustment of graphics preferences
</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AutoAdjustmentTimeout</key>
<map>
<key>Comment</key>
<string>Time before next iteration of automatic adjustments</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5</real>
</map>
<key>InitialAdjustmentTimeout</key>
<map>
<key>Comment</key>
<string>Time before first iteration of automatic adjustments after login to the world, teleporting, maximizing Viewer etc.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>10</real>
</map>
<key>AutoFPSLowerBoundary</key>
<map>
<key>Comment</key>
<string>FPS lower boundary when automatic adjustments are occured to reduce graphics quality to increase FPS</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>30</real>
</map>
<key>AutoFPSUpperBoundary</key>
<map>
<key>Comment</key>
<string>FPS upper boundary when automatic adjustments are occured to increase graphics quality</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>50</real>
</map>
<key>CameraOpacity</key>
<map>
<key>Comment</key>

View File

@ -4078,6 +4078,8 @@ void LLAgent::handleTeleportFinished()
mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
}
}
gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
}
void LLAgent::handleTeleportFailed()
@ -4109,6 +4111,8 @@ void LLAgent::handleTeleportFailed()
}
mTPNeedsNeabyChatSeparator = false;
gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
}
/*static*/

View File

@ -36,13 +36,15 @@
#include "llfloaterpreference.h" // LLAvatarComplexityControls
#include "llfloaterreg.h"
#include "llnamelistctrl.h"
#include "llnotificationsutil.h"
#include "llradiogroup.h"
#include "llsliderctrl.h"
#include "lltextbox.h"
#include "lltrans.h"
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llvoavatarself.h"
#include "llworld.h"
#include "pipeline.h"
const F32 REFRESH_INTERVAL = 1.0f;
@ -77,6 +79,8 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
mNearbyMaxComplexity(0)
{
mContextMenu = new LLExceptionsContextMenu(this);
mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPerformance::onUICtrlMouseDown, this));
}
LLFloaterPerformance::~LLFloaterPerformance()
@ -328,7 +332,7 @@ void LLFloaterPerformance::populateNearbyList()
static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
std::vector<LLCharacter*> valid_nearby_avs;
getNearbyAvatars(valid_nearby_avs);
mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
while (char_iter != valid_nearby_avs.end())
@ -401,31 +405,6 @@ void LLFloaterPerformance::populateNearbyList()
mNearbyList->selectByID(prev_selected_id);
}
void LLFloaterPerformance::getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs)
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
mNearbyMaxComplexity = 0;
F32 radius = render_far_clip * render_far_clip;
std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
while (char_iter != LLCharacter::sInstances.end())
{
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*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;
}
avatar->calculateUpdateRenderComplexity();
mNearbyMaxComplexity = llmax(mNearbyMaxComplexity, (S32)avatar->getVisualComplexity());
valid_nearby_avs.push_back(*char_iter);
}
char_iter++;
}
}
void LLFloaterPerformance::detachItem(const LLUUID& item_id)
{
LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
@ -561,4 +540,21 @@ void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
}
}
void LLFloaterPerformance::onUICtrlMouseDown()
{
static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
if (use_auto_adjust)
{
LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
[this](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
gSavedSettings.setBOOL("AutoFPS", FALSE);
}
});
}
}
// EOF

View File

@ -63,11 +63,11 @@ private:
void onClickHideAvatars();
void onClickExceptions();
void onUICtrlMouseDown();
void updateMaxComplexity();
void updateComplexityText();
void getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs);
LLPanel* mMainPanel;
LLPanel* mNearbyPanel;
LLPanel* mComplexityPanel;

View File

@ -304,6 +304,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPreference::onUICtrlMouseDown, this));
sSkin = gSavedSettings.getString("SkinCurrent");
@ -1782,6 +1783,23 @@ void LLFloaterPreference::updateSearchableItems()
mSearchDataDirty = true;
}
void LLFloaterPreference::onUICtrlMouseDown()
{
static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
if (use_auto_adjust)
{
LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
[this](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
gSavedSettings.setBOOL("AutoFPS", FALSE);
}
});
}
}
void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
{
LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));

View File

@ -110,6 +110,8 @@ public:
void updateClickActionViews();
void updateSearchableItems();
void onUICtrlMouseDown();
void onBtnOK(const LLSD& userdata);
void onBtnCancel(const LLSD& userdata);

View File

@ -32,6 +32,7 @@
#include "llfeaturemanager.h"
#include "llfloaterpreference.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsliderctrl.h"
#include "lltextbox.h"
#include "lltrans.h"
@ -48,8 +49,12 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown, this));
mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2));
}
LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
@ -190,6 +195,23 @@ void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, L
}
}
void LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown()
{
static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
if (use_auto_adjust)
{
LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
[this](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
gSavedSettings.setBOOL("AutoFPS", FALSE);
}
});
}
}
void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
{
// Called when the IndirectMaxNonImpostors control changes
@ -206,6 +228,16 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LLSD& newvalue)
{
U32 value = newvalue.asInteger();
if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
{
gSavedSettings.setU32("IndirectMaxNonImpostors", value);
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
}
void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
{
if (0 == value)
@ -340,9 +372,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
ctrl_reflections->setEnabled(reflections);
reflections_text->setEnabled(reflections);
// Transparent Water
LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
// Bump & Shiny
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
@ -393,9 +422,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);

View File

@ -45,6 +45,8 @@ public:
void refreshEnabledState();
void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
void updateMaxNonImpostors();
void updateIndirectMaxNonImpostors(const LLSD& newvalue);
void onUICtrlMouseDown();
void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
void updateMaxComplexity();
void updateComplexityText();

View File

@ -1024,6 +1024,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.clearReferences();
gPipeline.rebuildGroups();
gPipeline.autoAdjustSettings();
}
LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");

View File

@ -33,6 +33,7 @@
#include "llstl.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
#include "lldrawpool.h"
#include "llglheaders.h"
@ -1396,6 +1397,32 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
}
}
S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs)
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
S32 nearby_max_complexity = 0;
F32 radius = render_far_clip * render_far_clip;
std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
while (char_iter != LLCharacter::sInstances.end())
{
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*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;
}
avatar->calculateUpdateRenderComplexity();
nearby_max_complexity = llmax(nearby_max_complexity, (S32)avatar->getVisualComplexity());
valid_nearby_avs.push_back(*char_iter);
}
char_iter++;
}
return nearby_max_complexity;
}
bool LLWorld::isRegionListed(const LLViewerRegion* region) const
{
region_list_t::const_iterator it = find(mRegionList.begin(), mRegionList.end(), region);

View File

@ -51,6 +51,7 @@ class LLHost;
class LLViewerObject;
class LLSurfacePatch;
class LLCharacter;
class LLCloudPuff;
class LLCloudGroup;
class LLVOAvatar;
@ -172,6 +173,8 @@ public:
// or if the circuit to this simulator had been lost.
bool isRegionListed(const LLViewerRegion* region) const;
S32 getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs);
private:
region_list_t mActiveRegionList;
region_list_t mRegionList;

View File

@ -43,6 +43,7 @@
#include "llui.h"
#include "llglheaders.h"
#include "llrender.h"
#include "llstartup.h"
#include "llwindow.h" // swapBuffers()
// newview includes
@ -405,7 +406,8 @@ LLPipeline::LLPipeline() :
mLightMovingMask(0),
mLightingDetail(0),
mScreenWidth(0),
mScreenHeight(0)
mScreenHeight(0),
mUpdateTimer(new LLTimer())
{
mNoiseMap = 0;
mTrueNoiseMap = 0;
@ -613,7 +615,7 @@ void LLPipeline::init()
LLPipeline::~LLPipeline()
{
delete mUpdateTimer;
}
void LLPipeline::cleanup()
@ -11428,3 +11430,117 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
const F32 MIN_DRAW_DISTANCE = 64;
const F32 MAX_DRAW_DISTANCE = 256;
void update_far_clip(F32 fps_dif)
{
F32 DIST_PER_FRAME_DIF = 16;
F32 new_far_clip = llclamp(LLPipeline::RenderFarClip - llmin(fps_dif * DIST_PER_FRAME_DIF, (F32)128), MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE);
gSavedSettings.setF32("RenderFarClip", new_far_clip);
}
void update_max_non_impostors(F32 fps_dif, S32 max_avatars)
{
const F32 IMPOSTORS_PER_FRAME_DIF = 0.5;
U32 new_non_imp = (U32)llclamp((S32)(LLVOAvatar::sMaxNonImpostors - llmin((S32)(fps_dif / IMPOSTORS_PER_FRAME_DIF), 10)), 1, max_avatars);
gSavedSettings.setU32("RenderAvatarMaxNonImpostors", new_non_imp);
}
void LLPipeline::autoAdjustSettings()
{
static LLCachedControl<bool> use_auto_adjustment(gSavedSettings,"AutoFPS");
if (!use_auto_adjustment)
{
return;
}
if (LLStartUp::getStartupState() < STATE_STARTED || LLApp::isExiting())
{
return;
}
static LLCachedControl<F32> adjustment_timeout(gSavedSettings, "AutoAdjustmentTimeout");
static LLCachedControl<F32> initial_adjustment_timeout(gSavedSettings, "InitialAdjustmentTimeout");
static LLCachedControl<S32> fps_lower_boundary(gSavedSettings, "AutoFPSLowerBoundary");
static LLCachedControl<S32> fps_upper_boundary(gSavedSettings, "AutoFPSUpperBoundary");
if (gViewerWindow && gViewerWindow->getWindow()->getVisible()
&& gFocusMgr.getAppHasFocus() && !gTeleportDisplay)
{
static bool is_init = false;
if (!is_init)
{
//wait for FPS to stabilize after login in-world
mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
is_init = true;
}
if (mUpdateTimer->hasExpired())
{
mUpdateTimer->setTimerExpirySec((F32)adjustment_timeout);
const S32 FPS_STAT_PERIODS = 50;
S32 fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, FPS_STAT_PERIODS));
if (fps < fps_lower_boundary)
{
S32 fps_dif = fps_lower_boundary - fps;
if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0)
{
S32 shadow_detail = RenderShadowDetail - 1;
gSavedSettings.setS32("RenderShadowDetail", shadow_detail);
return;
}
if (RenderFarClip > MIN_DRAW_DISTANCE)
{
update_far_clip(fps_dif);
}
std::vector<LLCharacter*> valid_nearby_avs;
LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
if (valid_nearby_avs.size() > 1 && LLVOAvatar::sMaxNonImpostors > 1)
{
update_max_non_impostors(fps_dif, valid_nearby_avs.size());
}
}
else if (fps > fps_upper_boundary)
{
S32 fps_dif = fps_upper_boundary - fps;
std::vector<LLCharacter*> valid_nearby_avs;
LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
if (valid_nearby_avs.size() > 1 && (LLVOAvatar::sMaxNonImpostors < valid_nearby_avs.size()))
{
update_max_non_impostors(fps_dif, valid_nearby_avs.size());
return;
}
if (RenderFarClip < MAX_DRAW_DISTANCE)
{
update_far_clip(fps_dif);
}
if (LLPipeline::sRenderDeferred && RenderShadowDetail < 2)
{
S32 shadow_detail = RenderShadowDetail + 1;
gSavedSettings.setS32("RenderShadowDetail", shadow_detail);
}
}
}
}
else
{
//wait for FPS to stabilize if the window was minimized or not focused before
mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
}
}
void LLPipeline::setAdjustmentTimerExpiry(F32 expiration)
{
mUpdateTimer->setTimerExpirySec(expiration);
}

View File

@ -424,6 +424,9 @@ public:
void hideObject( const LLUUID& id );
void restoreHiddenObject( const LLUUID& id );
void autoAdjustSettings();
void setAdjustmentTimerExpiry(F32 expiration);
private:
void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp );
@ -715,7 +718,8 @@ protected:
U64 mOldRenderDebugMask;
std::stack<U32> mRenderDebugFeatureStack;
LLTimer* mUpdateTimer;
/////////////////////////////////////////////
//
//

View File

@ -39,7 +39,10 @@
max_val="512"
name="DrawDistance"
top_delta="16"
width="330" />
width="330">
<slider.mouse_down_callback
function="Pref.MouseDown" />
</slider>
<text
type="string"
length="1"
@ -182,6 +185,8 @@
<slider.commit_callback
function="Pref.UpdateIndirectMaxNonImpostors"
parameter="IndirectNonImpostorsText" />
<slider.mouse_down_callback
function="Pref.MouseDown" />
</slider>
<text
type="string"
@ -850,6 +855,8 @@
top_delta="0"
name="ShadowDetail"
width="150">
<combo_box.mouse_down_callback
function="Pref.MouseDown" />
<combo_box.item
label="None"
name="0"

View File

@ -1847,6 +1847,19 @@ Graphics Quality can be raised in Preferences &gt; Graphics.
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="AutoFPSConfirmDisable"
type="alertmodal">
Changing this setting will disable automatic adjustment and turn off 'Auto FPS' setting.
Are you sure you want to continue?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="Continue"/>
</notification>
<notification
icon="alertmodal.tga"
name="RegionNoTerraforming"

View File

@ -206,7 +206,10 @@
max_val="512"
name="draw_distance"
left_pad="5"
width="250" />
width="250">
<slider.mouse_down_callback
function="Pref.MouseDown" />
</slider>
<text
type="string"
length="1"

View File

@ -217,7 +217,10 @@
max_val="512"
name="DrawDistance"
top_delta="40"
width="330" />
width="330">
<slider.mouse_down_callback
function="Pref.MouseDown" />
</slider>
<text
type="string"
length="1"
@ -258,6 +261,18 @@
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
</check_box>
<check_box
control_name="AutoFPS"
height="16"
initial_value="true"
label="Auto FPS"
layout="topleft"
left="30"
name="AutoFPS"
top_delta="30"
width="256">
</check_box>
<slider
control_name="IndirectMaxComplexity"
@ -274,7 +289,7 @@
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
top_delta="60"
top_delta="34"
width="300">
<slider.commit_callback
function="Pref.UpdateIndirectMaxComplexity"