diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2023-05-02 17:39:13 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2023-05-02 17:39:13 +0300 | 
| commit | 1444c4a23cb0167002dd398a16cfc78a72e43e03 (patch) | |
| tree | b412497a524177b55b981220dfd8c11414496ad1 /indra/newview | |
| parent | f9cb6a13b23df14c2dcc7709fafdb28c578a934e (diff) | |
| parent | 7ed52090a67882cd0bc904f1e0a9ce07cf6768e9 (diff) | |
Merge branch 'main' into DRTVWR-582-maint-U
Diffstat (limited to 'indra/newview')
73 files changed, 5819 insertions, 853 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 361718a13e..dbd1f1b4ac 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -255,10 +255,12 @@ set(viewer_SOURCE_FILES      llfloaterpathfindinglinksets.cpp      llfloaterpathfindingobjects.cpp      llfloaterpay.cpp +    llfloaterperformance.cpp      llfloaterperms.cpp      llfloaterpostprocess.cpp      llfloaterprofile.cpp      llfloaterpreference.cpp +    llfloaterpreferencesgraphicsadvanced.cpp      llfloaterpreferenceviewadvanced.cpp      llfloaterpreviewtrash.cpp      llfloaterprofiletexture.cpp @@ -897,10 +899,12 @@ set(viewer_HEADER_FILES      llfloaterpathfindinglinksets.h      llfloaterpathfindingobjects.h      llfloaterpay.h +    llfloaterperformance.h      llfloaterperms.h      llfloaterpostprocess.h      llfloaterprofile.h      llfloaterpreference.h +    llfloaterpreferencesgraphicsadvanced.h      llfloaterpreferenceviewadvanced.h      llfloaterpreviewtrash.h      llfloaterprofiletexture.h @@ -1339,6 +1343,9 @@ set(viewer_HEADER_FILES      VorbisFramework.h      ) +  list(APPEND viewer_SOURCE_FILES llperfstats.cpp) +  list(APPEND viewer_HEADER_FILES llperfstats.h) +  source_group("CMake Rules" FILES ViewerInstall.cmake)  #build_data.json creation moved to viewer_manifest.py MAINT-6413 diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 8a68577213..5ea36a044a 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.11 +6.6.12 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 2644f5f449..4a3dfffde1 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -285,4 +285,14 @@           is_running_function="Floater.IsOpen"           is_running_parameters="360capture"             /> +  <command name="performance" +         available_in_toybox="true" +         icon="Command_Performance_Icon" +         label_ref="Command_Performance_Label" +         tooltip_ref="Command_Performance_Tooltip" +         execute_function="Floater.ToggleOrBringToFront" +         execute_parameters="performance" +         is_running_function="Floater.IsOpen" +         is_running_parameters="performance" +           />  </commands> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5b465864cc..8859080531 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1415,7 +1415,7 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>1024</integer> +      <integer>4096</integer>      </map>      <key>CacheValidateCounter</key>      <map> @@ -8828,6 +8828,28 @@        <key>Value</key>        <integer>1</integer>      </map> +  <key>RenderClass0MemoryBandwidth</key> +  <map> +    <key>Comment</key> +    <string>Memory bandwidth at which to default to Class 0 in gigabytes per second.  Used as basis for other classes.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>16.0</real> +  </map> +  <key>RenderCPUBasis</key> +  <map> +    <key>Comment</key> +    <string>Reference CPU clockspeed to use to bias GPU class (in MHz).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>3000.0</real> +  </map>    <key>RenderComplexityColorMin</key>      <map>        <key>Comment</key> @@ -9085,6 +9107,17 @@      <key>Value</key>      <real>0.5</real>    </map> +  <key>RenderShadowSplits</key> +  <map> +    <key>Comment</key> +    <string>Amount of shadow map splits to render (0 - 3).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>S32</string> +    <key>Value</key> +    <integer>3</integer> +  </map>    <key>RenderSSAOScale</key>    <map>      <key>Comment</key> @@ -16722,6 +16755,160 @@        <key>Value</key>        <integer>0</integer>      </map> +  <key>TargetFPS</key> +  <map> +    <key>Comment</key> +    <string>Desired minimum FPS</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>15</integer> +  </map> +  <key>AutoTuneFPS</key> +  <map> +    <key>Comment</key> +    <string>Allow the viewer to adjust your settings to achieve target FPS</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>AutoTuneLock</key> +  <map> +    <key>Comment</key> +    <string>When enabled the viewer will dynamically change settings until auto tune is explicitly turned off.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>KeepAutoTuneLock</key> +  <map> +    <key>Comment</key> +    <string>When enabled the AutoTuneLock will be maintainted all following sessions.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>AllowSelfImpostor</key> +  <map> +    <key>Comment</key> +    <string>Allow own render time to impostor your avatar.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>ShowTunedART</key> +  <map> +    <key>Comment</key> +    <string>Show the current render time not the pre-tuning render time in the avatar display.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>RenderAvatarMaxART</key> +  <map> +    <key>Comment</key> +    <string>Render Time Limit in microseconds (0.0 = no limit)</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>4.699</real> +  </map> +  <key>AutoTuneRenderFarClipMin</key> +  <map> +    <key>Comment</key> +    <string>The lowest draw distance that auto tune is allowed to use</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>32.0</real> +  </map> +  <key>AutoTuneRenderFarClipTarget</key> +  <map> +    <key>Comment</key> +    <string>The draw distance that auto tune will try to achieve</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>256.0</real> +  </map> +  <key>UserTargetReflections</key> +  <map> +    <key>Comment</key> +    <string>Set by auto tune floater on build</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>S32</string> +    <key>Value</key> +    <integer>4</integer> +  </map> +  <key>PerfStatsCaptureEnabled</key> +  <map> +    <key>Comment</key> +    <string>Enable/disable render time data to support autotune.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>AutoTuneImpostorByDistEnabled</key> +  <map> +    <key>Comment</key> +    <string>Enable/disable using MaxNonImpostor to limit avatar rendering by distance.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>AutoTuneImpostorFarAwayDistance</key> +  <map> +    <key>Comment</key> +    <string>Avatars beyond this range will automatically be optimized</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>64.0</real> +  </map> +  <key>TuningFPSStrategy</key> +  <map> +    <key>Comment</key> +    <string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings, 2=Tune only global scene.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>1</integer> +  </map>    <key>CameraOpacity</key>    <map>      <key>Comment</key> diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml index f3a23edc58..a1c9d6d9ee 100644 --- a/indra/newview/app_settings/toolbars.xml +++ b/indra/newview/app_settings/toolbars.xml @@ -22,6 +22,7 @@      <command name="voice"/>      <command name="minimap"/>      <command name="snapshot"/> +    <command name="performance"/>    </left_toolbar>    <right_toolbar      button_display_mode="icons_only"> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 93dd5e7e70..7bb89441f2 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -112,6 +112,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0.5  RenderAvatarMaxComplexity   1	100000  RenderAvatarPhysicsLODFactor 1	0.75 +RenderAvatarMaxNonImpostors 1   5  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	8 @@ -141,6 +142,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	200000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   7  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -152,7 +154,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.25  WindLightUseAtmosShaders	1	1  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -170,6 +172,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	250000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   9  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -181,7 +184,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.375  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	0 @@ -199,6 +202,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	300000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   11  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -210,7 +214,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.5  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -228,6 +232,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	350000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   16  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -239,7 +244,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.75  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -255,6 +260,7 @@ list Ultra  RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0 +RenderAvatarMaxNonImpostors 1   16  RenderAvatarPhysicsLODFactor 1	1.0  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index fed035c7fa..1281b77e45 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -93,7 +93,7 @@ RenderTerrainDetail			1	0  RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0 -RenderVolumeLODFactor		1	0.5 +RenderVolumeLODFactor		1	1.125  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -111,6 +111,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0.5  RenderAvatarMaxComplexity   1	100000  RenderAvatarPhysicsLODFactor 1	0.75 +RenderAvatarMaxNonImpostors 1   5  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	8 @@ -140,6 +141,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	200000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   7  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -151,7 +153,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.25  WindLightUseAtmosShaders	1	1  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -169,6 +171,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	250000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   9  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -180,7 +183,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.375  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	0 @@ -198,6 +201,7 @@ RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0  RenderAvatarMaxComplexity   1	300000  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   11  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 @@ -209,7 +213,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.5  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -225,6 +229,7 @@ list HighUltra  RenderAnisotropic			1	1  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0 +RenderAvatarMaxNonImpostors 1   16  RenderAvatarMaxComplexity   1	350000  RenderAvatarPhysicsLODFactor 1	1.0  RenderFarClip				1	128 @@ -238,7 +243,7 @@ RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5 -RenderVolumeLODFactor		1	1.125 +RenderVolumeLODFactor		1	1.75  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -255,6 +260,7 @@ RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0  RenderAvatarPhysicsLODFactor 1	1.0 +RenderAvatarMaxNonImpostors 1   16  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 9018a5f168..8cc9be7244 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -63,6 +63,7 @@  #include "llnotificationsutil.h"  #include "llpaneltopinfobar.h"  #include "llparcel.h" +#include "llperfstats.h"  #include "llrendersphere.h"  #include "llscriptruntimeperms.h"  #include "llsdutil.h" @@ -4102,6 +4103,7 @@ void LLAgent::handleTeleportFinished()              mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));          }      } +    LLPerfStats::tunables.autoTuneTimeout = true;  }  void LLAgent::handleTeleportFailed() @@ -4133,6 +4135,8 @@ void LLAgent::handleTeleportFailed()  	}      mTPNeedsNeabyChatSeparator = false; + +    LLPerfStats::tunables.autoTuneTimeout = true;  }  /*static*/ diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9e06fc3ac0..8d77a39c74 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -108,6 +108,7 @@  #include "llscenemonitor.h"  #include "llavatarrenderinfoaccountant.h"  #include "lllocalbitmaps.h" +#include "llperfstats.h"   // Linden library includes  #include "llavatarnamecache.h" @@ -1376,82 +1377,91 @@ bool LLAppViewer::frame()  bool LLAppViewer::doFrame()  { -	LL_RECORD_BLOCK_TIME(FTM_FRAME); +    LL_RECORD_BLOCK_TIME(FTM_FRAME); +    { +    // and now adjust the visuals from previous frame. +    if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing) +    { +        LLPerfStats::tunables.applyUpdates(); +    } +    LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_FRAME);      if (!LLWorld::instanceExists())      {          LLWorld::createInstance();      } -	LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); -	LLSD newFrame; - -	{ -        LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace"); -        if (LLFloaterReg::instanceVisible("block_timers")) +    LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); +    LLSD newFrame; +    { +        LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); // perf stats          { -	LLTrace::BlockTimer::processTimes(); -        } -         -	LLTrace::get_frame_recording().nextPeriod(); -	LLTrace::BlockTimer::logStats(); -	} +            LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace"); +            if (LLFloaterReg::instanceVisible("block_timers")) +            { +                LLTrace::BlockTimer::processTimes(); +            } -	LLTrace::get_thread_recorder()->pullFromChildren(); +            LLTrace::get_frame_recording().nextPeriod(); +            LLTrace::BlockTimer::logStats(); +        } -	//clear call stack records -	LL_CLEAR_CALLSTACKS(); +        LLTrace::get_thread_recorder()->pullFromChildren(); -	{ -		LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df processMiscNativeEvents" ) -		pingMainloopTimeout("Main:MiscNativeWindowEvents"); +        //clear call stack records +        LL_CLEAR_CALLSTACKS(); +    } +    { +        { +            LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE); // ensure we have the entire top scope of frame covered (input event and coro) +            LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df processMiscNativeEvents") +            pingMainloopTimeout("Main:MiscNativeWindowEvents"); -		if (gViewerWindow) -		{ -			LL_RECORD_BLOCK_TIME(FTM_MESSAGES); -			gViewerWindow->getWindow()->processMiscNativeEvents(); -		} +            if (gViewerWindow) +            { +                LL_RECORD_BLOCK_TIME(FTM_MESSAGES); +                gViewerWindow->getWindow()->processMiscNativeEvents(); +            } -		{ -			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gatherInput" ) -		pingMainloopTimeout("Main:GatherInput"); -		} +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df gatherInput") +                pingMainloopTimeout("Main:GatherInput"); +            } -		if (gViewerWindow) -		{ -			LL_RECORD_BLOCK_TIME(FTM_MESSAGES); -			if (!restoreErrorTrap()) -			{ -				LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; -			} +            if (gViewerWindow) +            { +                LL_RECORD_BLOCK_TIME(FTM_MESSAGES); +                if (!restoreErrorTrap()) +                { +                    LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; +                } -			gViewerWindow->getWindow()->gatherInput(); -		} +                gViewerWindow->getWindow()->gatherInput(); +            } -		//memory leaking simulation -		if (gSimulateMemLeak) -		{ -			LLFloaterMemLeak* mem_leak_instance = -				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -			if (mem_leak_instance) -			{ -				mem_leak_instance->idle(); -			} -		} +            //memory leaking simulation +            if (gSimulateMemLeak) +            { +                LLFloaterMemLeak* mem_leak_instance = +                    LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +                if (mem_leak_instance) +                { +                    mem_leak_instance->idle(); +                } +            } -		{ -			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df mainloop" ) -		// canonical per-frame event -		mainloop.post(newFrame); -		} +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df mainloop") +                // canonical per-frame event +                mainloop.post(newFrame); +            } -		{ -			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" ) -		// give listeners a chance to run -		llcoro::suspend(); -		// if one of our coroutines threw an uncaught exception, rethrow it now -		LLCoros::instance().rethrow(); -		} +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend") +                // give listeners a chance to run +                llcoro::suspend(); +            } +        }  		if (!LLApp::isExiting())  		{ @@ -1469,6 +1479,7 @@ bool LLAppViewer::doFrame()  				&& (gHeadlessClient || !gViewerWindow->getShowProgress())  				&& !gFocusMgr.focusLocked())  			{ +                LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);  				joystick->scanJoystick();  				gKeyboard->scanKeyboard();                  gViewerInput.scanMouse(); @@ -1482,6 +1493,7 @@ bool LLAppViewer::doFrame()  				}  				{ +                    LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);  					LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);  					idle();  				} @@ -1516,13 +1528,14 @@ bool LLAppViewer::doFrame()  				display(); -				{ -					LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) -				pingMainloopTimeout("Main:Snapshot"); -				LLFloaterSnapshot::update(); // take snapshots -                LLFloaterSimpleOutfitSnapshot::update(); -				gGLActive = FALSE; -			} +                { +                    LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE); +                    LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) +                    pingMainloopTimeout("Main:Snapshot"); +                    LLFloaterSnapshot::update(); // take snapshots +                    LLFloaterSimpleOutfitSnapshot::update(); +                    gGLActive = FALSE; +                }  		}  		} @@ -1568,7 +1581,8 @@ bool LLAppViewer::doFrame()  				// of equal priority on Windows  				if (milliseconds_to_sleep > 0)  				{ -					ms_sleep(milliseconds_to_sleep); +                    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SLEEP ); +                    ms_sleep(milliseconds_to_sleep);  					// also pause worker threads during this wait period  					LLAppViewer::getTextureCache()->pause();  					LLAppViewer::getImageDecodeThread()->pause(); @@ -1669,7 +1683,7 @@ bool LLAppViewer::doFrame()  		LL_INFOS() << "Exiting main_loop" << LL_ENDL;  	} - +    }LLPerfStats::StatsRecorder::endFrame();      LL_PROFILER_FRAME_END  	return ! LLApp::isRunning(); @@ -3010,15 +3024,9 @@ void LLAppViewer::initStrings()  	}  } -// -// This function decides whether the client machine meets the minimum requirements to -// run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011. -//  bool LLAppViewer::meetsRequirementsForMaximizedStart()  { -	bool maximizedOk = (LLFeatureManager::getInstance()->getGPUClass() >= GPU_CLASS_2); - -	maximizedOk &= (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1)); +    bool maximizedOk = (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));  	return maximizedOk;  } diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp index 94584a623b..8b09f7903d 100644 --- a/indra/newview/llavatarrendernotifier.cpp +++ b/indra/newview/llavatarrendernotifier.cpp @@ -235,6 +235,12 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity)      // save the value for use in following messages      mLatestAgentComplexity = agentComplexity; +    static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); +    if (!show_my_complexity_changes) +    { +        return; +    } +      if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded())      {          // data not ready, nothing to show. @@ -282,7 +288,8 @@ static const char* e_hud_messages[] =  };  LLHUDRenderNotifier::LLHUDRenderNotifier() : -mReportedHUDWarning(WARN_NONE) +mReportedHUDWarning(WARN_NONE), +mHUDsCount(0)  {  } @@ -298,6 +305,15 @@ void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity          return;      } +    mHUDComplexityList = complexity; +    mHUDsCount = mHUDComplexityList.size(); + +    static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); +    if (!show_my_complexity_changes) +    { +        return; +    } +              // TODO:      // Find a way to show message with list of issues, but without making it too large      // and intrusive. diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h index ec17b3d9e6..37130bfcf6 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -63,6 +63,25 @@ struct LLHUDComplexity  typedef std::list<LLHUDComplexity> hud_complexity_list_t; +struct LLObjectComplexity +{ +    LLObjectComplexity() +    { +        reset(); +    } +    void reset() +    { +        objectId = LLUUID::null; +        objectName = ""; +        objectCost = 0; +    } +    LLUUID objectId; +    std::string objectName; +    U32 objectCost; +}; + +typedef std::list<LLObjectComplexity> object_complexity_list_t; +  // Class to notify user about drastic changes in agent's render weights or if other agents  // reported that user's agent is too 'heavy' for their settings  class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier> @@ -77,6 +96,9 @@ public:      void updateNotificationState();  	void updateNotificationAgent(U32 agentComplexity); +    void setObjectComplexityList(object_complexity_list_t object_list) { mObjectComplexityList = object_list; } +    object_complexity_list_t getObjectComplexityList() { return mObjectComplexityList; } +  private:  	LLNotificationPtr mNotificationPtr; @@ -109,6 +131,8 @@ private:      // Used to detect changes in voavatar's rezzed status.      // If value decreases - there were changes in outfit.      S32 mLastOutfitRezStatus; + +    object_complexity_list_t mObjectComplexityList;  };  // Class to notify user about heavy set of HUD @@ -121,6 +145,9 @@ public:      void updateNotificationHUD(hud_complexity_list_t complexity);      bool isNotificationVisible(); +    hud_complexity_list_t getHUDComplexityList() { return mHUDComplexityList; } +    S32 getHUDsCount() { return mHUDsCount; } +  private:      enum EWarnLevel      { @@ -141,6 +168,8 @@ private:      EWarnLevel mReportedHUDWarning;      LLHUDComplexity mLatestHUDComplexity;      LLFrameTimer mHUDPopUpDelayTimer; +    hud_complexity_list_t mHUDComplexityList; +    S32 mHUDsCount;  };  #endif /* ! defined(LL_llavatarrendernotifier_H) */ diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index a3837fe10c..594cfe513d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -52,6 +52,7 @@  #include "llglcommonfunc.h"  #include "llvoavatar.h"  #include "llviewershadermgr.h" +#include "llperfstats.h"  S32 LLDrawPool::sNumDrawPools = 0; @@ -391,13 +392,22 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;  	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; -	 + +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats   	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	  	{  		LLDrawInfo *pparams = *k;  		if (pparams)           { -			pushBatch(*pparams, mask, texture); +            if(pparams->mFace) +            { +                LLViewerObject* vobj = pparams->mFace->getViewerObject(); +                if(vobj->isAttachment()) +                { +                    trackAttachments(vobj, false, &ratPtr); +                } +            } +            pushBatch(*pparams, mask, texture);  		}  	}  } @@ -410,11 +420,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,      U64 lastMeshId = 0;      mask |= LLVertexBuffer::MAP_WEIGHT4; +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats       for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)      {          LLDrawInfo* pparams = *k;          if (pparams)           { +            if(pparams->mFace) +            { +                LLViewerObject* vobj = pparams->mFace->getViewerObject(); +                if(vobj->isAttachment()) +                { +                    trackAttachments( vobj, true ,&ratPtr); +                } +            } +              if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)              {                  uploadMatrixPalette(*pparams); @@ -430,12 +450,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,  void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)   		{ -			pushBatch(*pparams, mask, texture, batch_textures); +            if(pparams->mFace) +            { +                LLViewerObject* vobj = pparams->mFace->getViewerObject(); +                if(vobj->isAttachment()) +                { +                    trackAttachments( vobj, false, &ratPtr); +                } +            } +            pushBatch(*pparams, mask, texture, batch_textures);  		}  	}  } @@ -446,11 +475,21 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc      LLVOAvatar* lastAvatar = nullptr;      U64 lastMeshId = 0;      mask |= LLVertexBuffer::MAP_WEIGHT4; +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats       for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)      {          LLDrawInfo* pparams = *i;          if (pparams)          { +            if(pparams->mFace) +            { +                LLViewerObject* vobj = pparams->mFace->getViewerObject(); +                if(vobj->isAttachment()) +                { +                    trackAttachments( vobj, true, &ratPtr); +                } +            } +              if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))              {                  uploadMatrixPalette(*pparams); @@ -466,11 +505,20 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc  void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)   		{ +            if((*pparams).mFace) +            { +                LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); +                if(vobj->isAttachment()) +                { +                    trackAttachments( vobj, false, &ratPtr); +                } +            }  			LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);  			pushBatch(*pparams, mask, texture, batch_textures);  		} @@ -482,11 +530,20 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL      LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;      LLVOAvatar* lastAvatar = nullptr;      U64 lastMeshId = 0; +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};      for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)      {          LLDrawInfo* pparams = *i;          if (pparams)          { +            if((*pparams).mFace) +            { +                LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); +                if(vobj->isAttachment()) +                { +                    trackAttachments( vobj, true, &ratPtr); +                } +            }              if (LLGLSLShader::sCurBoundShaderPtr)              {                  LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 6c1abb24c9..5b205d373b 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -49,6 +49,7 @@  #include "llspatialpartition.h"  #include "llglcommonfunc.h"  #include "llvoavatar.h" +#include "llperfstats.h"  BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; @@ -338,10 +339,20 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)              {                  LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass  +                std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection                  for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)                  {                      LLDrawInfo& params = **k; +                    if(params.mFace) +                    { +                        LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); +                        if(vobj->isAttachment()) +                        { +                            trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); +                        } +                    } +                      if (params.mParticle)                      {                          continue; @@ -511,8 +522,16 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&      mask |= LLVertexBuffer::MAP_WEIGHT4; +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection      for (LLDrawInfo* draw : emissives)      { +        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives"); +        auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr; +        if(vobj && vobj->isAttachment()) +        { +            trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr ); +        } +          bool tex_setup = TexSetup(draw, false);          if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)          { @@ -577,7 +596,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)  			LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA]; -			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	 +            std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection +            for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	  			{  				LLDrawInfo& params = **k;                  if ((bool)params.mAvatar != rigged) @@ -596,6 +616,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)  					continue;  				} +                if(params.mFace) +                { +                    LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + +                    if(vobj->isAttachment()) +                    { +                        trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); +                    } +                } +  				if(depth_only)  				{                      // when updating depth buffer, discard faces that are more than 90% transparent @@ -780,6 +810,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)  				}  			} +            ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives +              // render emissive faces into alpha channel for bloom effects              if (!depth_only)              { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 4a9a3caaec..4ffa903cca 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -52,6 +52,7 @@  #include "llviewerpartsim.h"  #include "llviewercontrol.h" // for gSavedSettings  #include "llviewertexturelist.h" +#include "llperfstats.h"  static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;  static U32 sBufferUsage = GL_STREAM_DRAW_ARB; @@ -380,9 +381,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	{  		return;  	} +    LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS); +  	LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); -	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); -    if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE)) +	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();     +    // no shadows if the shadows are causing this avatar to breach the limit. +    if (avatarp->isTooSlow() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))  	{          // No shadows for impostored (including jellydolled) or invisible avs.  		return; @@ -789,6 +793,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	{  		return;  	} +    LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);  	if (!single_avatar && !avatarp->isFullyLoaded() )  	{ diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index e6b6b10408..cc454417c6 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -49,6 +49,7 @@  #include "llspatialpartition.h"  #include "llviewershadermgr.h"  #include "llmodel.h" +#include "llperfstats.h"  //#include "llimagebmp.h"  //#include "../tools/imdebug/imdebug.h" @@ -542,10 +543,18 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL  {					  	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];	 -	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)  +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; +    for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)   	{  		LLDrawInfo& params = **k; +        LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + +        if( vobj && vobj->isAttachment() ) +        { +            trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); +        } +  		applyModelMatrix(params);  		if (params.mGroup) @@ -710,10 +719,21 @@ void LLDrawPoolBump::renderDeferred(S32 pass)          LLVOAvatar* avatar = nullptr;          U64 skin = 0; +        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};          for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)          {              LLDrawInfo& params = **i; +            if(params.mFace) +            { +                LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + +                if(vobj && vobj->isAttachment()) +                { +                    trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); +                } +            } +              LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);              LLDrawPoolBump::bindBumpMap(params, bump_channel); @@ -1339,10 +1359,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)      LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);      LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{  		LLDrawInfo& params = **i; +        if(params.mFace) +        { +            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + +            if( vobj && vobj->isAttachment() ) +            { +                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); +            } +        } +  		if (LLDrawPoolBump::bindBumpMap(params))  		{              if (mRigged) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 2b05f4c453..f2408a3294 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -32,6 +32,7 @@  #include "pipeline.h"  #include "llglcommonfunc.h"  #include "llvoavatar.h" +#include "llperfstats.h"  S32 diffuse_channel = -1; @@ -164,9 +165,20 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)  	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);  	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; +    for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)  	{  		LLDrawInfo& params = **i; + +        if(params.mFace) +        { +            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + +            if( vobj && vobj->isAttachment() ) +            { +                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); +            } +        }  		mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);  		mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index e934041e2e..329af264eb 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -408,6 +408,7 @@ bool LLFeatureManager::loadGPUClass()  {  	if (!gSavedSettings.getBOOL("SkipBenchmark"))  	{ +        F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");  		//get memory bandwidth from benchmark  		F32 gbps;  		try @@ -424,6 +425,14 @@ bool LLFeatureManager::loadGPUClass()  			LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;  		} +        mGPUMemoryBandwidth = gbps; + +        // bias by CPU speed +        F32 cpu_basis_mhz = gSavedSettings.getF32("RenderCPUBasis"); +        F32 cpu_mhz = (F32) gSysCPU.getMHz(); +        F32 cpu_bias = llclamp(cpu_mhz / cpu_basis_mhz, 0.5f, 1.f); +        gbps *= cpu_bias; +  		if (gbps < 0.f)  		{ //couldn't bench, use GLVersion  	#if LL_DARWIN @@ -466,23 +475,23 @@ bool LLFeatureManager::loadGPUClass()  		{  			mGPUClass = GPU_CLASS_1;  		} -		else if (gbps <= 5.f) +		else if (gbps <= class0_gbps)  		{  			mGPUClass = GPU_CLASS_0;  		} -		else if (gbps <= 8.f) +		else if (gbps <= class0_gbps*2.f)  		{  			mGPUClass = GPU_CLASS_1;  		} -		else if (gbps <= 16.f) +		else if (gbps <= class0_gbps*4.f)  		{  			mGPUClass = GPU_CLASS_2;  		} -		else if (gbps <= 40.f) +		else if (gbps <= class0_gbps*8.f)  		{  			mGPUClass = GPU_CLASS_3;  		} -		else if (gbps <= 80.f) +		else if (gbps <= class0_gbps*16.f)  		{  			mGPUClass = GPU_CLASS_4;  		} diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index 42a226cd18..651404d890 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -111,6 +111,10 @@ public:  	EGPUClass getGPUClass() 			{ return mGPUClass; }  	std::string& getGPUString() 		{ return mGPUString; } +     +    // get the measured GPU memory bandwidth in GB/sec +    // may return 0 of benchmark has not been run or failed to run +    F32 getGPUMemoryBandwidth() { return mGPUMemoryBandwidth; }  	BOOL isGPUSupported()				{ return mGPUSupported; }  	F32 getExpectedGLVersion()			{ return mExpectedGLVersion; } @@ -162,6 +166,7 @@ protected:  	S32			mTableVersion;  	BOOL		mSafe;					// Reinitialize everything to the "safe" mask  	EGPUClass	mGPUClass; +    F32         mGPUMemoryBandwidth = 0.f;  // measured memory bandwidth of GPU in GB/second  	F32			mExpectedGLVersion;		//expected GL version according to gpu table  	std::string	mGPUString;  	BOOL		mGPUSupported; diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index 542a1ea39b..23f86e2361 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -319,13 +319,7 @@ const std::string LLFloater360Capture::getHTMLBaseFolder()  // triggered when the 'capture' button in the UI is pressed  void LLFloater360Capture::onCapture360ImagesBtn()  { -    // launch the main capture code in a coroutine so we can -    // yield/suspend at some points to give the main UI -    // thread a look-in occasionally. -    LLCoros::instance().launch("capture360cap", [this]() -    { -        capture360Images(); -    }); +    capture360Images();  }  // Gets the full path name for a given JavaScript file in the HTML folder. We @@ -686,9 +680,6 @@ void LLFloater360Capture::capture360Images()      mCaptureBtn->setEnabled(true);      mSaveLocalBtn->setEnabled(true); -    // allow the UI to update by suspending and waiting for the -    // main render loop to update the UI -    suspendForAFrame();  }  // once the request is made to navigate to the web page containing the code diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp index 8b28f6941e..7d098e6c88 100644 --- a/indra/newview/llfloateravatarrendersettings.cpp +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -89,8 +89,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()      LLFloater::postBuild();      mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");      mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); -    mAvatarSettingsList->setAlternateSort(); -    getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));  	return TRUE;  } @@ -134,37 +132,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); @@ -215,6 +189,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/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h index 00ee074f17..2e0a844afd 100644 --- a/indra/newview/llfloateravatarrendersettings.h +++ b/indra/newview/llfloateravatarrendersettings.h @@ -48,7 +48,6 @@ public:      void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);      void updateList(); -    void onFilterEdit(const std::string& search_string);      void onCustomAction (const LLSD& userdata, const LLUUID& av_id);      bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);      void onClickAdd(const LLSD& userdata); @@ -59,15 +58,12 @@ public:      static void setNeedsUpdate();  private: -    bool isHiddenRow(const std::string& av_name);      void callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting);      void removePicker();      bool mNeedsUpdate;      LLListContextMenu* mContextMenu;      LLNameListCtrl* mAvatarSettingsList; - -    std::string mNameFilter;  }; diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp new file mode 100644 index 0000000000..e35fa55564 --- /dev/null +++ b/indra/newview/llfloaterperformance.cpp @@ -0,0 +1,699 @@ +/**  + * @file llfloaterperformance.cpp + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterperformance.h" + +#include "llagent.h" +#include "llagentcamera.h" +#include "llappearancemgr.h" +#include "llavataractions.h" +#include "llavatarrendernotifier.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfeaturemanager.h" +#include "llfloaterpreference.h" // LLAvatarComplexityControls +#include "llfloaterreg.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llperfstats.h" +#include "llpresetsmanager.h" +#include "llradiogroup.h" +#include "llsliderctrl.h" +#include "lltextbox.h" +#include "lltrans.h" +#include "llviewerobjectlist.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llvoavatarself.h" +#include "llworld.h" +#include "pipeline.h" + +const F32 REFRESH_INTERVAL = 1.0f; +const S32 BAR_LEFT_PAD = 2; +const S32 BAR_RIGHT_PAD = 5; +const S32 BAR_BOTTOM_PAD = 9; + +constexpr auto AvType       {LLPerfStats::ObjType_t::OT_AVATAR}; +constexpr auto AttType      {LLPerfStats::ObjType_t::OT_ATTACHMENT}; +constexpr auto HudType      {LLPerfStats::ObjType_t::OT_HUD}; + +class LLExceptionsContextMenu : public LLListContextMenu +{ +public: +    LLExceptionsContextMenu(LLFloaterPerformance* floater_settings) +        :   mFloaterPerformance(floater_settings) +    {} +protected: +    LLContextMenu* createMenu() +    { +        LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +        LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; +        registrar.add("Settings.SetRendering", boost::bind(&LLFloaterPerformance::onCustomAction, mFloaterPerformance, _2, mUUIDs.front())); +        enable_registrar.add("Settings.IsSelected", boost::bind(&LLFloaterPerformance::isActionChecked, mFloaterPerformance, _2, mUUIDs.front())); +        LLContextMenu* menu = createFromFile("menu_avatar_rendering_settings.xml"); + +        return menu; +    } + +    LLFloaterPerformance* mFloaterPerformance; +}; + +LLFloaterPerformance::LLFloaterPerformance(const LLSD& key) +:   LLFloater(key), +    mUpdateTimer(new LLTimer()), +    mNearbyMaxComplexity(0) +{ +    mContextMenu = new LLExceptionsContextMenu(this); +} + +LLFloaterPerformance::~LLFloaterPerformance() +{ +    mMaxARTChangedSignal.disconnect(); +    delete mContextMenu; +    delete mUpdateTimer; +} + +BOOL LLFloaterPerformance::postBuild() +{ +    mMainPanel = getChild<LLPanel>("panel_performance_main"); +    mNearbyPanel = getChild<LLPanel>("panel_performance_nearby"); +    mComplexityPanel = getChild<LLPanel>("panel_performance_complexity"); +    mSettingsPanel = getChild<LLPanel>("panel_performance_preferences"); +    mHUDsPanel = getChild<LLPanel>("panel_performance_huds"); +    mAutoadjustmentsPanel = getChild<LLPanel>("panel_performance_autoadjustments"); + +    getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); +    getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel)); +    getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel)); +    getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel)); +    getChild<LLPanel>("autoadjustments_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mAutoadjustmentsPanel)); + +    initBackBtn(mNearbyPanel); +    initBackBtn(mComplexityPanel); +    initBackBtn(mSettingsPanel); +    initBackBtn(mHUDsPanel); +    initBackBtn(mAutoadjustmentsPanel); + +    mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list"); +    mHUDList->setNameListType(LLNameListCtrl::SPECIAL); +    mHUDList->setHoverIconName("StopReload_Off"); +    mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + +    mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list"); +    mObjectList->setNameListType(LLNameListCtrl::SPECIAL); +    mObjectList->setHoverIconName("StopReload_Off"); +    mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + +    mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); +    mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this)); +    mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2)); +    mSettingsPanel->getChild<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this)); +    mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this)); + +    mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); +    mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this)); +    mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); +    mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list"); +    mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3)); + +    mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this)); +    mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this)); + +    // store the current setting as the users desired reflection detail and DD +    gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail); +    if(!LLPerfStats::tunables.userAutoTuneEnabled) +    { +        gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip); +    } + +    LLStringExplicit fps_limit(llformat("%d", gViewerWindow->getWindow()->getRefreshRate())); +    mAutoadjustmentsPanel->getChild<LLTextBox>("vsync_desc_limit")->setTextArg("[FPS_LIMIT]", fps_limit); +    mAutoadjustmentsPanel->getChild<LLTextBox>("display_desc")->setTextArg("[FPS_LIMIT]", fps_limit); +    mAutoadjustmentsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this)); + +    mStartAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("start_autotune"); +    mStopAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("stop_autotune"); +    mStartAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::startAutotune, this)); +    mStopAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::stopAutotune, this)); + +    gSavedPerAccountSettings.declareBOOL("HadEnabledAutoFPS", FALSE, "User had enabled AutoFPS at least once", LLControlVariable::PERSIST_ALWAYS); + +    return TRUE; +} + +void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel) +{ +    hidePanels(); +    mMainPanel->setVisible(FALSE); +    selected_panel->setVisible(TRUE); + +    if (mHUDsPanel == selected_panel) +    { +        populateHUDList(); +    } +    else if (mNearbyPanel == selected_panel) +    { +        populateNearbyList(); +    } +    else if (mComplexityPanel == selected_panel) +    { +        populateObjectList(); +    } +} + +void LLFloaterPerformance::showAutoadjustmentsPanel() +{ +    showSelectedPanel(mAutoadjustmentsPanel); +} + +void LLFloaterPerformance::draw() +{ +    enableAutotuneWarning(); + +    if (mUpdateTimer->hasExpired() &&  +        !LLFloaterReg::instanceVisible("save_pref_preset", PRESETS_GRAPHIC)) // give user a chance to save the graphics settings before updating them +    { +        setFPSText(); +        if (mHUDsPanel->getVisible()) +        { +            populateHUDList(); +        } +        else if (mNearbyPanel->getVisible()) +        { +            populateNearbyList(); +            mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); +        } +        else if (mComplexityPanel->getVisible()) +        { +            populateObjectList(); +        } + +        mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL); +    } +    updateAutotuneCtrls(LLPerfStats::tunables.userAutoTuneEnabled); + +    LLFloater::draw(); +} + +void LLFloaterPerformance::showMainPanel() +{ +    hidePanels(); +    mMainPanel->setVisible(TRUE); +} + +void LLFloaterPerformance::hidePanels() +{ +    mNearbyPanel->setVisible(FALSE); +    mComplexityPanel->setVisible(FALSE); +    mHUDsPanel->setVisible(FALSE); +    mSettingsPanel->setVisible(FALSE); +    mAutoadjustmentsPanel->setVisible(FALSE); +} + +void LLFloaterPerformance::initBackBtn(LLPanel* panel) +{ +    panel->getChild<LLButton>("back_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this)); + +    panel->getChild<LLTextBox>("back_lbl")->setShowCursorHand(false); +    panel->getChild<LLTextBox>("back_lbl")->setSoundFlags(LLView::MOUSE_UP); +    panel->getChild<LLTextBox>("back_lbl")->setClickedCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this)); +} + +void LLFloaterPerformance::populateHUDList() +{ +    S32 prev_pos = mHUDList->getScrollPos(); +    LLUUID prev_selected_id = mHUDList->getSelectedSpecialId(); +    mHUDList->clearRows(); +    mHUDList->updateColumns(true); + +    hud_complexity_list_t complexity_list = LLHUDRenderNotifier::getInstance()->getHUDComplexityList(); + +    hud_complexity_list_t::iterator iter = complexity_list.begin(); +    hud_complexity_list_t::iterator end = complexity_list.end(); + +    auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY); +    for (iter = complexity_list.begin(); iter != end; ++iter) +    { +        LLHUDComplexity hud_object_complexity = *iter; + +        auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY); + +        LLSD item; +        item["special_id"] = hud_object_complexity.objectId; +        item["target"] = LLNameListCtrl::SPECIAL; +        LLSD& row = item["columns"]; +        row[0]["column"] = "complex_visual"; +        row[0]["type"] = "bar"; +        LLSD& value = row[0]["value"]; +        value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw; +        value["bottom"] = BAR_BOTTOM_PAD; +        value["left_pad"] = BAR_LEFT_PAD; +        value["right_pad"] = BAR_RIGHT_PAD; + +        row[1]["column"] = "complex_value"; +        row[1]["type"] = "text"; +        row[1]["value"] = llformat( "%.f", llmax(LLPerfStats::raw_to_us(hud_render_time_raw), (double)1)); +        row[1]["font"]["name"] = "SANSSERIF"; +  +        row[2]["column"] = "name"; +        row[2]["type"] = "text"; +        row[2]["value"] = hud_object_complexity.objectName; +        row[2]["font"]["name"] = "SANSSERIF"; + +        LLScrollListItem* obj = mHUDList->addElement(item); +        if (obj) +        { +            LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1)); +            if (value_text) +            { +                value_text->setAlignment(LLFontGL::HCENTER); +            } +        } +    } +    mHUDList->sortByColumnIndex(1, FALSE); +    mHUDList->setScrollPos(prev_pos); +    mHUDList->selectItemBySpecialId(prev_selected_id); +} + +void LLFloaterPerformance::populateObjectList() +{ +    S32 prev_pos = mObjectList->getScrollPos(); +    LLUUID prev_selected_id = mObjectList->getSelectedSpecialId(); +    mObjectList->clearRows(); +    mObjectList->updateColumns(true); + +    object_complexity_list_t complexity_list = LLAvatarRenderNotifier::getInstance()->getObjectComplexityList(); + +    object_complexity_list_t::iterator iter = complexity_list.begin(); +    object_complexity_list_t::iterator end = complexity_list.end(); + +    // for consistency we lock the buffer while we build the list. In theory this is uncontended as the buffer should only toggle on end of frame +    { +        std::lock_guard<std::mutex> guard{ LLPerfStats::bufferToggleLock }; +        auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED); + +        for (iter = complexity_list.begin(); iter != end; ++iter) +        { +            LLObjectComplexity object_complexity = *iter; + +            auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, object_complexity.objectId, LLPerfStats::StatType_t::RENDER_COMBINED); +            LLSD item; +            item["special_id"] = object_complexity.objectId; +            item["target"] = LLNameListCtrl::SPECIAL; +            LLSD& row = item["columns"]; +            row[0]["column"] = "complex_visual"; +            row[0]["type"] = "bar"; +            LLSD& value = row[0]["value"]; +            value["ratio"] = ((F32)attach_render_time_raw) / att_max_render_time_raw; +            value["bottom"] = BAR_BOTTOM_PAD; +            value["left_pad"] = BAR_LEFT_PAD; +            value["right_pad"] = BAR_RIGHT_PAD; + +            row[1]["column"] = "complex_value"; +            row[1]["type"] = "text"; +            row[1]["value"] = llformat("%.f", llmax(LLPerfStats::raw_to_us(attach_render_time_raw), (double)1)); +            row[1]["font"]["name"] = "SANSSERIF"; + +            row[2]["column"] = "name"; +            row[2]["type"] = "text"; +            row[2]["value"] = object_complexity.objectName; +            row[2]["font"]["name"] = "SANSSERIF"; + +            LLScrollListItem* obj = mObjectList->addElement(item); +            if (obj) +            { +                LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1)); +                if (value_text) +                { +                    value_text->setAlignment(LLFontGL::HCENTER); +                } +            } +        } +    } +    mObjectList->sortByColumnIndex(1, FALSE); +    mObjectList->setScrollPos(prev_pos); +    mObjectList->selectItemBySpecialId(prev_selected_id); +} + +void LLFloaterPerformance::populateNearbyList() +{ +    static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART"); +    S32 prev_pos = mNearbyList->getScrollPos(); +    LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem(); +    mNearbyList->clearRows(); +    mNearbyList->updateColumns(true); + +    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); +    std::vector<LLCharacter*> valid_nearby_avs; +    mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs); + +    std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin(); + +    LLPerfStats::bufferToggleLock.lock(); +    auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED); +    LLPerfStats::bufferToggleLock.unlock(); + +    while (char_iter != valid_nearby_avs.end()) +    { +        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter); +        if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance())) +        { +            LLPerfStats::bufferToggleLock.lock(); +            auto render_av_raw  = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED); +            LLPerfStats::bufferToggleLock.unlock(); + +            auto is_slow = avatar->isTooSlow(); +            LLSD item; +            item["id"] = avatar->getID(); +            LLSD& row = item["columns"]; +            row[0]["column"] = "complex_visual"; +            row[0]["type"] = "bar"; +            LLSD& value = row[0]["value"]; +            // The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the  +            // pre-tune value for the numerical column and sorting. +            value["ratio"] = (double)render_av_raw / av_render_max_raw; +            value["bottom"] = BAR_BOTTOM_PAD; +            value["left_pad"] = BAR_LEFT_PAD; +            value["right_pad"] = BAR_RIGHT_PAD; + +            row[1]["column"] = "complex_value"; +            row[1]["type"] = "text"; +            if (is_slow && !showTunedART) +            { +                row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( avatar->getLastART() ) ); +            } +            else +            { +                row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( render_av_raw ) ); +            } +            row[1]["font"]["name"] = "SANSSERIF"; + +            row[2]["column"] = "name"; +            row[2]["type"] = "text"; +            row[2]["value"] = avatar->getFullname(); +            row[2]["font"]["name"] = "SANSSERIF"; + +            LLScrollListItem* av_item = mNearbyList->addElement(item); +            if(av_item) +            { +                LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(1)); +                if (value_text) +                { +                    value_text->setAlignment(LLFontGL::HCENTER); +                } +                LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(2)); +                if (name_text) +                { +                    if (avatar->isSelf()) +                    { +                        name_text->setColor(LLUIColorTable::instance().getColor("DrYellow")); +                    } +                    else +                    { +                        std::string color = "white"; +                        if (is_slow || LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance()) +                        { +                            color = "LabelDisabledColor"; +                            LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0)); +                            if (bar) +                            { +                                bar->setColor(LLUIColorTable::instance().getColor(color)); +                            } +                        } +                        else if (LLVOAvatar::AOA_NORMAL == avatar->getOverallAppearance()) +                        { +                            color = LLAvatarActions::isFriend(avatar->getID()) ? "ConversationFriendColor" : "white"; +                        } +                        name_text->setColor(LLUIColorTable::instance().getColor(color)); +                    } +                } +            } +        } +        char_iter++; +    } +    mNearbyList->sortByColumnIndex(1, FALSE); +    mNearbyList->setScrollPos(prev_pos); +    mNearbyList->selectByID(prev_selected_id); +} + +void LLFloaterPerformance::setFPSText() +{ +    const S32 NUM_PERIODS = 50; +    S32 current_fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, NUM_PERIODS)); +    getChild<LLTextBox>("fps_value")->setValue(current_fps); + +    std::string fps_text = getString("fps_text"); +    static LLCachedControl<bool> vsync_enabled(gSavedSettings, "RenderVSyncEnable", true); +    S32 refresh_rate = gViewerWindow->getWindow()->getRefreshRate(); +    if (vsync_enabled && (refresh_rate > 0) && (current_fps >= refresh_rate)) +    { +        fps_text += getString("max_text"); +    } +    getChild<LLTextBox>("fps_lbl")->setValue(fps_text); +} + +void LLFloaterPerformance::detachItem(const LLUUID& item_id) +{ +    LLAppearanceMgr::instance().removeItemFromAvatar(item_id); +} + +void LLFloaterPerformance::onClickAdvanced() +{ +    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->saveSettings(); +    } +    LLFloaterReg::showInstance("prefs_graphics_advanced"); +} + +void LLFloaterPerformance::onClickDefaults() +{ +    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->setRecommendedSettings(); +    } +} + +void LLFloaterPerformance::onChangeQuality(const LLSD& data) +{ +    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->onChangeQuality(data); +    } +} + +void LLFloaterPerformance::onClickHideAvatars() +{ +    LLPipeline::toggleRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR); +} + +void LLFloaterPerformance::onClickExceptions() +{ +    LLFloaterReg::showInstance("avatar_render_settings"); +} + +void LLFloaterPerformance::updateMaxRenderTime() +{ +    LLAvatarComplexityControls::updateMaxRenderTime( +        mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART"), +        mNearbyPanel->getChild<LLTextBox>("RenderAvatarMaxARTText"),  +        true); +} + +static LLVOAvatar* find_avatar(const LLUUID& id) +{ +    LLViewerObject *obj = gObjectList.findObject(id); +    while (obj && obj->isAttachment()) +    { +        obj = (LLViewerObject *)obj->getParent(); +    } + +    if (obj && obj->isAvatar()) +    { +        return (LLVOAvatar*)obj; +    } +    else +    { +        return NULL; +    } +} + +void LLFloaterPerformance::onCustomAction(const LLSD& userdata, const LLUUID& av_id) +{ +    const std::string command_name = userdata.asString(); + +    S32 new_setting = 0; +    if ("default" == command_name) +    { +        new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY); +    } +    else if ("never" == command_name) +    { +        new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER); +    } +    else if ("always" == command_name) +    { +        new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER); +    } + +    LLVOAvatar *avatarp = find_avatar(av_id); +    if (avatarp) +    { +        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting)); +    } +    else +    { +        LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting); +    } +} + + +bool LLFloaterPerformance::isActionChecked(const LLSD& userdata, const LLUUID& av_id) +{ +    const std::string command_name = userdata.asString(); + +    S32 visual_setting = LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(av_id); +    if ("default" == command_name) +    { +        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)); +    } +    else if ("always" == command_name) +    { +        return (visual_setting == S32(LLVOAvatar::AV_ALWAYS_RENDER)); +    } +    return false; +} + +void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ +    LLNameListCtrl* list = dynamic_cast<LLNameListCtrl*>(ctrl); +    if (!list) return; +    list->selectItemAt(x, y, MASK_NONE); +    uuid_vec_t selected_uuids; + +    if((list->getCurrentID().notNull()) && (list->getCurrentID() != gAgentID)) +    { +        selected_uuids.push_back(list->getCurrentID()); +        mContextMenu->show(ctrl, selected_uuids, x, y); +    } +} + +const U32 RENDER_QUALITY_LEVEL = 3; +void LLFloaterPerformance::changeQualityLevel(const std::string& notif) +{ +    LLNotificationsUtil::add(notif, LLSD(), LLSD(), +        [](const LLSD¬if, const LLSD&resp) +    { +        S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); +        if (opt == 0) +        { +            LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences"); +            if (instance) +            { +                gSavedSettings.setU32("RenderQualityPerformance", RENDER_QUALITY_LEVEL); +                instance->onChangeQuality(LLSD((S32)RENDER_QUALITY_LEVEL)); +            } +        } +    }); +} + +bool is_ALM_available() +{ +    bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump"); +    bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); +     +    return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +        bumpshiny && +        shaders; +} + +void LLFloaterPerformance::onClickAdvancedLighting() +{ +    if (!is_ALM_available()) +    { +        changeQualityLevel("AdvancedLightingConfirm"); +    } +} + +void LLFloaterPerformance::onClickShadows() +{ +    if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred")) +    { +        changeQualityLevel("ShadowsConfirm"); +    } + +} + +void LLFloaterPerformance::startAutotune() +{ +    LLPerfStats::tunables.userAutoTuneEnabled = true; +} + +void LLFloaterPerformance::stopAutotune() +{ +    LLPerfStats::tunables.userAutoTuneEnabled = false; +} + +void LLFloaterPerformance::updateAutotuneCtrls(bool autotune_enabled) +{ +    static LLCachedControl<bool> auto_tune_locked(gSavedSettings, "AutoTuneLock"); +    mStartAutotuneBtn->setEnabled(!autotune_enabled && !auto_tune_locked); +    mStopAutotuneBtn->setEnabled(autotune_enabled && !auto_tune_locked); +    getChild<LLCheckBoxCtrl>("AutoTuneContinuous")->setEnabled(!autotune_enabled || (autotune_enabled && auto_tune_locked)); + +    getChild<LLTextBox>("wip_desc")->setVisible(autotune_enabled && !auto_tune_locked); +    getChild<LLTextBox>("display_desc")->setVisible(LLPerfStats::tunables.vsyncEnabled); +} + +void LLFloaterPerformance::enableAutotuneWarning() +{ +    if (!gSavedPerAccountSettings.getBOOL("HadEnabledAutoFPS") && LLPerfStats::tunables.userAutoTuneEnabled) +    { +        gSavedPerAccountSettings.setBOOL("HadEnabledAutoFPS", TRUE); + +        LLNotificationsUtil::add("EnableAutoFPSWarning", LLSD(), LLSD(), +            [](const LLSD& notif, const LLSD& resp) +            { +                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); +                if (opt == 0) +                { // offer user to save current graphics settings as a preset +                    LLFloaterReg::showInstance("save_pref_preset", PRESETS_GRAPHIC); +                } +            }); +    } +} +// EOF diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h new file mode 100644 index 0000000000..00f904f6d6 --- /dev/null +++ b/indra/newview/llfloaterperformance.h @@ -0,0 +1,102 @@ +/**  + * @file llfloaterperformance.h + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERPERFORMANCE_H +#define LL_LLFLOATERPERFORMANCE_H + +#include "llfloater.h" +#include "lllistcontextmenu.h" + +class LLCharacter; +class LLNameListCtrl; + +class LLFloaterPerformance : public LLFloater +{ +public: +    LLFloaterPerformance(const LLSD& key); +    virtual ~LLFloaterPerformance(); + +    /*virtual*/ BOOL postBuild(); +    /*virtual*/ void draw(); + +    void showSelectedPanel(LLPanel* selected_panel); +    void showMainPanel(); +    void hidePanels(); +    void showAutoadjustmentsPanel(); + +    void detachItem(const LLUUID& item_id); + +    void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + +    void onCustomAction (const LLSD& userdata, const LLUUID& av_id); +    bool isActionChecked(const LLSD& userdata, const LLUUID& av_id); + +private: +    void initBackBtn(LLPanel* panel); +    void populateHUDList(); +    void populateObjectList(); +    void populateNearbyList(); +    void setFPSText(); + +    void onClickAdvanced(); +    void onClickDefaults(); +    void onChangeQuality(const LLSD& data); +    void onClickHideAvatars(); +    void onClickExceptions(); +    void onClickShadows(); +    void onClickAdvancedLighting(); + +    void startAutotune(); +    void stopAutotune(); +    void updateAutotuneCtrls(bool autotune_enabled); +    void enableAutotuneWarning(); + +    void updateMaxRenderTime(); + +    static void changeQualityLevel(const std::string& notif); + +    LLPanel* mMainPanel; +    LLPanel* mNearbyPanel; +    LLPanel* mComplexityPanel; +    LLPanel* mHUDsPanel; +    LLPanel* mSettingsPanel; +    LLPanel* mAutoadjustmentsPanel; +    LLNameListCtrl* mHUDList; +    LLNameListCtrl* mObjectList; +    LLNameListCtrl* mNearbyList; + +    LLButton* mStartAutotuneBtn; +    LLButton* mStopAutotuneBtn; + +    LLListContextMenu* mContextMenu; + +    LLTimer* mUpdateTimer; + +    S32 mNearbyMaxComplexity; + +    boost::signals2::connection	mMaxARTChangedSignal; +}; + +#endif // LL_LLFLOATERPERFORMANCE_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 6909ad513d..9ea49e935f 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -50,6 +50,8 @@  #include "llfloaterreg.h"  #include "llfloaterabout.h"  #include "llfavoritesbar.h" +#include "llfloaterpreferencesgraphicsadvanced.h" +#include "llfloaterperformance.h"  #include "llfloatersidepanelcontainer.h"  #include "llfloaterimsession.h"  #include "llkeyboard.h" @@ -74,7 +76,6 @@  #include "llviewereventrecorder.h"  #include "llviewermessage.h"  #include "llviewerwindow.h" -#include "llviewershadermgr.h"  #include "llviewerthrottle.h"  #include "llvoavatarself.h"  #include "llvotree.h" @@ -98,11 +99,9 @@  #include "lltextbox.h"  #include "llui.h"  #include "llviewerobjectlist.h" -#include "llvoavatar.h"  #include "llvovolume.h"  #include "llwindow.h"  #include "llworld.h" -#include "pipeline.h"  #include "lluictrlfactory.h"  #include "llviewermedia.h"  #include "llpluginclassmedia.h" @@ -115,10 +114,9 @@  #include "llpresetsmanager.h"  #include "llviewercontrol.h"  #include "llpresetsmanager.h" -#include "llfeaturemanager.h" -#include "llviewertexturelist.h"  #include "llsearchableui.h" +#include "llperfstats.h"  const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;  char const* const VISIBILITY_DEFAULT = "default"; @@ -290,6 +288,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	  	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));  	mCommitCallbackRegistrar.add("Pref.RenderExceptions",       boost::bind(&LLFloaterPreference::onClickRenderExceptions, this)); +	mCommitCallbackRegistrar.add("Pref.AutoAdjustments",         boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));  	mCommitCallbackRegistrar.add("Pref.HardwareDefaults",		boost::bind(&LLFloaterPreference::setHardwareDefaults, this));  	mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable",	boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));  	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",	boost::bind(&LLFloaterPreference::updateMaxComplexity, this)); @@ -318,9 +317,12 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));  	gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged,  _2)); +    gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAtmosShaderChange, this));  	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this ); +    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this)); +  	mCommitCallbackRegistrar.add("Pref.ClearLog",				boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));  	mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));  	mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering @@ -487,6 +489,7 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged()  LLFloaterPreference::~LLFloaterPreference()  {  	LLConversationLog::instance().removeObserver(this); +    mComplexityChangedSignal.disconnect();  }  void LLFloaterPreference::draw() @@ -729,13 +732,15 @@ void LLFloaterPreference::onOpen(const LLSD& key)  	LLButton* save_btn = findChild<LLButton>("PrefSaveButton");  	LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");  	LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton"); +    LLButton* auto_adjustments_btn = findChild<LLButton>("AutoAdjustmentsButton"); -	if (load_btn && save_btn && delete_btn && exceptions_btn) +	if (load_btn && save_btn && delete_btn && exceptions_btn && auto_adjustments_btn)  	{  		load_btn->setEnabled(started);  		save_btn->setEnabled(started);  		delete_btn->setEnabled(started);  		exceptions_btn->setEnabled(started); +        auto_adjustments_btn->setEnabled(started);  	}      collectSearchableItems(); @@ -751,33 +756,6 @@ void LLFloaterPreference::onRenderOptionEnable()  	refreshEnabledGraphics();  } -void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable() -{ -	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); -	if (instance) -	{ -		instance->refresh(); -	} - -	refreshEnabledGraphics(); -} - -void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable() -{ -	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); -	if (instance) -	{ -		instance->refresh(); -	} - -	refreshEnabledGraphics(); -} - -void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics() -{ -	refreshEnabledState(); -} -  void LLFloaterPreference::onAvatarImpostorsEnable()  {  	refreshEnabledGraphics(); @@ -811,6 +789,13 @@ void LLFloaterPreference::setHardwareDefaults()  		saveGraphicsPreset(preset_graphic_active);  		saveSettings(); // save here to be able to return to the previous preset by Cancel  	} +    setRecommendedSettings(); +} + +void LLFloaterPreference::setRecommendedSettings() +{ +    resetAutotuneSettings(); +    gSavedSettings.getControl("RenderVSyncEnable")->resetToDefault(true);  	LLFeatureManager::getInstance()->applyRecommendedSettings(); @@ -835,6 +820,28 @@ void LLFloaterPreference::setHardwareDefaults()  	}  } +void LLFloaterPreference::resetAutotuneSettings() +{ +    gSavedSettings.setBOOL("AutoTuneFPS", FALSE); + +    const std::string autotune_settings[] = { +        "AutoTuneLock", +        "KeepAutoTuneLock", +        "TargetFPS", +        "TuningFPSStrategy", +        "AutoTuneImpostorByDistEnabled", +        "AutoTuneImpostorFarAwayDistance" , +        "AutoTuneRenderFarClipMin", +        "AutoTuneRenderFarClipTarget", +        "RenderAvatarMaxART" +    }; + +    for (auto it : autotune_settings) +    { +        gSavedSettings.getControl(it)->resetToDefault(true); +    } +} +  void LLFloaterPreference::getControlNames(std::vector<std::string>& names)  {  	LLView* view = findChild<LLView>("display"); @@ -1212,98 +1219,6 @@ void LLFloaterPreference::refreshEnabledState()  	getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());  } -void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() -{ -	LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections"); -	LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText"); - -	// Reflections -    BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; -	ctrl_reflections->setEnabled(reflections); -	reflections_text->setEnabled(reflections); - -	// Bump & Shiny	 -	LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny"); -	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); -	bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE); -     -	// Avatar Mode -	// Avatar Render Mode -    getChild<LLCheckBoxCtrl>("AvatarCloth")->setEnabled(TRUE); - -    // Vertex Shaders, Global Shader Enable -    // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code -    LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail");   // can be linked with control var -    LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText"); - -    terrain_detail->setEnabled(FALSE); -    terrain_text->setEnabled(FALSE); - -    // WindLight -    LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders"); -    LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail"); -    LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText"); -    ctrl_wind_light->setEnabled(TRUE); -    sky->setEnabled(TRUE); -    sky_text->setEnabled(TRUE); - -    //Deferred/SSAO/Shadows -    LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); -     -    BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && -                        ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) && -                        (ctrl_wind_light->get()) ? TRUE : FALSE; - -    ctrl_deferred->setEnabled(enabled); - -	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); -	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); -	LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); -	LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText"); - -	// note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it -	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); -	 -	ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred")); - -	ctrl_ssao->setEnabled(enabled); -	ctrl_dof->setEnabled(enabled); - -	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"); - -	ctrl_shadow->setEnabled(enabled); -	shadow_text->setEnabled(enabled); - -	// Hardware settings -	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); -	S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); -	S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); -	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value()); -	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value()); - -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || -		!gGLManager.mHasVertexBufferObject) -	{ -		getChildView("vbo")->setEnabled(FALSE); -	} - -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") || -		!gGLManager.mHasVertexBufferObject) -	{ -		getChildView("texture compression")->setEnabled(FALSE); -	} - -	// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance -	LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma"); -	gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders()); -	getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders()); -	getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders()); -	getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")); - -	// now turn off any features that are unavailable -	disableUnavailableSettings(); -} -  // static  void LLAvatarComplexityControls::setIndirectControls()  { @@ -1346,92 +1261,6 @@ void LLAvatarComplexityControls::setIndirectMaxArc()  	gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);  } -void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() -{	 -	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections"); -	LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText"); -	LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth"); -	LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders"); -	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); -	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); -	LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText"); -	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); -	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); -	LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail"); -	LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText"); - -	// disabled windlight -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")) -	{ -		ctrl_wind_light->setEnabled(FALSE); -		ctrl_wind_light->setValue(FALSE); - -		sky->setEnabled(FALSE); -		sky_text->setEnabled(FALSE); - -		//deferred needs windlight, disable deferred -		ctrl_shadows->setEnabled(FALSE); -		ctrl_shadows->setValue(0); -		shadows_text->setEnabled(FALSE); -		 -		ctrl_ssao->setEnabled(FALSE); -		ctrl_ssao->setValue(FALSE); - -		ctrl_dof->setEnabled(FALSE); -		ctrl_dof->setValue(FALSE); - -		ctrl_deferred->setEnabled(FALSE); -		ctrl_deferred->setValue(FALSE); -	} - -	// disabled deferred -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) -	{ -		ctrl_shadows->setEnabled(FALSE); -		ctrl_shadows->setValue(0); -		shadows_text->setEnabled(FALSE); -		 -		ctrl_ssao->setEnabled(FALSE); -		ctrl_ssao->setValue(FALSE); - -		ctrl_dof->setEnabled(FALSE); -		ctrl_dof->setValue(FALSE); - -		ctrl_deferred->setEnabled(FALSE); -		ctrl_deferred->setValue(FALSE); -	} -	 -	// disabled deferred SSAO -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO")) -	{ -		ctrl_ssao->setEnabled(FALSE); -		ctrl_ssao->setValue(FALSE); -	} -	 -	// disabled deferred shadows -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail")) -	{ -		ctrl_shadows->setEnabled(FALSE); -		ctrl_shadows->setValue(0); -		shadows_text->setEnabled(FALSE); -	} - -	// disabled reflections -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail")) -	{ -		ctrl_reflections->setEnabled(FALSE); -		ctrl_reflections->setValue(FALSE); -		reflections_text->setEnabled(FALSE); -	} -	 -	// disabled cloth -	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth")) -	{ -		ctrl_avatar_cloth->setEnabled(FALSE); -		ctrl_avatar_cloth->setValue(FALSE); -	} -} -  void LLFloaterPreference::refresh()  {  	LLPanel::refresh(); @@ -1447,32 +1276,6 @@ void LLFloaterPreference::refresh()      updateClickActionViews();  } -void LLFloaterPreferenceGraphicsAdvanced::refresh() -{ -	getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer)  gSavedSettings.getU32("RenderFSAASamples")); - -	// sliders and their text boxes -	//	mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow"); -	// slider text boxes -	updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail",		true), getChild<LLTextBox>("ObjectMeshDetailText",		true)); -	updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail",	true), getChild<LLTextBox>("FlexibleMeshDetailText",	true)); -	updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail",		true), getChild<LLTextBox>("TreeMeshDetailText",		true)); -	updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail",		true), getChild<LLTextBox>("AvatarMeshDetailText",		true)); -	updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail",	true), getChild<LLTextBox>("AvatarPhysicsDetailText",		true)); -	updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail",	true), getChild<LLTextBox>("TerrainMeshDetailText",		true)); -	updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess",	true), getChild<LLTextBox>("PostProcessText",			true)); -	updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true)); -	updateSliderText(getChild<LLSliderCtrl>("TerrainDetail",		true), getChild<LLTextBox>("TerrainDetailText",			true));	 -    LLAvatarComplexityControls::setIndirectControls(); -	setMaxNonImpostorsText( -        gSavedSettings.getU32("RenderAvatarMaxNonImpostors"), -        getChild<LLTextBox>("IndirectMaxNonImpostorsText", true)); -    LLAvatarComplexityControls::setText( -        gSavedSettings.getU32("RenderAvatarMaxComplexity"), -        getChild<LLTextBox>("IndirectMaxComplexityText", true)); -	refreshEnabledState(); -} -  void LLFloaterPreference::onCommitWindowedMode()  {  	refresh(); @@ -1684,64 +1487,7 @@ void LLFloaterPreference::refreshUI()  	refresh();  } -void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box) -{ -	if (text_box == NULL || ctrl== NULL) -		return; - -	// get range and points when text should change -	F32 value = (F32)ctrl->getValue().asReal(); -	F32 min = ctrl->getMinValue(); -	F32 max = ctrl->getMaxValue(); -	F32 range = max - min; -	llassert(range > 0); -	F32 midPoint = min + range / 3.0f; -	F32 highPoint = min + (2.0f * range / 3.0f); - -	// choose the right text -	if (value < midPoint) -	{ -		text_box->setText(LLTrans::getString("GraphicsQualityLow")); -	}  -	else if (value < highPoint) -	{ -		text_box->setText(LLTrans::getString("GraphicsQualityMid")); -	} -	else -	{ -		text_box->setText(LLTrans::getString("GraphicsQualityHigh")); -	} -} - -void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors() -{ -	// Called when the IndirectMaxNonImpostors control changes -	// Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors -	LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true); -	U32 value = ctrl->getValue().asInteger(); - -	if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value) -	{ -		value=0; -	} -	gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value); -	LLVOAvatar::updateImpostorRendering(value); // make it effective immediately -	setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); -} - -void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box) -{ -	if (0 == value) -	{ -		text_box->setText(LLTrans::getString("no_limit")); -	} -	else -	{ -		text_box->setText(llformat("%d", value)); -	} -} - -void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label) +void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)  {  	// Called when the IndirectMaxComplexity control changes  	// Responsible for fixing the slider label (IndirectMaxComplexityText) and setting RenderAvatarMaxComplexity @@ -1763,10 +1509,10 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu  	}  	gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc); -	setText(max_arc, value_label); +	setText(max_arc, value_label, short_val);  } -void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box) +void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool short_val)  {  	if (0 == value)  	{ @@ -1774,24 +1520,40 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box)  	}  	else  	{ -		text_box->setText(llformat("%d", value)); +        std::string text_value = short_val ? llformat("%d", value / 1000) : llformat("%d", value); +        text_box->setText(text_value);  	}  } +void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val) +{ +    setRenderTimeText((F32)(LLPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val); +} + +void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val) +{ +    if (0 == value) +    { +        text_box->setText(LLTrans::getString("no_limit")); +    } +    else +    { +        text_box->setText(llformat("%.0f", value)); +    } +} +  void LLFloaterPreference::updateMaxComplexity()  {  	// Called when the IndirectMaxComplexity control changes      LLAvatarComplexityControls::updateMax(          getChild<LLSliderCtrl>("IndirectMaxComplexity"),          getChild<LLTextBox>("IndirectMaxComplexityText")); +} -    LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced"); -    if (floater_graphics_advanced) -    { -        LLAvatarComplexityControls::updateMax( -            floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"), -            floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText")); -    } +void LLFloaterPreference::updateComplexityText() +{ +    LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), +        getChild<LLTextBox>("IndirectMaxComplexityText", true));  }  bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map) @@ -1833,22 +1595,6 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map      return true;  } -void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() -{ -	// Called when the IndirectMaxComplexity control changes -    LLAvatarComplexityControls::updateMax( -        getChild<LLSliderCtrl>("IndirectMaxComplexity"), -        getChild<LLTextBox>("IndirectMaxComplexityText")); - -    LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); -    if (floater_preferences) -    { -        LLAvatarComplexityControls::updateMax( -            floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"), -            floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText")); -    } -} -  void LLFloaterPreference::onChangeMaturity()  {  	U8 sim_access = gSavedSettings.getU32("PreferredMaturity"); @@ -1953,6 +1699,15 @@ void LLFloaterPreference::onClickRenderExceptions()      LLFloaterReg::showInstance("avatar_render_settings");  } +void LLFloaterPreference::onClickAutoAdjustments() +{ +    LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance"); +    if (performance_floater) +    { +        performance_floater->showAutoadjustmentsPanel(); +    } +} +  void LLFloaterPreference::onClickAdvanced()  {  	LLFloaterReg::showInstance("prefs_graphics_advanced"); @@ -1975,6 +1730,22 @@ void LLFloaterPreference::onClickActionChange()      updateClickActionControls();  } +void LLFloaterPreference::onAtmosShaderChange() +{ +    LLCheckBoxCtrl* ctrl_alm = getChild<LLCheckBoxCtrl>("UseLightShaders"); +    if(ctrl_alm) +    { +        //Deferred/SSAO/Shadows +        BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump"); +        BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); +        BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +                        bumpshiny && +                        shaders; + +        ctrl_alm->setEnabled(enabled); +    } +} +  void LLFloaterPreference::onClickPermsDefault()  {  	LLFloaterReg::showInstance("perms_default"); @@ -3295,18 +3066,6 @@ void LLPanelPreferenceControls::onCancelKeyBind()      pControlsTable->deselectAllItems();  } -LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key) -	: LLFloater(key) -{ -    mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate",            boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this)); -	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this)); -	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this)); -} - -LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced() -{ -} -  LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)  	: LLFloater(key),  	  mSocksSettingsDirty(false) @@ -3316,41 +3075,6 @@ LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)  	mCommitCallbackRegistrar.add("Proxy.Change",            boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));  } -BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild() -{ -    // Don't do this on Mac as their braindead GL versioning -    // sets this when 8x and 16x are indeed available -    // -#if !LL_DARWIN -    if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) -    { //remove FSAA settings above "4x" -        LLComboBox* combo = getChild<LLComboBox>("fsaa"); -        combo->remove("8x"); -        combo->remove("16x"); -    } -	 -	LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI"); -	use_HiDPI->setVisible(FALSE); -#endif - -    return TRUE; -} - -void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key) -{ -    refresh(); -} - -void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting) -{ -	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); -	if (instance) -	{ -		instance->cancel(); -	} -	updateMaxComplexity(); -} -  LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()  {  } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index e312c35135..6b23c4d4cd 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -109,9 +109,10 @@ public:  	void updateClickActionViews();      void updateSearchableItems(); +    void		onBtnOK(const LLSD& userdata); +    void		onBtnCancel(const LLSD& userdata); +  protected:	 -	void		onBtnOK(const LLSD& userdata); -	void		onBtnCancel(const LLSD& userdata);  	void		onClickClearCache();			// Clear viewer texture cache, file cache on next startup  	void		onClickBrowserClearCache();		// Clear web history and caches as well as viewer caches above @@ -138,6 +139,8 @@ protected:  	// updates click/double-click action keybindngs depending on view values  	void updateClickActionControls(); +    void onAtmosShaderChange(); +  public:  	// This function squirrels away the current values of the controls so that  	// cancel() can restore them.	 @@ -187,6 +190,7 @@ public:  	void onClickAutoReplace();  	void onClickSpellChecker();  	void onClickRenderExceptions(); +	void onClickAutoAdjustments();  	void onClickAdvanced();  	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);  	void getUIColor(LLUICtrl* ctrl, const LLSD& param); @@ -197,12 +201,16 @@ public:  	void saveCameraPreset(std::string& preset);  	void saveGraphicsPreset(std::string& preset); +    void setRecommendedSettings(); +    void resetAutotuneSettings(); +  private:  	void onDeleteTranscripts();  	void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);  	void updateDeleteTranscriptsButton();  	void updateMaxComplexity(); +    void updateComplexityText();  	static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map);  	static std::string sSkin; @@ -224,6 +232,8 @@ private:  	std::unique_ptr< ll::prefs::SearchData > mSearchData;  	bool mSearchDataDirty; +    boost::signals2::connection	mComplexityChangedSignal; +  	void onUpdateFilterTerm( bool force = false );  	void collectSearchableItems();      void filterIgnorableNotifications(); @@ -353,37 +363,13 @@ private:  	S32 mEditingMode;  }; -class LLFloaterPreferenceGraphicsAdvanced : public LLFloater -{ -  public:  -	LLFloaterPreferenceGraphicsAdvanced(const LLSD& key); -	~LLFloaterPreferenceGraphicsAdvanced(); -	/*virtual*/ BOOL postBuild(); -	void onOpen(const LLSD& key); -	void onClickCloseBtn(bool app_quitting); -	void disableUnavailableSettings(); -	void refreshEnabledGraphics(); -	void refreshEnabledState(); -	void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box); -	void updateMaxNonImpostors(); -	void setMaxNonImpostorsText(U32 value, LLTextBox* text_box); -	void updateMaxComplexity(); -	void setMaxComplexityText(U32 value, LLTextBox* text_box); -	static void setIndirectControls(); -	static void setIndirectMaxNonImpostors(); -	static void setIndirectMaxArc(); -	void refresh(); -	// callback for when client modifies a render option -	void onRenderOptionEnable(); -    void onAdvancedAtmosphericsEnable(); -	LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced); -}; -  class LLAvatarComplexityControls  {    public:  -	static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label); -	static void setText(U32 value, LLTextBox* text_box); +	static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false); +	static void setText(U32 value, LLTextBox* text_box, bool short_val = false); +	static void updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false); +	static void setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false);  	static void setIndirectControls();  	static void setIndirectMaxNonImpostors();  	static void setIndirectMaxArc(); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp new file mode 100644 index 0000000000..a976b97831 --- /dev/null +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -0,0 +1,479 @@ +/**  + * @file llfloaterpreferencesgraphicsadvanced.cpp + * @brief floater for adjusting camera position + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterpreferencesgraphicsadvanced.h" + +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfeaturemanager.h" +#include "llfloaterpreference.h" +#include "llfloaterreg.h" +#include "llnotificationsutil.h" +#include "llsliderctrl.h" +#include "lltextbox.h" +#include "lltrans.h" +#include "llviewershadermgr.h" +#include "llviewertexturelist.h" +#include "llvoavatar.h" +#include "pipeline.h" + + +LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key) +    : LLFloater(key) +{ +    mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate",            boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this)); +    mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this)); +    mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,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() +{ +    mComplexityChangedSignal.disconnect(); +    mLODFactorChangedSignal.disconnect(); +} + +BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild() +{ +    // Don't do this on Mac as their braindead GL versioning +    // sets this when 8x and 16x are indeed available +    // +#if !LL_DARWIN +    if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) +    { //remove FSAA settings above "4x" +        LLComboBox* combo = getChild<LLComboBox>("fsaa"); +        combo->remove("8x"); +        combo->remove("16x"); +    } + +    LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI"); +    use_HiDPI->setVisible(FALSE); +#endif + +    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));  +    mLODFactorChangedSignal = gSavedSettings.getControl("RenderVolumeLODFactor")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText, this)); +    return TRUE; +} + +void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key) +{ +    refresh(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting) +{ +    LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->cancel(); +    } +    updateMaxComplexity(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable() +{ +    LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->refresh(); +    } + +    refreshEnabledGraphics(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable() +{ +    LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->refresh(); +    } + +    refreshEnabledGraphics(); +} + +void LLFloaterPreferenceGraphicsAdvanced::refresh() +{ +    getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer)  gSavedSettings.getU32("RenderFSAASamples")); + +    // sliders and their text boxes +    //	mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow"); +    // slider text boxes +    updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail",		true), getChild<LLTextBox>("ObjectMeshDetailText",		true)); +    updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail",	true), getChild<LLTextBox>("FlexibleMeshDetailText",	true)); +    updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail",		true), getChild<LLTextBox>("TreeMeshDetailText",		true)); +    updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail",		true), getChild<LLTextBox>("AvatarMeshDetailText",		true)); +    updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail",	true), getChild<LLTextBox>("AvatarPhysicsDetailText",		true)); +    updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail",	true), getChild<LLTextBox>("TerrainMeshDetailText",		true)); +    updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess",	true), getChild<LLTextBox>("PostProcessText",			true)); +    updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true)); +    updateSliderText(getChild<LLSliderCtrl>("TerrainDetail",		true), getChild<LLTextBox>("TerrainDetailText",			true));	 +    LLAvatarComplexityControls::setIndirectControls(); +    setMaxNonImpostorsText( +        gSavedSettings.getU32("RenderAvatarMaxNonImpostors"), +        getChild<LLTextBox>("IndirectMaxNonImpostorsText", true)); +    LLAvatarComplexityControls::setText( +        gSavedSettings.getU32("RenderAvatarMaxComplexity"), +        getChild<LLTextBox>("IndirectMaxComplexityText", true)); +    refreshEnabledState(); +} + +void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics() +{ +    refreshEnabledState(); +} + +void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() +{ +    // Called when the IndirectMaxComplexity control changes +    LLAvatarComplexityControls::updateMax( +        getChild<LLSliderCtrl>("IndirectMaxComplexity"), +        getChild<LLTextBox>("IndirectMaxComplexityText")); +} + +void LLFloaterPreferenceGraphicsAdvanced::updateComplexityText() +{ +    LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), +        getChild<LLTextBox>("IndirectMaxComplexityText", true)); +} + +void LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText() +{ +    updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail", true), getChild<LLTextBox>("ObjectMeshDetailText", true)); +} + +void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box) +{ +    if (text_box == NULL || ctrl== NULL) +        return; + +    // get range and points when text should change +    F32 value = (F32)ctrl->getValue().asReal(); +    F32 min = ctrl->getMinValue(); +    F32 max = ctrl->getMaxValue(); +    F32 range = max - min; +    llassert(range > 0); +    F32 midPoint = min + range / 3.0f; +    F32 highPoint = min + (2.0f * range / 3.0f); + +    // choose the right text +    if (value < midPoint) +    { +        text_box->setText(LLTrans::getString("GraphicsQualityLow")); +    }  +    else if (value < highPoint) +    { +        text_box->setText(LLTrans::getString("GraphicsQualityMid")); +    } +    else +    { +        text_box->setText(LLTrans::getString("GraphicsQualityHigh")); +    } +} + +void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors() +{ +    // Called when the IndirectMaxNonImpostors control changes +    // Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors +    LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true); +    U32 value = ctrl->getValue().asInteger(); + +    if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value) +    { +        value=0; +    } +    gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value); +    LLVOAvatar::updateImpostorRendering(value); // make it effective immediately +    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) +    { +        text_box->setText(LLTrans::getString("no_limit")); +    } +    else +    { +        text_box->setText(llformat("%d", value)); +    } +} + +void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() +{	 +    LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections"); +    LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText"); +    LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); +    LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth"); +    LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders"); +    LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); +    LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); +    LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText"); +    LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); +    LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); +    LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail"); +    LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText"); + +    // disabled windlight +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")) +    { +        ctrl_wind_light->setEnabled(FALSE); +        ctrl_wind_light->setValue(FALSE); + +        sky->setEnabled(FALSE); +        sky_text->setEnabled(FALSE); + +        //deferred needs windlight, disable deferred +        ctrl_shadows->setEnabled(FALSE); +        ctrl_shadows->setValue(0); +        shadows_text->setEnabled(FALSE); + +        ctrl_ssao->setEnabled(FALSE); +        ctrl_ssao->setValue(FALSE); + +        ctrl_dof->setEnabled(FALSE); +        ctrl_dof->setValue(FALSE); + +        ctrl_deferred->setEnabled(FALSE); +        ctrl_deferred->setValue(FALSE); +    } + +    // disabled deferred +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) +    { +        ctrl_shadows->setEnabled(FALSE); +        ctrl_shadows->setValue(0); +        shadows_text->setEnabled(FALSE); + +        ctrl_ssao->setEnabled(FALSE); +        ctrl_ssao->setValue(FALSE); + +        ctrl_dof->setEnabled(FALSE); +        ctrl_dof->setValue(FALSE); + +        ctrl_deferred->setEnabled(FALSE); +        ctrl_deferred->setValue(FALSE); +    } + +    // disabled deferred SSAO +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO")) +    { +        ctrl_ssao->setEnabled(FALSE); +        ctrl_ssao->setValue(FALSE); +    } + +    // disabled deferred shadows +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail")) +    { +        ctrl_shadows->setEnabled(FALSE); +        ctrl_shadows->setValue(0); +        shadows_text->setEnabled(FALSE); +    } + +    // disabled reflections +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail")) +    { +        ctrl_reflections->setEnabled(FALSE); +        ctrl_reflections->setValue(FALSE); +        reflections_text->setEnabled(FALSE); +    } + +    // disabled av +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP")) +    { +        ctrl_avatar_vp->setEnabled(FALSE); +        ctrl_avatar_vp->setValue(FALSE); + +        ctrl_avatar_cloth->setEnabled(FALSE); +        ctrl_avatar_cloth->setValue(FALSE); + +        //deferred needs AvatarVP, disable deferred +        ctrl_shadows->setEnabled(FALSE); +        ctrl_shadows->setValue(0); +        shadows_text->setEnabled(FALSE); + +        ctrl_ssao->setEnabled(FALSE); +        ctrl_ssao->setValue(FALSE); + +        ctrl_dof->setEnabled(FALSE); +        ctrl_dof->setValue(FALSE); + +        ctrl_deferred->setEnabled(FALSE); +        ctrl_deferred->setValue(FALSE); +    } + +    // disabled cloth +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth")) +    { +        ctrl_avatar_cloth->setEnabled(FALSE); +        ctrl_avatar_cloth->setValue(FALSE); +    } +} + +void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() +{ +    LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections"); +    LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText"); + +    // Reflections +    BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; +    ctrl_reflections->setEnabled(reflections); +    reflections_text->setEnabled(reflections); + +    // Bump & Shiny	 +    LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny"); +    bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); +    bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE); + +    // Avatar Mode +    // Enable Avatar Shaders +    LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); +    // Avatar Render Mode +    LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth"); + +    bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"); +    if (LLViewerShaderMgr::sInitialized) +    { +        S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel; +        avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE; +    } + +    ctrl_avatar_vp->setEnabled(avatar_vp_enabled); + +    if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE) +    { +        ctrl_avatar_cloth->setEnabled(FALSE); +    }  +    else +    { +        ctrl_avatar_cloth->setEnabled(TRUE); +    } + +    // Vertex Shaders, Global Shader Enable +    // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code +    LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail");   // can be linked with control var +    LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText"); + +    terrain_detail->setEnabled(FALSE); +    terrain_text->setEnabled(FALSE); + +    // WindLight +    LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders"); +    LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail"); +    LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText"); +    ctrl_wind_light->setEnabled(TRUE); +    sky->setEnabled(TRUE); +    sky_text->setEnabled(TRUE); + +    //Deferred/SSAO/Shadows +    LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); + +    BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +        ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) && +        (ctrl_wind_light->get()) ? TRUE : FALSE; + +    ctrl_deferred->setEnabled(enabled); + +    LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); +    LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); +    LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); +    LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText"); + +    // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it +    enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); + +    ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred")); + +    ctrl_ssao->setEnabled(enabled); +    ctrl_dof->setEnabled(enabled); + +    enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"); + +    ctrl_shadow->setEnabled(enabled); +    shadow_text->setEnabled(enabled); + +    // Hardware settings +    F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); +    S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); +    S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); +    getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value()); +    getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value()); + +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || +        !gGLManager.mHasVertexBufferObject) +    { +        getChildView("vbo")->setEnabled(FALSE); +    } + +    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") || +        !gGLManager.mHasVertexBufferObject) +    { +        getChildView("texture compression")->setEnabled(FALSE); +    } + +    // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance +    LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma"); +    gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders()); +    getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders()); +    getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders()); +    getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")); + +    // now turn off any features that are unavailable +    disableUnavailableSettings(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onBtnOK(const LLSD& userdata) +{ +    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->onBtnOK(userdata); +    } +} + +void LLFloaterPreferenceGraphicsAdvanced::onBtnCancel(const LLSD& userdata) +{ +    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences"); +    if (instance) +    { +        instance->onBtnCancel(userdata); +    } +} diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h new file mode 100644 index 0000000000..2c92f3dbf1 --- /dev/null +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h @@ -0,0 +1,68 @@ +/**  + * @file llfloaterpreferencesgraphicsadvanced.h + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LLFLOATERPREFERENCEGRAPHICSADVANCED_H +#define LLFLOATERPREFERENCEGRAPHICSADVANCED_H + +#include "llcontrol.h" +#include "llfloater.h" + +class LLSliderCtrl; +class LLTextBox; + +class LLFloaterPreferenceGraphicsAdvanced : public LLFloater +{ +public:  +    LLFloaterPreferenceGraphicsAdvanced(const LLSD& key); +    ~LLFloaterPreferenceGraphicsAdvanced(); +    /*virtual*/ BOOL postBuild(); +    void onOpen(const LLSD& key); +    void onClickCloseBtn(bool app_quitting); +    void disableUnavailableSettings(); +    void refreshEnabledGraphics(); +    void refreshEnabledState(); +    void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box); +    void updateMaxNonImpostors(); +    void updateIndirectMaxNonImpostors(const LLSD& newvalue); +    void setMaxNonImpostorsText(U32 value, LLTextBox* text_box); +    void updateMaxComplexity(); +    void updateComplexityText(); +    void updateObjectMeshDetailText(); +    void refresh(); +    // callback for when client modifies a render option +    void onRenderOptionEnable(); +    void onAdvancedAtmosphericsEnable(); +    LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced); + +protected:	 +    void		onBtnOK(const LLSD& userdata); +    void		onBtnCancel(const LLSD& userdata); + +    boost::signals2::connection	mComplexityChangedSignal; +    boost::signals2::connection	mLODFactorChangedSignal; +}; + +#endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H + diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 25e9ade7df..03c1b6f631 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -990,6 +990,7 @@ private:  //-----------------------------------------------------------------------------  // gpu_benchmark() +//  returns measured memory bandwidth of GPU in gigabytes per second  //-----------------------------------------------------------------------------  F32 gpu_benchmark()  { diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 8058faa5c7..d7d6fa1893 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -67,7 +67,9 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)  	mNameColumn(p.name_column.column_name),  	mAllowCallingCardDrop(p.allow_calling_card_drop),  	mShortNames(p.short_names), -	mPendingLookupsRemaining(0) +	mPendingLookupsRemaining(0), +    mHoverIconName("Info_Small"), +    mNameListType(INDIVIDUAL)  {}  // public @@ -134,7 +136,12 @@ BOOL LLNameListCtrl::handleDragAndDrop(  void LLNameListCtrl::showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience)  { -	if(is_experience) +    if (isSpecialType()) +    { +        mIconClickedSignal(avatar_id); +        return; +    } +    if(is_experience)  	{  		LLFloaterReg::showInstance("experience_profile", avatar_id, true);  		return; @@ -215,14 +222,16 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)  	S32 column_index = getColumnIndexFromOffset(x);  	LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));  	LLFloater* floater = gFloaterView->getParentFloater(this); -	if (floater  + + +    if (floater   		&& floater->isFrontmost()  		&& hit_item -		&& column_index == mNameColumnIndex) +		&& ((column_index == mNameColumnIndex) || isSpecialType()))  	{ -		// ...this is the column with the avatar name -		LLUUID avatar_id = hit_item->getUUID(); -		if (avatar_id.notNull()) +        // ...this is the column with the avatar name +		LLUUID item_id = isSpecialType() ? hit_item->getSpecialID() : hit_item->getUUID(); +		if (item_id.notNull())  		{  			// ...valid avatar id @@ -230,13 +239,13 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)  			if (hit_cell)  			{  				S32 row_index = getItemIndex(hit_item); -				LLRect cell_rect = getCellRect(row_index, column_index); +				LLRect cell_rect = getCellRect(row_index, isSpecialType() ? getNumColumns() - 1 : column_index);  				// Convert rect local to screen coordinates  				LLRect sticky_rect;  				localRectToScreen(cell_rect, &sticky_rect);  				// Spawn at right side of cell -				LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small"); +				LLPointer<LLUIImage> icon = LLUI::getUIImage(mHoverIconName);  				S32 screenX = sticky_rect.mRight - info_icon_size;  				S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2;  				LLCoordGL pos(screenX, screenY); @@ -250,7 +259,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)  					LLToolTip::Params params;  					params.background_visible(false); -					params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience)); +					params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, item_id, is_group, is_experience));  					params.delay_time(0.0f);		// spawn instantly on hover  					params.image(icon);  					params.message(""); @@ -340,6 +349,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(  	// use supplied name by default  	std::string fullname = name_item.name; +  	switch(name_item.target)  	{  	case GROUP: @@ -358,8 +368,10 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(  		}  		break;  	case SPECIAL: -		// just use supplied name -		break; +        { +        item->setSpecialID(name_item.special_id()); +        return item; +        }  	case INDIVIDUAL:  		{  			LLAvatarName av_name; @@ -370,7 +382,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(  			else if (LLAvatarNameCache::get(id, &av_name))  			{  				if (mShortNames) -					fullname = av_name.getDisplayName(); +					fullname = av_name.getDisplayName(true);  				else  					fullname = av_name.getCompleteName();  			} @@ -440,7 +452,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)  	for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)  	{  		LLScrollListItem* item = *it; -		if (item->getUUID() == agent_id) +        LLUUID cur_id = isSpecialType() ? dynamic_cast<LLNameListItem*>(item)->getSpecialID() : item->getUUID(); +        if (cur_id == agent_id)  		{  			idx = getItemIndex(item);  			break; @@ -471,6 +484,34 @@ LLScrollListItem* LLNameListCtrl::getNameItemByAgentId(const LLUUID& agent_id)  	return NULL;  } +void LLNameListCtrl::selectItemBySpecialId(const LLUUID& special_id) +{ +    if (special_id.isNull()) +    { +        return; +    } + +    for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++) +    { +        LLNameListItem* item = dynamic_cast<LLNameListItem*>(*it); +        if (item && item->getSpecialID() == special_id) +        { +            item->setSelected(TRUE); +            break; +        } +    } +} + +LLUUID LLNameListCtrl::getSelectedSpecialId() +{ +    LLNameListItem* item = dynamic_cast<LLNameListItem*>(getFirstSelected()); +    if(item) +    { +        return item->getSpecialID(); +    } +    return LLUUID(); +} +  void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,  									   const LLAvatarName& av_name,  									   std::string suffix, diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 5dd5da5892..4a4bd4ba09 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -46,6 +46,8 @@ public:  	void setIsGroup(bool is_group) { mIsGroup = is_group; }  	bool isExperience() const { return mIsExperience; }  	void setIsExperience(bool is_experience) { mIsExperience = is_experience; } +    void setSpecialID(const LLUUID& special_id) { mSpecialID = special_id; } +    const LLUUID& getSpecialID() const { return mSpecialID; }  protected:  	friend class LLNameListCtrl; @@ -68,6 +70,8 @@ protected:  private:  	bool mIsGroup;  	bool mIsExperience; + +    LLUUID mSpecialID;  }; @@ -95,10 +99,12 @@ public:  	{  		Optional<std::string>				name;  		Optional<ENameType, NameTypeNames>	target; +        Optional<LLUUID>                    special_id;  		NameItem()  		:	name("name"), -			target("target", INDIVIDUAL) +			target("target", INDIVIDUAL), +            special_id("special_id", LLUUID())  		{}  	}; @@ -156,6 +162,9 @@ public:  	LLScrollListItem* getNameItemByAgentId(const LLUUID& agent_id); +    void selectItemBySpecialId(const LLUUID& special_id); +    LLUUID getSelectedSpecialId(); +  	// LLView interface  	/*virtual*/ BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask,  									  BOOL drop, EDragAndDropType cargo_type, void *cargo_data, @@ -170,7 +179,14 @@ public:  	/*virtual*/ void updateColumns(bool force_update);  	/*virtual*/ void mouseOverHighlightNthItem( S32 index ); +      /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + +    bool isSpecialType() { return (mNameListType == SPECIAL); } + +    void setNameListType(e_name_type type) { mNameListType = type; } +    void setHoverIconName(std::string icon_name) { mHoverIconName = icon_name; } +  private:  	void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);  	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item); @@ -187,6 +203,11 @@ private:  	S32 mPendingLookupsRemaining;  	namelist_complete_signal_t mNameListCompleteSignal; + +    std::string     mHoverIconName; +    e_name_type     mNameListType; + +    boost::signals2::signal<void(const LLUUID &)> mIconClickedSignal;  public:  	boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback)  @@ -194,6 +215,10 @@ public:  		return mNameListCompleteSignal.connect(onNameListCompleteCallback);   	} +    boost::signals2::connection setIconClickedCallback(boost::function<void(const LLUUID &)> cb)  +    {  +        return mIconClickedSignal.connect(cb);  +    }  }; diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp index 23e4fa8887..f6e501f147 100644 --- a/indra/newview/llpanelpresetspulldown.cpp +++ b/indra/newview/llpanelpresetspulldown.cpp @@ -34,6 +34,7 @@  #include "llbutton.h"  #include "lltabcontainer.h"  #include "llfloater.h" +#include "llfloaterperformance.h"  #include "llfloaterreg.h"  #include "llpresetsmanager.h"  #include "llsliderctrl.h" @@ -50,6 +51,7 @@ LLPanelPresetsPulldown::LLPanelPresetsPulldown()  	mHoverTimer.stop();  	mCommitCallbackRegistrar.add("Presets.GoGraphicsPrefs", boost::bind(&LLPanelPresetsPulldown::onGraphicsButtonClick, this, _2)); +    mCommitCallbackRegistrar.add("Presets.GoAutofpsPrefs", boost::bind(&LLPanelPresetsPulldown::onAutofpsButtonClick, this, _2));  	mCommitCallbackRegistrar.add("Presets.RowClick", boost::bind(&LLPanelPresetsPulldown::onRowClick, this, _2));  	buildFromFile( "panel_presets_pulldown.xml"); @@ -157,3 +159,13 @@ void LLPanelPresetsPulldown::onGraphicsButtonClick(const LLSD& user_data)  		}  	}  } + +void LLPanelPresetsPulldown::onAutofpsButtonClick(const LLSD& user_data) +{ +    setVisible(FALSE); +    LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance"); +    if (performance_floater) +    { +        performance_floater->showAutoadjustmentsPanel(); +    } +} diff --git a/indra/newview/llpanelpresetspulldown.h b/indra/newview/llpanelpresetspulldown.h index c0d32b9b21..79bd6886b1 100644 --- a/indra/newview/llpanelpresetspulldown.h +++ b/indra/newview/llpanelpresetspulldown.h @@ -41,6 +41,7 @@ class LLPanelPresetsPulldown : public LLPanelPulldown   private:  	void onGraphicsButtonClick(const LLSD& user_data); +    void onAutofpsButtonClick(const LLSD& user_data);  	void onRowClick(const LLSD& user_data);  	std::list<std::string> mPresetNames; diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp new file mode 100644 index 0000000000..7ff363c3c1 --- /dev/null +++ b/indra/newview/llperfstats.cpp @@ -0,0 +1,548 @@ +/**  +* @file llperfstats.cpp +* @brief Statistics collection to support autotune and perf flaoter. +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llperfstats.h" +#include "llcontrol.h" +#include "pipeline.h" +#include "llagentcamera.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llwindow.h" +#include "llworld.h" +#include <llthread.h> + +extern LLControlGroup gSavedSettings; + +namespace LLPerfStats +{ +    std::atomic<int64_t> tunedAvatars{0}; +    std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features +    bool belowTargetFPS{false}; +    U32 lastGlobalPrefChange{0};  +    U32 lastSleepedFrame{0}; +    U64 meanFrameTime{0}; +    std::mutex bufferToggleLock{}; + +    F64 cpu_hertz{0.0}; +    U32 vsync_max_fps{60}; + +    Tunables tunables; + +    std::atomic<int> 	StatsRecorder::writeBuffer{0}; +    bool 	            StatsRecorder::collectionEnabled{true}; +    LLUUID              StatsRecorder::focusAv{LLUUID::null}; +    bool                StatsRecorder::autotuneInit{false}; +	std::array<StatsRecorder::StatsTypeMatrix,2>  StatsRecorder::statsDoubleBuffer{ {} }; +    std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} }; +    std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} }; + +    void Tunables::applyUpdates() +    { +        assert_main_thread(); +        // these following variables are proxies for pipeline statics we do not need a two way update (no llviewercontrol handler) +        if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImpostors); }; +        if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); }; +        if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); }; +        if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipMin", userMinDrawDistance); }; +        if( tuningFlag & UserTargetDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipTarget", userTargetDrawDistance); }; +        if( tuningFlag & UserImpostorDistance ){ gSavedSettings.setF32("AutoTuneImpostorFarAwayDistance", userImpostorDistance); }; +        if( tuningFlag & UserImpostorDistanceTuningEnabled ){ gSavedSettings.setBOOL("AutoTuneImpostorByDistEnabled", userImpostorDistanceTuningEnabled); }; +        if( tuningFlag & UserFPSTuningStrategy ){ gSavedSettings.setU32("TuningFPSStrategy", userFPSTuningStrategy); }; +        if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("AutoTuneFPS", userAutoTuneEnabled); }; +        if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("AutoTuneLock", userAutoTuneLock); }; +        if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("TargetFPS", userTargetFPS); }; +        if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("UserTargetReflections", userTargetReflections); }; +        // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value +        if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("RenderAvatarMaxART", userARTCutoffSliderValue); }; +        resetChanges(); +    } + +    void Tunables::updateRenderCostLimitFromSettings() +    { +        assert_main_thread(); +        const auto newval = gSavedSettings.getF32("RenderAvatarMaxART"); +        if(newval < log10(LLPerfStats::ART_UNLIMITED_NANOS/1000)) +        { +            LLPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000; +        } +        else +        { +            LLPerfStats::renderAvatarMaxART_ns = 0; +        } +    } + +    // static  +    void Tunables::updateSettingsFromRenderCostLimit() +    { +        if( userARTCutoffSliderValue != log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) ) +        { +            if( LLPerfStats::renderAvatarMaxART_ns != 0 ) +            { +                updateUserARTCutoffSlider(log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) ); +            } +            else +            { +                updateUserARTCutoffSlider(log10( (F32)LLPerfStats::ART_UNLIMITED_NANOS/1000 ) ); +            } +        }         +    } + +    void Tunables::initialiseFromSettings() +    { +        assert_main_thread(); +        // the following variables are two way and have "push" in llviewercontrol  +        LLPerfStats::tunables.userMinDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipMin"); +        LLPerfStats::tunables.userTargetDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipTarget"); +        LLPerfStats::tunables.userImpostorDistance = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance"); +        LLPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled"); +        LLPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("TuningFPSStrategy"); +        LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS"); +        LLPerfStats::tunables.vsyncEnabled = gSavedSettings.getBOOL("RenderVSyncEnable"); +        LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections"); + +        LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock") && gSavedSettings.getU32("KeepAutoTuneLock"); + +        if(gSavedSettings.getBOOL("AutoTuneLock") && !gSavedSettings.getU32("KeepAutoTuneLock")) +        { +            gSavedSettings.setBOOL("AutoTuneLock", FALSE); +        } + +        LLPerfStats::tunables.userAutoTuneEnabled = LLPerfStats::tunables.userAutoTuneLock; + +        if (LLPerfStats::tunables.userAutoTuneEnabled && !gSavedSettings.getBOOL("AutoTuneFPS")) +        { +            gSavedSettings.setBOOL("AutoTuneFPS", TRUE); +        } + +        // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value +        updateRenderCostLimitFromSettings(); +        resetChanges(); +    } + +    StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run) +    { +        // create a queue +        // create a thread to consume from the queue +        tunables.initialiseFromSettings(); +        LLPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond(); +        LLPerfStats::vsync_max_fps = gViewerWindow->getWindow()->getRefreshRate(); +        t.detach(); +    } + +    // static +    void StatsRecorder::toggleBuffer() +    { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +        using ST = StatType_t; + +        bool unreliable{false}; +        LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME); +        auto& sceneStats = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null]; +        auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null]; + +        static constexpr std::initializer_list<StatType_t> sceneStatsToAvg = { +            StatType_t::RENDER_FRAME,  +            StatType_t::RENDER_DISPLAY,  +            StatType_t::RENDER_HUDS, +            StatType_t::RENDER_UI, +            StatType_t::RENDER_SWAP, +            // RENDER_LFS, +            // RENDER_MESHREPO, +            StatType_t::RENDER_IDLE }; + +        static constexpr std::initializer_list<StatType_t> avatarStatsToAvg = { +            StatType_t::RENDER_GEOMETRY,  +            StatType_t::RENDER_SHADOWS,  +            StatType_t::RENDER_COMBINED, +            StatType_t::RENDER_IDLE }; + + +        if( /*sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] != 0 ||*/ sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] != 0 ) +        { +            unreliable = true; +            //lastStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)]; +            lastStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)]; +            lastStats[static_cast<size_t>(StatType_t::RENDER_FRAME)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FRAME)]; //  bring over the total frame render time to deal with region crossing overlap issues +        } + +        if(!unreliable) +        { +            // only use these stats when things are reliable.  + +            for(auto & statEntry : sceneStatsToAvg) +            { +                auto avg = lastStats[static_cast<size_t>(statEntry)]; +                auto val = sceneStats[static_cast<size_t>(statEntry)]; +                sceneStats[static_cast<size_t>(statEntry)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS); +                // LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL; +            } +        } +// Allow attachment times etc to update even when FPS limited or sleeping. +        auto& statsMap = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)]; +        for(auto& stat_entry : statsMap) +        { +            auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)]; +            if(val > SMOOTHING_PERIODS){ +                auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)]; +                stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS); +            } +        } + + +        auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)]; +        for(auto& stat_entry : statsMapAv) +        { +            for(auto& stat : avatarStatsToAvg) +            { +                auto val = stat_entry.second[static_cast<size_t>(stat)]; +                if(val > SMOOTHING_PERIODS) +                { +                    auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_AVATAR)][stat_entry.first][static_cast<size_t>(stat)]; +                    stat_entry.second[static_cast<size_t>(stat)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS); +                } +            } +        } + +        // swap the buffers +        if(enabled()) +        { +            std::lock_guard<std::mutex> lock{bufferToggleLock}; +            writeBuffer ^= 1; +        }; // note we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display.  + +        // clean the write maps in all cases. +        auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer]; +        for(auto& statsMapByType : statsTypeMatrix) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("Clear stats maps"); +            for(auto& stat_entry : statsMapByType) +            { +                std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0); +            } +            statsMapByType.clear(); +        } +        for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("clear max/sum"); +            max[writeBuffer][i].fill(0); +            sum[writeBuffer][i].fill(0); +        } + +        // and now adjust the proxy vars so that the main thread can adjust the visuals. +        if(autotuneInit && tunables.userAutoTuneEnabled) +        { +            updateAvatarParams(); +        } +    } + +    // clear buffers when we change region or need a hard reset. +    // static  +    void StatsRecorder::clearStatsBuffers() +    { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +        using ST = StatType_t; + +        auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer]; +        for(auto& statsMap : statsTypeMatrix) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("Clear stats maps"); +            for(auto& stat_entry : statsMap) +            { +                std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0); +            } +            statsMap.clear(); +        } +        for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("clear max/sum"); +            max[writeBuffer][i].fill(0); +            sum[writeBuffer][i].fill(0); +        } +        // swap the clean buffers in +        if(enabled()) +        { +            std::lock_guard<std::mutex> lock{bufferToggleLock}; +            writeBuffer ^= 1; +        };  +        // repeat before we start processing new stuff +        for(auto& statsMap : statsTypeMatrix) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("Clear stats maps"); +            for(auto& stat_entry : statsMap) +            { +                std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0); +            } +            statsMap.clear(); +        } +        for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("clear max/sum"); +            max[writeBuffer][i].fill(0); +            sum[writeBuffer][i].fill(0); +        } +    } + +    //static +    int StatsRecorder::countNearbyAvatars(S32 distance) +    { +        const auto our_pos = gAgentCamera.getCameraPositionGlobal(); + +       	std::vector<LLVector3d> positions; +	    uuid_vec_t avatar_ids; +        LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, our_pos, distance); +        return positions.size(); +	} + +    const U32 NUM_PERIODS = 50; +    void StatsRecorder::updateMeanFrameTime(U64 cur_frame_time_raw) +    { +        static std::deque<U64> frame_time_deque; +        frame_time_deque.push_front(cur_frame_time_raw); +        if (frame_time_deque.size() > NUM_PERIODS) +        { +            frame_time_deque.pop_back(); +        } +         +        std::vector<U64> buf(frame_time_deque.begin(), frame_time_deque.end()); +        std::sort(buf.begin(), buf.end()); + +        LLPerfStats::meanFrameTime = (buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]; +    } +    U64 StatsRecorder::getMeanTotalFrameTime() +    { +        return LLPerfStats::meanFrameTime; +    } + +    // static +    void StatsRecorder::updateAvatarParams() +    { +        if(tunables.autoTuneTimeout) +        { +            LLPerfStats::lastSleepedFrame = gFrameCount; +            tunables.autoTuneTimeout = false; +            return; +        } +        // sleep time is basically forced sleep when window out of focus +        auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP); +        // similar to sleep time, induced by FPS limit +        //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT); + + +        // the time spent this frame on the "doFrame" call. Treated as "tot time for frame" +        auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME); + +        if( tot_sleep_time_raw != 0 ) +        { +            // Note: we do not average sleep  +            // if at some point we need to, the averaging will need to take this into account or  +            // we forever think we're in the background due to residuals. +            LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL; +            LLPerfStats::lastSleepedFrame = gFrameCount; +            return; +        } + +        U32 target_fps = tunables.vsyncEnabled ? std::min(LLPerfStats::vsync_max_fps, tunables.userTargetFPS) : tunables.userTargetFPS; + +        if(LLPerfStats::lastSleepedFrame != 0) +        { +            // wait a short time after viewer regains focus +            if((gFrameCount - LLPerfStats::lastSleepedFrame) > target_fps * 5) +            { +                LLPerfStats::lastSleepedFrame = 0; +            } +            else +            { +                return; +            } +        } +        updateMeanFrameTime(tot_frame_time_raw); + +        if(tunables.userImpostorDistanceTuningEnabled) +        { +            // if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit. +            // also adjusts back up again for nearby crowds. +            auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance)); +            if( count != tunables.nonImpostors ) +            { +                tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER ); +                LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL; +            } +        } + +        auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); +        // Is our target frame time lower than current? If so we need to take action to reduce draw overheads. +        // cumulative avatar time (includes idle processing, attachments and base av) +        auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); + +        // The frametime budget we have based on the target FPS selected +        auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps)); +        // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL; +        auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)}; +        U32 settingsChangeFrequency{inferredFPS > 50?inferredFPS:50}; +        /*if( tot_limit_time_raw != 0) +        { +            // This could be problematic. +            tot_frame_time_raw -= tot_limit_time_raw; +        }*/ +         +        F64 time_buf = target_frame_time_raw * 0.1; + +        // 1) Is the target frame time lower than current? +        if ((target_frame_time_raw + time_buf) <= tot_frame_time_raw) +        { +            if (target_frame_time_raw - time_buf >= getMeanTotalFrameTime()) +            { +                belowTargetFPS = false; +                LLPerfStats::lastGlobalPrefChange = gFrameCount; +                return; +            } + +            if(belowTargetFPS == false) +            { +                // this is the first frame under. hold fire to add a little hysteresis +                belowTargetFPS = true; +                LLPerfStats::lastGlobalPrefChange = gFrameCount; +            } +            // if so we've got work to do + +            // how much of the frame was spent on non avatar related work? +            U64 non_avatar_time_raw = tot_frame_time_raw - tot_avatar_time_raw; + +            // If the target frame time < scene time (estimated as non_avatar time) +            U64 target_avatar_time_raw; +            if(target_frame_time_raw < non_avatar_time_raw) +            { +                // 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_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 +                        if(LLPipeline::RenderReflectionDetail != -2) +                        { +                            LLPerfStats::tunables.updateReflectionDetail(-2); +                            LLPerfStats::lastGlobalPrefChange = gFrameCount; +                            return; +                        } +                        else // deliberately "else" here so we only do one of these in any given frame +                        { +                            // step down the DD by 10m per update +                            auto new_dd = (LLPipeline::RenderFarClip - DD_STEP > tunables.userMinDrawDistance)?(LLPipeline::RenderFarClip - DD_STEP) : tunables.userMinDrawDistance; +                            if(new_dd != LLPipeline::RenderFarClip) +                            { +                                LLPerfStats::tunables.updateFarClip( new_dd ); +                                LLPerfStats::lastGlobalPrefChange = gFrameCount; +                                return; +                            } +                        } +                    } +                    // if we reach here, we've no more changes to make to tune scenery so we'll resort to agressive Avatar tuning +                    // Note: moved from outside "if changefrequency elapsed" to stop fallthrough and allow scenery changes time to take effect. +                    target_avatar_time_raw = 0; +                } +                else  +                { +                    // we made a settings change recently so let's give it time. +                    return; +                } +            } +            else +            { +                // set desired avatar budget. +                target_avatar_time_raw =  target_frame_time_raw - non_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)}; +                // max render this frame may be higher than the last (cos new entrants and jitter) so make sure we are heading in the right direction +                if( new_render_limit_ns > renderAvatarMaxART_ns ) +                { +                    new_render_limit_ns = renderAvatarMaxART_ns; +                } +                new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS; + +                // bounce at the bottom to prevent "no limit"  +                new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS); + +                // assign the new value +                if(renderAvatarMaxART_ns != new_render_limit_ns) +                { +                    renderAvatarMaxART_ns = new_render_limit_ns; +                    tunables.updateSettingsFromRenderCostLimit(); +                } +                // LL_DEBUGS() << "AUTO_TUNE: avatar_budget adjusted to:" << new_render_limit_ns << LL_ENDL; +            } +            // LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< LLPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << LLPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL; +        } +        else if(( LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) ) || +                 (tunables.vsyncEnabled && (target_fps == LLPerfStats::vsync_max_fps) && (target_frame_time_raw > getMeanTotalFrameTime()))) +        { +            if(belowTargetFPS == true) +            { +                // we reached target, force a pause +                lastGlobalPrefChange = gFrameCount; +                belowTargetFPS = false; +            } + +            // once we're over the FPS target we slow down further +            if((gFrameCount - lastGlobalPrefChange) > settingsChangeFrequency*3) +            { +                if(!tunables.userAutoTuneLock) +                { +                    // we've reached the target and stayed long enough to consider stable. +                    // turn off if we are not locked. +                    tunables.updateUserAutoTuneEnabled(false); +                } +                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; +                    renderAvatarMaxART_ns += up_step; +                    tunables.updateSettingsFromRenderCostLimit(); +                    return; +                } +                if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY) +                { +                    if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance )  +                    { +                        LLPerfStats::tunables.updateFarClip( std::min(LLPipeline::RenderFarClip + DD_STEP, tunables.userTargetDrawDistance) ); +                        LLPerfStats::lastGlobalPrefChange = gFrameCount; +                        return; +                    } +                    if( (tot_frame_time_raw * 1.5) < target_frame_time_raw ) +                    { +                        // if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time. +                        LLPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) ); +                    } +                } +            } +        } +   } +} diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h new file mode 100644 index 0000000000..48ac483ce7 --- /dev/null +++ b/indra/newview/llperfstats.h @@ -0,0 +1,465 @@ +/**  +* @file llperfstats.h +* @brief Statistics collection to support autotune and perf flaoter. +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ +#pragma once +#ifndef LL_PERFSTATS_H_INCLUDED +#define LL_PERFSTATS_H_INCLUDED + +#include <atomic> +#include <chrono> +#include <array> +#include <unordered_map> +#include <mutex> +#include "lluuid.h" +#include "llfasttimer.h" +#include "llapp.h" +#include "llprofiler.h" +#include "pipeline.h" + +extern U32 gFrameCount; +extern LLUUID gAgentID; +namespace LLPerfStats +{ +// Note if changing these, they should correspond with the log range of the correpsonding sliders +    static constexpr U64 ART_UNLIMITED_NANOS{50000000}; +    static constexpr U64 ART_MINIMUM_NANOS{100000}; +    static constexpr U64 ART_MIN_ADJUST_UP_NANOS{5000}; +    static constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000};  + +    static constexpr F32 PREFERRED_DD{180}; +    static constexpr U32 SMOOTHING_PERIODS{50}; +    static constexpr U32 DD_STEP{10}; + +    static constexpr U32 TUNE_AVATARS_ONLY{0}; +    static constexpr U32 TUNE_SCENE_AND_AVATARS{1}; +    static constexpr U32 TUNE_SCENE_ONLY{2}; + +    extern F64 cpu_hertz; + +    extern std::atomic<int64_t> tunedAvatars; +    extern std::atomic<U64> renderAvatarMaxART_ns; +    extern bool belowTargetFPS; +    extern U32 lastGlobalPrefChange; +    extern U32 lastSleepedFrame; +    extern U64 meanFrameTime; +    extern std::mutex bufferToggleLock; + +    enum class ObjType_t{ +        OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery +        OT_AVATAR, +        OT_ATTACHMENT, +        OT_HUD, +        OT_COUNT +    }; +    enum class StatType_t{ +        RENDER_GEOMETRY=0, +        RENDER_SHADOWS, +        RENDER_HUDS, +        RENDER_UI, +        RENDER_COMBINED, +        RENDER_SWAP, +        RENDER_FRAME, +        RENDER_DISPLAY, +        RENDER_SLEEP, +        RENDER_LFS, +        RENDER_MESHREPO, +        //RENDER_FPSLIMIT, +        RENDER_FPS, +        RENDER_IDLE, +        RENDER_DONE, // toggle buffer & clearbuffer (see processUpdate for hackery) +        STATS_COUNT +    }; + +    struct StatsRecord +    {  +        StatType_t  statType; +        ObjType_t   objType; +        LLUUID      avID; +        LLUUID      objID; +        uint64_t    time; +        bool        isRigged; +        bool        isHUD; +    }; + +    struct Tunables +    { +        static constexpr U32 Nothing{0}; +        static constexpr U32 NonImpostors{1}; +        static constexpr U32 ReflectionDetail{2}; +        static constexpr U32 FarClip{4}; +        static constexpr U32 UserMinDrawDistance{8}; +        static constexpr U32 UserTargetDrawDistance{16}; +        static constexpr U32 UserImpostorDistance{32}; +        static constexpr U32 UserImpostorDistanceTuningEnabled{64}; +        static constexpr U32 UserFPSTuningStrategy{128}; +        static constexpr U32 UserAutoTuneEnabled{256}; +        static constexpr U32 UserTargetFPS{512}; +        static constexpr U32 UserARTCutoff{1024}; +        static constexpr U32 UserTargetReflections{2048}; +        static constexpr U32 UserAutoTuneLock{4096}; + +        U32 tuningFlag{0}; // bit mask for changed settings + +        // proxy variables, used to pas the new value to be set via the mainthread +        U32 nonImpostors{0};  +        S32 reflectionDetail{0};  +        F32 farClip{0.0};  +        F32 userMinDrawDistance{0.0};  +        F32 userTargetDrawDistance{0.0}; +        F32 userImpostorDistance{0.0}; +        bool userImpostorDistanceTuningEnabled{false}; +        U32 userFPSTuningStrategy{0}; +        bool userAutoTuneEnabled{false}; +        bool userAutoTuneLock{true}; +        U32 userTargetFPS{0}; +        F32 userARTCutoffSliderValue{0}; +        S32 userTargetReflections{0}; +        bool autoTuneTimeout{true}; +        bool vsyncEnabled{true}; + +        void updateNonImposters(U32 nv){nonImpostors=nv; tuningFlag |= NonImpostors;}; +        void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;}; +        void updateFarClip(F32 nv){farClip=nv; tuningFlag |= FarClip;}; +        void updateUserMinDrawDistance(F32 nv){userMinDrawDistance=nv; tuningFlag |= UserMinDrawDistance;}; +        void updateUserTargetDrawDistance(F32 nv){userTargetDrawDistance=nv; tuningFlag |= UserTargetDrawDistance;}; +        void updateImposterDistance(F32 nv){userImpostorDistance=nv; tuningFlag |= UserImpostorDistance;}; +        void updateImposterDistanceTuningEnabled(bool nv){userImpostorDistanceTuningEnabled=nv; tuningFlag |= UserImpostorDistanceTuningEnabled;}; +        void updateUserFPSTuningStrategy(U32 nv){userFPSTuningStrategy=nv; tuningFlag |= UserFPSTuningStrategy;}; +        void updateTargetFps(U32 nv){userTargetFPS=nv; tuningFlag |= UserTargetFPS;}; +        void updateUserARTCutoffSlider(F32 nv){userARTCutoffSliderValue=nv; tuningFlag |= UserARTCutoff;}; +        void updateUserAutoTuneEnabled(bool nv){userAutoTuneEnabled=nv; tuningFlag |= UserAutoTuneEnabled;}; +        void updateUserAutoTuneLock(bool nv){userAutoTuneLock=nv; tuningFlag |= UserAutoTuneLock;}; +        void updateUserTargetReflections(S32 nv){userTargetReflections=nv; tuningFlag |= UserTargetReflections;}; + +        void resetChanges(){tuningFlag=Nothing;}; +        void initialiseFromSettings(); +        void updateRenderCostLimitFromSettings(); +        void updateSettingsFromRenderCostLimit(); +        void applyUpdates(); +    }; + +    extern Tunables tunables; + +    class StatsRecorder{ +        using Queue = LLThreadSafeQueue<StatsRecord>; +    public: + +        static inline StatsRecorder& getInstance() +        { +            static StatsRecorder instance; +            return instance; +        } +        static inline void setFocusAv(const LLUUID& avID){focusAv = avID;}; +        static inline const LLUUID& getFocusAv(){return focusAv;}; +        static inline void setAutotuneInit(){autotuneInit = true;}; +        static inline void send(StatsRecord && upd){StatsRecorder::getInstance().q.pushFront(std::move(upd));}; +        static void endFrame(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});}; +        static void clearStats(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});}; + +        static inline void setEnabled(bool on_or_off){collectionEnabled=on_or_off;}; +        static inline void enable()     { collectionEnabled=true; }; +        static inline void disable()    { collectionEnabled=false; }; +        static inline bool enabled()    { return collectionEnabled; }; + +        static inline int getReadBufferIndex() { return (writeBuffer ^ 1); }; +        // static inline const StatsTypeMatrix& getCurrentStatsMatrix(){ return statsDoubleBuffer[getReadBufferIndex()];} +        static inline uint64_t get(ObjType_t otype, LLUUID id, StatType_t type) +        { +            return statsDoubleBuffer[getReadBufferIndex()][static_cast<size_t>(otype)][id][static_cast<size_t>(type)]; +        } +        static inline uint64_t getSceneStat(StatType_t type) +        { +            return statsDoubleBuffer[getReadBufferIndex()][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(type)]; +        } + +        static inline uint64_t getSum(ObjType_t otype, StatType_t type) +        { +            return sum[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)]; +        } +        static inline uint64_t getMax(ObjType_t otype, StatType_t type) +        { +            return max[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)]; +        } +        static void updateAvatarParams(); +    private: +        StatsRecorder(); + +        static int countNearbyAvatars(S32 distance); +        static U64 getMeanTotalFrameTime(); +        static void updateMeanFrameTime(U64 tot_frame_time_raw); +// StatsArray is a uint64_t for each possible statistic type. +        using StatsArray    = std::array<uint64_t, static_cast<size_t>(LLPerfStats::StatType_t::STATS_COUNT)>; +        using StatsMap      = std::unordered_map<LLUUID, StatsArray, boost::hash<LLUUID>>; +        using StatsTypeMatrix = std::array<StatsMap, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>; +        using StatsSummaryArray = std::array<StatsArray, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>; + +        static std::atomic<int> writeBuffer; +        static LLUUID focusAv; +        static bool autotuneInit; +        static std::array<StatsTypeMatrix,2> statsDoubleBuffer; +        static std::array<StatsSummaryArray,2> max; +        static std::array<StatsSummaryArray,2> sum; +        static bool collectionEnabled; + + +        void processUpdate(const StatsRecord& upd) const +        { +            LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +            // LL_INFOS("perfstats") << "processing update:" << LL_ENDL; +            // Note: nullptr is used as the key for global stats +            #ifdef TRACY_ENABLE +            static char avstr[36]; +            static char obstr[36]; +            #endif + +            if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 0) +            { +                // LL_INFOS("perfstats") << "End of Frame Toggle Buffer:" << gFrameCount << LL_ENDL; +                toggleBuffer(); +                return; +            } +            if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 1) +            { +                // LL_INFOS("perfstats") << "New region - clear buffers:" << gFrameCount << LL_ENDL; +                clearStatsBuffers(); +                return; +            } + +            auto ot{upd.objType}; +            auto& key{upd.objID}; +            auto& avKey{upd.avID}; +            auto type {upd.statType}; +            auto val {upd.time}; + +            if (ot == ObjType_t::OT_GENERAL) +            { +                // LL_INFOS("perfstats") << "General update:" << LL_ENDL; +                doUpd(key, ot, type,val); +                return; +            } + +            if (ot == ObjType_t::OT_AVATAR) +            { +                // LL_INFOS("perfstats") << "Avatar update:" << LL_ENDL; +                doUpd(avKey, ot, type, val); +                return; +            } + +            if (ot == ObjType_t::OT_ATTACHMENT) +            { +                if( !upd.isHUD ) // don't include HUD cost in self. +                { +                    LL_PROFILE_ZONE_NAMED("Att as Av") +                    // For all attachments that are not rigged we add them to the avatar (for all avatars) cost. +                    doUpd(avKey, ObjType_t::OT_AVATAR, type, val); +                } +                if( avKey == focusAv ) +                { +                    LL_PROFILE_ZONE_NAMED("Att as Att") +                // For attachments that are for the focusAv (self for now) we record them for the attachment/complexity view +                    if(upd.isHUD) +                    { +                        ot = ObjType_t::OT_HUD; +                    } +                    // LL_INFOS("perfstats") << "frame: " << gFrameCount << " Attachment update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << LL_ENDL; +                    doUpd(key, ot, type, val); +                } +                // else +                // { +                //     // LL_INFOS("perfstats") << "frame: " << gFrameCount << " non-self Att update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << " for av " << avKey.asString() << LL_ENDL; +                // } +            } +        } + +        static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val) +        { +            LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +            using ST = StatType_t; +            StatsMap& stm {statsDoubleBuffer[writeBuffer][static_cast<size_t>(ot)]}; +            auto& thisAsset = stm[key]; + +            thisAsset[static_cast<size_t>(type)] += val; +            thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)] += val; + +            sum[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] += val; +            sum[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] += val; + +            if(max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] < thisAsset[static_cast<size_t>(type)]) +            { +                max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] = thisAsset[static_cast<size_t>(type)]; +            } +            if(max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] < thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)]) +            { +                max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] = thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)]; +            } +        } + +        static void toggleBuffer(); +        static void clearStatsBuffers(); + +        // thread entry +        static void run() +        { +            StatsRecord upd[10]; +            auto & instance {StatsRecorder::getInstance()}; +            LL_PROFILER_SET_THREAD_NAME("PerfStats"); + +            while( enabled() && !LLApp::isExiting() ) +            { +                auto count = 0; +                while (count < 10) +                { +                    if (instance.q.tryPopFor(std::chrono::milliseconds(10), upd[count])) +                    { +                        count++; +                    } +                    else +                    { +                        break; +                    } +                } +                //LL_PROFILER_THREAD_BEGIN("PerfStats"); +                if(count) +                { +                    // LL_INFOS("perfstats") << "processing " << count << " updates." << LL_ENDL; +                    for(auto i =0; i < count; i++) +                    { +                        instance.processUpdate(upd[i]); +                    } +                } +                //LL_PROFILER_THREAD_END("PerfStats"); +            } +        } + +        Queue q; +        std::thread t; + +        ~StatsRecorder() = default; +        StatsRecorder(const StatsRecorder&) = delete; +        StatsRecorder& operator=(const StatsRecorder&) = delete; + +    }; + +    template <enum ObjType_t ObjTypeDiscriminator> +    class RecordTime +    { + +    private: +        RecordTime(const RecordTime&) = delete; +        RecordTime() = delete; +        U64 start; +    public: +        StatsRecord stat; + +        RecordTime( const LLUUID& av, const LLUUID& id, StatType_t type, bool isRiggedAtt=false, bool isHUDAtt=false): +                    start{LLTrace::BlockTimer::getCPUClockCount64()}, +                    stat{type, ObjTypeDiscriminator, std::move(av), std::move(id), 0, isRiggedAtt, isHUDAtt} +        { +            //LL_PROFILE_ZONE_COLOR(tracy::Color::Orange); +        }; + +        template < ObjType_t OD = ObjTypeDiscriminator, +                   std::enable_if_t<OD == ObjType_t::OT_GENERAL> * = nullptr> +        explicit RecordTime( StatType_t type ):RecordTime<ObjTypeDiscriminator>(LLUUID::null, LLUUID::null, type ) +        { +            LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +        }; + +        template < ObjType_t OD = ObjTypeDiscriminator, +                   std::enable_if_t<OD == ObjType_t::OT_AVATAR> * = nullptr> +        RecordTime( const LLUUID & av, StatType_t type ):RecordTime<ObjTypeDiscriminator>(std::move(av), LLUUID::null, type) +        { +            //LL_PROFILE_ZONE_COLOR(tracy::Color::Purple); +        }; + +        ~RecordTime() +        {  +            if(!LLPerfStats::StatsRecorder::enabled()) +            { +                return; +            } + +            //LL_PROFILE_ZONE_COLOR(tracy::Color::Red); + +            stat.time = LLTrace::BlockTimer::getCPUClockCount64() - start; +            StatsRecorder::send(std::move(stat)); +        }; +    }; + +     +    inline double raw_to_ns(U64 raw)    { return (static_cast<double>(raw) * 1000000000.0) / LLPerfStats::cpu_hertz; }; +    inline double raw_to_us(U64 raw)    { return (static_cast<double>(raw) *    1000000.0) / LLPerfStats::cpu_hertz; }; +    inline double raw_to_ms(U64 raw)    { return (static_cast<double>(raw) *       1000.0) / LLPerfStats::cpu_hertz; }; + +    using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>; +    using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>; +    using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>; +    using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>; +      +};// namespace LLPerfStats + +// helper functions +using RATptr = std::unique_ptr<LLPerfStats::RecordAttachmentTime>; +using RSTptr = std::unique_ptr<LLPerfStats::RecordSceneTime>; + +template <typename T> +static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp) +{ +    if( !vobj ){ ratPtrp->reset(); return;}; +     +    const T* rootAtt{vobj}; +    if (rootAtt->isAttachment()) +    { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + +        while( !rootAtt->isRootEdit() ) +        { +            rootAtt = (T*)(rootAtt->getParent()); +        } + +        auto avPtr = (T*)(rootAtt->getParent());  +        if(!avPtr){ratPtrp->reset(); return;} + +        auto& av = avPtr->getID(); +        auto& obj = rootAtt->getAttachmentItemID(); +        if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av) +        { +            if (*ratPtrp) +            { +                // deliberately reset to ensure destruction before construction of replacement. +                ratPtrp->reset(); +            }; +            *ratPtrp = std::make_unique<LLPerfStats::RecordAttachmentTime>(  +                av,  +                obj, +                ( LLPipeline::sShadowRender?LLPerfStats::StatType_t::RENDER_SHADOWS : LLPerfStats::StatType_t::RENDER_GEOMETRY ),  +                isRigged,  +                rootAtt->isHUDAttachment()); +        } +    } +    return; +}; + +#endif diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 9cebce2609..221912a029 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -207,6 +207,7 @@  #include "llstacktrace.h"  #include "threadpool.h" +#include "llperfstats.h"  #if LL_WINDOWS @@ -1499,6 +1500,8 @@ bool idle_startup()  			LLViewerParcelAskPlay::getInstance()->loadSettings();  		} +		gAgent.addRegionChangedCallback(boost::bind(&LLPerfStats::StatsRecorder::clearStats)); +  		// *Note: this is where gWorldMap used to be initialized.  		// register null callbacks for audio until the audio system is initialized @@ -2258,7 +2261,7 @@ bool idle_startup()  	if (STATE_CLEANUP == LLStartUp::getStartupState())  	{ -		set_startup_status(1.0, "", ""); +        set_startup_status(1.0, "", "");  		display_startup();  		if (!mBenefitsSuccessfullyInit) @@ -2345,6 +2348,8 @@ bool idle_startup()  		LLUIUsage::instance().clear(); +        LLPerfStats::StatsRecorder::setAutotuneInit(); +  		return TRUE;  	} @@ -3407,6 +3412,9 @@ bool process_login_success_response()  	if(!text.empty()) gAgentID.set(text);  	gDebugInfo["AgentID"] = text; +	LLPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("PerfStatsCaptureEnabled")); +	LLPerfStats::StatsRecorder::setFocusAv(gAgentID); +  	// Agent id needed for parcel info request in LLUrlEntryParcel  	// to resolve parcel name.  	LLUrlEntryParcel::setAgentID(gAgentID); diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 01d799dcd5..4f47c465c4 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -44,6 +44,7 @@  #include "llagent.h"  // HACK for destinations guide on startup  #include "llfloaterreg.h"  // HACK for destinations guide on startup  #include "llviewercontrol.h"  // HACK for destinations guide on startup +#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX  #include <boost/foreach.hpp> @@ -319,6 +320,25 @@ bool LLToolBarView::loadToolbars(bool force_default)  			}  		}  	} + +    // SL-18581: Don't show the starter avatar toolbar button for NUX users +    LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS)); +    if (gAgent.isFirstLogin()) +    { +        LL_WARNS() << "First login: checking for NUX user." << LL_ENDL; +        if (my_outfits_cat != NULL && my_outfits_cat->getDescendentCount() > 0) +        { +            LL_WARNS() << "First login: My Outfits folder is not empty, removing the avatar picker button." << LL_ENDL; +            for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++) +            { +                if (mToolbars[i]) +                { +                    mToolbars[i]->removeCommand(LLCommandId("avatar")); +                } +            } +        } +    } +  	mToolbarsLoaded = true;  	return true;  } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 34c9dae4bb..50d48987ed 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -75,6 +75,7 @@  #include "llspellcheck.h"  #include "llslurl.h"  #include "llstartup.h" +#include "llperfstats.h"  // Third party library includes  #include <boost/algorithm/string.hpp> @@ -166,6 +167,12 @@ static bool handleSetShaderChanged(const LLSD& newvalue)  	return true;  } +static bool handleShadowDetailChanged(const LLSD& newvalue) +{ +    gPipeline.handleShadowDetailChanged(); +    return true; +} +  static bool handleRenderPerfTestChanged(const LLSD& newvalue)  {         bool status = !newvalue.asBoolean(); @@ -260,8 +267,15 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)  static bool handleVSyncChanged(const LLSD& newvalue)  { +    LLPerfStats::tunables.vsyncEnabled = newvalue.asBoolean();      gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean()); +    if(newvalue.asBoolean() == true) +    { +        U32 current_target = gSavedSettings.getU32("TargetFPS"); +        gSavedSettings.setU32("TargetFPS", std::min((U32)gViewerWindow->getWindow()->getRefreshRate(), current_target)); +    } +      return true;  } @@ -637,6 +651,77 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)  }  void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value); + +void handleTargetFPSChanged(const LLSD& newValue) +{ +    const auto targetFPS = gSavedSettings.getU32("TargetFPS"); + +    U32 frame_rate_limit = gViewerWindow->getWindow()->getRefreshRate(); +    if(LLPerfStats::tunables.vsyncEnabled && (targetFPS > frame_rate_limit)) +    { +        gSavedSettings.setU32("TargetFPS", std::min(frame_rate_limit, targetFPS)); +    } +    else +    { +        LLPerfStats::tunables.userTargetFPS = targetFPS; +    } +} + +void handleAutoTuneLockChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getBOOL("AutoTuneLock"); +    LLPerfStats::tunables.userAutoTuneLock = newval; + +    gSavedSettings.setBOOL("AutoTuneFPS", newval); +} + +void handleAutoTuneFPSChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getBOOL("AutoTuneFPS"); +    LLPerfStats::tunables.userAutoTuneEnabled = newval; +    if(newval && LLPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max +    { +        gSavedSettings.setF32("RenderAvatarMaxART",log10(LLPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var +    } +} + +void handleRenderAvatarMaxARTChanged(const LLSD& newValue) +{ +    LLPerfStats::tunables.updateRenderCostLimitFromSettings(); +} + +void handleUserTargetDrawDistanceChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getF32("AutoTuneRenderFarClipTarget"); +    LLPerfStats::tunables.userTargetDrawDistance = newval; +} + +void handleUserTargetReflectionsChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getS32("UserTargetReflections"); +    LLPerfStats::tunables.userTargetReflections = newval; +} + +void handlePerformanceStatsEnabledChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled"); +    LLPerfStats::StatsRecorder::setEnabled(newval); +} +void handleUserImpostorByDistEnabledChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled"); +    LLPerfStats::tunables.userImpostorDistanceTuningEnabled = newval; +} +void handleUserImpostorDistanceChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance"); +    LLPerfStats::tunables.userImpostorDistance = newval; +} +void handleFPSTuningStrategyChanged(const LLSD& newValue) +{ +    const auto newval = gSavedSettings.getU32("TuningFPSStrategy"); +    LLPerfStats::tunables.userFPSTuningStrategy = newval; +}  ////////////////////////////////////////////////////////////////////////////  LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting) @@ -670,153 +755,164 @@ void setting_setup_signal_listener(LLControlGroup& group, const std::string& set  void settings_setup_listeners()  {      setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); -	setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); -	setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); -	setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); -	setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition); -	setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); -	setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); -	setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); -	setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); +    setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); +    setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); +    setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); +    setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition); +    setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); +    setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); +    setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); +    setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged); +    setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);      setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); -	setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged); -	setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); -	setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); -	setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); -	setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); -	setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged); -	setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged); -	setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged); -	setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged); -	setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged); -	setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); -	setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);	 -	setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); -	setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); -	setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus); -	setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause); -	setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); -	setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); -	setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost); -	setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid); -	setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged); -	setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged); -	setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged); -	setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged); -	setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged); -	setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleShadowDetailChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); +    setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged); +    setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); +    setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); +    setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); +    setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); +    setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged); +    setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged); +    setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged); +    setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged); +    setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged); +    setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); +    setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);	 +    setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); +    setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); +    setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus); +    setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause); +    setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); +    setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); +    setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost); +    setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid); +    setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged); +    setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged); +    setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged); +    setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged); +    setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged); + +    setting_setup_signal_listener(gSavedSettings, "TargetFPS", handleTargetFPSChanged); +    setting_setup_signal_listener(gSavedSettings, "AutoTuneFPS", handleAutoTuneFPSChanged); +    setting_setup_signal_listener(gSavedSettings, "AutoTuneLock", handleAutoTuneLockChanged); +    setting_setup_signal_listener(gSavedSettings, "RenderAvatarMaxART", handleRenderAvatarMaxARTChanged); +    setting_setup_signal_listener(gSavedSettings, "PerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged); +    setting_setup_signal_listener(gSavedSettings, "UserTargetReflections", handleUserTargetReflectionsChanged); +    setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged); +    setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged); +    setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged); +    setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged);      setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);  } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 031f9f6c52..b40cf4acec 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -78,6 +78,7 @@  #include "llscenemonitor.h"  #include "llenvironment.h" +#include "llperfstats.h"  extern LLPointer<LLViewerTexture> gStartTexture;  extern bool gShiftFrame; @@ -398,7 +399,8 @@ static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");  // Paint the display!  void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  { -	LL_RECORD_BLOCK_TIME(FTM_RENDER); +    LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering. +    LL_RECORD_BLOCK_TIME(FTM_RENDER);  	if (gWindowResized)  	{ //skip render on frames where window has been resized @@ -1092,7 +1094,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  void render_hud_attachments()  { -	gGL.matrixMode(LLRender::MM_PROJECTION); +    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_HUDS); // render time capture - Primary contributor to HUDs (though these end up in render batches) +    gGL.matrixMode(LLRender::MM_PROJECTION);  	gGL.pushMatrix();  	gGL.matrixMode(LLRender::MM_MODELVIEW);  	gGL.pushMatrix(); @@ -1283,7 +1286,8 @@ bool setup_hud_matrices(const LLRect& screen_region)  void render_ui(F32 zoom_factor, int subfield)  { -	LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); +    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_UI ); // render time capture - Primary UI stat can have HUD time overlap (TODO) +    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);  	LLGLState::checkStates(); @@ -1366,7 +1370,8 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");  void swap()  { -	LL_RECORD_BLOCK_TIME(FTM_SWAP); +    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SWAP ); // render time capture - Swap buffer time - can signify excessive data transfer to/from GPU +    LL_RECORD_BLOCK_TIME(FTM_SWAP);  	if (gDisplaySwapBuffers)  	{ diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 23b7999399..0f2fe1e1cd 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -108,9 +108,11 @@  #include "llfloaterpathfindingconsole.h"  #include "llfloaterpathfindinglinksets.h"  #include "llfloaterpay.h" +#include "llfloaterperformance.h"  #include "llfloaterperms.h"  #include "llfloaterpostprocess.h"  #include "llfloaterpreference.h" +#include "llfloaterpreferencesgraphicsadvanced.h"  #include "llfloaterpreferenceviewadvanced.h"  #include "llfloaterpreviewtrash.h"  #include "llfloaterprofile.h" @@ -413,6 +415,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);  	LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);  	LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); +	LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerformance>);  	LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPermsDefault>);  	LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);  	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index f3b0e82b3a..489f90aabb 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -55,6 +55,7 @@  #include "m3math.h"  #include "m4math.h"  #include "llmatrix4a.h" +#include "llperfstats.h"   #if !LL_DARWIN && !LL_LINUX  extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; @@ -230,6 +231,16 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  		return 0;  	} +    // render time capture +    // This path does not appear to have attachments. Prove this then remove. +    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; +    auto vobj = mFace->getViewerObject(); +    if( vobj && vobj->isAttachment() ) +    { +        trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr ); +        LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL; +    } +  	U32 triangle_count = 0;  	S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 111e70bfe9..5b82fb5030 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3305,6 +3305,8 @@ class LLAvatarCheckImpostorMode : public view_listener_t  				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);  			case 2:  				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER); +            case 4: +                return (avatar->getVisualMuteSettings() != LLVOAvatar::AV_RENDER_NORMALLY);  			default:  				return false;  		} diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index e5265f1dcd..449fd4ba43 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -716,7 +716,7 @@ void LLViewerPartSim::updateSimulation()  			if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME))  			{ -				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex()) +				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex() && vobj->getAvatar()->isTooSlow())  				{  					upd = FALSE;  				} diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 0f2b0714fd..519166af63 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -58,6 +58,7 @@  #include "llfeaturemanager.h"  #include "llviewernetwork.h"  #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived +#include "llperfstats.h"  #include "llsdserialize.h"  #include "llsdutil.h"  #include "llcorehttputil.h" @@ -209,6 +210,13 @@ LLTrace::EventStatHandle<F64Seconds >	AVATAR_EDIT_TIME("avataredittime", "Second  LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits");  LLTrace::EventStatHandle<F64Seconds >	TEXTURE_FETCH_TIME("texture_fetch_time"); + +LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  SCENERY_FRAME_PCT("scenery_frame_pct"); +LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  AVATAR_FRAME_PCT("avatar_frame_pct"); +LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  HUDS_FRAME_PCT("huds_frame_pct"); +LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  UI_FRAME_PCT("ui_frame_pct"); +LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  SWAP_FRAME_PCT("swap_frame_pct"); +LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  IDLE_FRAME_PCT("idle_frame_pct");  }  LLViewerStats::LLViewerStats()  @@ -415,6 +423,89 @@ void update_statistics()  			texture_stats_timer.reset();  		}  	} + +    if (LLFloaterReg::instanceVisible("scene_load_stats")) +    { +        static const F32 perf_stats_freq = 1; +        static LLFrameTimer perf_stats_timer; +        if (perf_stats_timer.getElapsedTimeF32() >= perf_stats_freq) +        { +            LLStringUtil::format_map_t args; +            LLPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment + +            auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME); +            // cumulative avatar time (includes idle processing, attachments and base av) +            auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(LLPerfStats::ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); +            // cumulative avatar render specific time (a bit arbitrary as the processing is too.) +            // auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE); +            // auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw; +            // the time spent this frame on the "display()" call. Treated as "tot time rendering" +            auto tot_render_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_DISPLAY); +            // sleep time is basically forced sleep when window out of focus  +            auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP); +            // time spent on UI +            auto tot_ui_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_UI); +            // cumulative time spent rendering HUDS +            auto tot_huds_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_HUDS); +            // "idle" time. This is the time spent in the idle poll section of the main loop +            auto tot_idle_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_IDLE); +            // similar to sleep time, induced by FPS limit +            //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT); +            // swap time is time spent in swap buffer +            auto tot_swap_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SWAP); + +            LLPerfStats::bufferToggleLock.unlock(); + +             auto tot_frame_time_ns = LLPerfStats::raw_to_ns(tot_frame_time_raw); +            auto tot_avatar_time_ns = LLPerfStats::raw_to_ns(tot_avatar_time_raw); +            auto tot_huds_time_ns = LLPerfStats::raw_to_ns(tot_huds_time_raw); +            // UI time includes HUD time so dedut that before we calc percentages +            auto tot_ui_time_ns = LLPerfStats::raw_to_ns(tot_ui_time_raw - tot_huds_time_raw); + +            // auto tot_sleep_time_ns          = LLPerfStats::raw_to_ns( tot_sleep_time_raw ); +            // auto tot_limit_time_ns          = LLPerfStats::raw_to_ns( tot_limit_time_raw ); + +            // auto tot_render_time_ns         = LLPerfStats::raw_to_ns( tot_render_time_raw ); +            auto tot_idle_time_ns = LLPerfStats::raw_to_ns(tot_idle_time_raw); +            auto tot_swap_time_ns = LLPerfStats::raw_to_ns(tot_swap_time_raw); +            auto tot_scene_time_ns = LLPerfStats::raw_to_ns(tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw); +            // auto tot_overhead_time_ns  = LLPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw ); + +            // // remove time spent sleeping for fps limit or out of focus. +            // tot_frame_time_ns -= tot_limit_time_ns; +            // tot_frame_time_ns -= tot_sleep_time_ns; + +            if (tot_frame_time_ns != 0) +            { +                auto pct_avatar_time = (tot_avatar_time_ns * 100) / tot_frame_time_ns; +                auto pct_huds_time = (tot_huds_time_ns * 100) / tot_frame_time_ns; +                auto pct_ui_time = (tot_ui_time_ns * 100) / tot_frame_time_ns; +                auto pct_idle_time = (tot_idle_time_ns * 100) / tot_frame_time_ns; +                auto pct_swap_time = (tot_swap_time_ns * 100) / tot_frame_time_ns; +                auto pct_scene_render_time = (tot_scene_time_ns * 100) / tot_frame_time_ns; +                pct_avatar_time = llclamp(pct_avatar_time, 0., 100.); +                pct_huds_time = llclamp(pct_huds_time, 0., 100.); +                pct_ui_time = llclamp(pct_ui_time, 0., 100.); +                pct_idle_time = llclamp(pct_idle_time, 0., 100.); +                pct_swap_time = llclamp(pct_swap_time, 0., 100.); +                pct_scene_render_time = llclamp(pct_scene_render_time, 0., 100.); +                if (tot_sleep_time_raw == 0) +                { +                    sample(LLStatViewer::SCENERY_FRAME_PCT, (U32)llround(pct_scene_render_time)); +                    sample(LLStatViewer::AVATAR_FRAME_PCT, (U32)llround(pct_avatar_time)); +                    sample(LLStatViewer::HUDS_FRAME_PCT, (U32)llround(pct_huds_time)); +                    sample(LLStatViewer::UI_FRAME_PCT, (U32)llround(pct_ui_time)); +                    sample(LLStatViewer::SWAP_FRAME_PCT, (U32)llround(pct_swap_time)); +                    sample(LLStatViewer::IDLE_FRAME_PCT, (U32)llround(pct_idle_time)); +                } +            } +            else +            { +                LL_WARNS("performance") << "Scene time 0. Skipping til we have data." << LL_ENDL; +            } +            perf_stats_timer.reset(); +        } +    }  }  void update_texture_time() @@ -527,6 +618,7 @@ void send_viewer_stats(bool include_preferences)  	system["gpu"] = gpu_desc;  	system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass(); +    system["gpu_memory_bandwidth"] = LLFeatureManager::getInstance()->getGPUMemoryBandwidth();  	system["gpu_vendor"] = gGLManager.mGLVendorShort;  	system["gpu_version"] = gGLManager.mDriverVersionVendorString;  	system["opengl_version"] = gGLManager.mGLVersionString; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 6306e15f5c..0a20c864dd 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -208,8 +208,8 @@ static std::string get_texture_list_name()  void LLViewerTextureList::doPrefetchImages()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	gTextureTimer.start(); -	gTextureTimer.pause(); +    gTextureTimer.start(); +    gTextureTimer.pause();      // todo: do not load without getViewerAssetUrl()      // either fail login without caps or provide this diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 17299b6c61..305c489cc8 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -113,6 +113,8 @@  #include "llrendersphere.h"  #include "llskinningutil.h" +#include "llperfstats.h" +  #include <boost/lexical_cast.hpp>  extern F32 SPEED_ADJUST_MAX; @@ -205,6 +207,8 @@ const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;  const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60; +const S32 MIN_NONTUNED_AVS = 5; +  enum ERenderName  {  	RENDER_NAME_NEVER, @@ -616,6 +620,8 @@ F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;  F32 LLVOAvatar::sGreyTime = 0.f;  F32 LLVOAvatar::sGreyUpdateTime = 0.f;  LLPointer<LLViewerTexture> LLVOAvatar::sCloudTexture = NULL; +std::vector<LLUUID> LLVOAvatar::sAVsIgnoringARTLimit; +S32 LLVOAvatar::sAvatarsNearby = 0;  //-----------------------------------------------------------------------------  // Helper functions @@ -814,6 +820,14 @@ LLVOAvatar::~LLVOAvatar()  		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");  	} +    if(mTuned) +    { +        LLPerfStats::tunedAvatars--; +        mTuned = false; +    } +    sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), sAVsIgnoringARTLimit.end()); + +  	logPendingPhases();  	LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL; @@ -2544,12 +2558,19 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  		LL_INFOS() << "Warning!  Idle on dead avatar" << LL_ENDL;  		return;  	} +    // record time and refresh "tooSlow" status +    LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time. +    updateTooSlow();  	static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");  	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))  		&& !disable_all_render_types && !isSelf())  	{ -		return; +        if (!mIsControlAvatar) +        { +            idleUpdateNameTag( mLastRootPos ); +        } +        return;  	}      // Update should be happening max once per frame. @@ -3128,7 +3149,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()  																 LLPartData::LL_PART_TARGET_POS_MASK );  			// do not generate particles for dummy or overly-complex avatars -			if (!mIsDummy && !isTooComplex()) +			if (!mIsDummy && !isTooComplex() && !isTooSlow())  			{  				setParticleSource(particle_parameters, getID());  			} @@ -3213,11 +3234,9 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)      static LLCachedControl<F32> FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds      static LLCachedControl<bool> use_chat_bubbles(gSavedSettings, "UseChatBubbles"); -	bool visible_avatar = isVisible() || mNeedsAnimUpdate;  	bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping);  	bool render_name =	visible_chat || -		(visible_avatar && -		 ((sRenderName == RENDER_NAME_ALWAYS) || +		(((sRenderName == RENDER_NAME_ALWAYS) ||  		  (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));  	// If it's your own avatar, don't draw in mouselook, and don't  	// draw if we're specifically hiding our own name. @@ -3712,7 +3731,7 @@ bool LLVOAvatar::isVisuallyMuted()          }  		else   		{ -			muted = isTooComplex(); +			muted = isTooComplex() || isTooSlow();  		}  	} @@ -8282,6 +8301,133 @@ bool LLVOAvatar::isTooComplex() const  	return too_complex;  } +bool LLVOAvatar::isTooSlow() const +{ +    static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends"); +    bool render_friend =  (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends); + +    if (render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) +    { +        return false; +    } +    return mTooSlow; +} + +// use Avatar Render Time as complexity metric +// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number. +void LLVOAvatar::markARTStale() +{ +    mARTStale=true; +    mLastARTUpdateFrame = LLFrameTimer::getFrameCount(); +} + +// Udpate Avatar state based on render time +void LLVOAvatar::updateTooSlow() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; +    static LLCachedControl<bool> alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends"); +    static LLCachedControl<bool> allowSelfImpostor(gSavedSettings, "AllowSelfImpostor"); +    const auto id = getID(); + +    // mTooSlow - Is the avatar flagged as being slow (includes shadow time) +    // mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed. +    // mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness + +    if( mARTStale ) +    { +        if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 )  +        { +            // LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL; +            // we've not had a chance to update yet (allow a few to be certain a full frame has passed) +            return; +        } + +        mARTStale = false; +        mTooSlow = false; +        mTooSlowWithoutShadows = false; +        // LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL; +    } + +    // Either we're not stale or we've updated. + +    U64 render_time_raw; +    U64 render_geom_time_raw; + +    if( !mTooSlow )  +    { +        // we are fully rendered, so we use the live values +        std::lock_guard<std::mutex> lock{LLPerfStats::bufferToggleLock}; +        render_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_COMBINED); +        render_geom_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_GEOMETRY); +    } +    else +    { +        // use the cached values. +        render_time_raw = mRenderTime; +        render_geom_time_raw = mGeomTime;		 +    } + +	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.) +        {			 +            // if we weren't capped, we are now +            mLastARTUpdateFrame = LLFrameTimer::getFrameCount(); +            mRenderTime = render_time_raw; +            mGeomTime = render_geom_time_raw; +            mARTStale = false; +            mTooSlow = true; +        } +        if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap +        { +            bool render_friend_or_exception =  	( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) || +                ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER );  +            if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception  ) +            { +                // Note: slow rendering Friends still get their shadows zapped. +                mTooSlowWithoutShadows = (LLPerfStats::raw_to_ns(render_geom_time_raw) >= LLPerfStats::renderAvatarMaxART_ns); +            } +        } +    } +    else +    { +        // LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << LLPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL; +        mTooSlow = false; +        mTooSlowWithoutShadows = false; + +		if (ignore_tune) +		{ +            return; +		} +    } +    if(mTooSlow && !mTuned) +    { +        LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked. +        mTuned = true; +    } +    else if(!mTooSlow && mTuned) +    { +        LLPerfStats::tunedAvatars--; +        mTuned = false; +    } +} +  //-----------------------------------------------------------------------------  // findMotion()  //----------------------------------------------------------------------------- @@ -10543,6 +10689,64 @@ void LLVOAvatar::idleUpdateRenderComplexity()      // Render Complexity      calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed	 + +	bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); +    if (autotune && !isDead()) +    { +        static LLCachedControl<F32> 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<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); +        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; +                } +                avs_nearby++; +            } +            char_iter++; +        } +        sAvatarsNearby = avs_nearby; +        agent_update_timer.reset(); +    }  }  void LLVOAvatar::idleUpdateDebugInfo() @@ -10641,7 +10845,8 @@ void LLVOAvatar::accountRenderComplexityForObject(      const F32 max_attachment_complexity,      LLVOVolume::texture_cost_t& textures,      U32& cost, -    hud_complexity_list_t& hud_complexity_list) +    hud_complexity_list_t& hud_complexity_list, +    object_complexity_list_t& object_complexity_list)  {      if (attached_object && !attached_object->isHUDAttachment())  		{ @@ -10699,6 +10904,15 @@ void LLVOAvatar::accountRenderComplexityForObject(                                                     << LL_ENDL;                              // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI                              cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); + +                            if (isSelf()) +                            { +                                LLObjectComplexity object_complexity; +                                object_complexity.objectName = attached_object->getAttachmentItemName(); +                                object_complexity.objectId = attached_object->getAttachmentItemID(); +                                object_complexity.objectCost = attachment_total_cost; +                                object_complexity_list.push_back(object_complexity); +                            }  						}  					}  				} @@ -10796,6 +11010,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()  		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++)  		{ @@ -10839,7 +11054,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()              if (volp && !volp->isAttachment())              {                  accountRenderComplexityForObject(volp, max_attachment_complexity, -                                                 textures, cost, hud_complexity_list); +                                                 textures, cost, hud_complexity_list, object_complexity_list);              }          } @@ -10855,7 +11070,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()  			{                  LLViewerObject* attached_object = attachment_iter->get();                  accountRenderComplexityForObject(attached_object, max_attachment_complexity, -                                                 textures, cost, hud_complexity_list); +                                                 textures, cost, hud_complexity_list, object_complexity_list);  			}  		} @@ -10920,7 +11135,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()          {              // Avatar complexity              LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); - +            LLAvatarRenderNotifier::getInstance()->setObjectComplexityList(object_complexity_list);              // HUD complexity              LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);          } @@ -11095,7 +11310,7 @@ LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const  		{	// Always want to see this AV as an impostor  			result = AOA_JELLYDOLL;  		} -		else if (isTooComplex()) +		else if (isTooComplex() || isTooSlow())  		{  			result = AOA_JELLYDOLL;  		} @@ -11122,7 +11337,7 @@ void LLVOAvatar::calcMutedAVColor()          new_color = LLColor4::grey4;          change_msg = " blocked: color is grey4";      } -    else if (!isTooComplex()) +    else if (!isTooComplex() && !isTooSlow())      {          new_color = LLColor4::white;          change_msg = " simple imposter "; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 56f2b73bef..970ca523a5 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -297,7 +297,8 @@ public:                                                       const F32 max_attachment_complexity,                                                       LLVOVolume::texture_cost_t& textures,                                                       U32& cost, -                                                     hud_complexity_list_t& hud_complexity_list); +                                                     hud_complexity_list_t& hud_complexity_list, +                                                     object_complexity_list_t& object_complexity_list);  	void			calculateUpdateRenderComplexity();  	static const U32 VISUAL_COMPLEXITY_UNKNOWN;  	void			updateVisualComplexity(); @@ -314,6 +315,8 @@ public:  	void 			idleUpdateBelowWater(); +	static void updateNearbyAvatarCount(); +  	//--------------------------------------------------------------------  	// Static preferences (controlled by user settings/menus)  	//-------------------------------------------------------------------- @@ -338,6 +341,9 @@ public:      static LLPointer<LLViewerTexture>  sCloudTexture; +	static std::vector<LLUUID> sAVsIgnoringARTLimit; +    static S32 sAvatarsNearby; +  	//--------------------------------------------------------------------  	// Region state  	//-------------------------------------------------------------------- @@ -349,6 +355,16 @@ public:  	//--------------------------------------------------------------------  public:  	BOOL			isFullyLoaded() const; + +    // check and return current state relative to limits +    // default will test only the geometry (combined=false). +    // this allows us to disable shadows separately on complex avatars. + +    inline bool 	isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;}; +    bool 	isTooSlow() const; + +    void 			updateTooSlow(); +  	bool 			isTooComplex() const;  	bool 			visualParamWeightsAreDefault();  	virtual bool	getIsCloud() const; @@ -368,6 +384,7 @@ public:  	void 			logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);      void            calcMutedAVColor(); +    void            markARTStale();  protected:  	LLViewerStats::PhaseMap& getPhases() { return mPhases; } @@ -389,6 +406,17 @@ private:  	LLFrameTimer	mFullyLoadedTimer;  	LLFrameTimer	mRuthTimer; +    U32				mLastARTUpdateFrame{0}; +    U64				mRenderTime{0}; +    U64				mGeomTime{0}; +    bool			mARTStale{true}; +    bool			mARTCapped{false}; +    // variables to hold "slowness" status +    bool			mTooSlow{false}; +    bool			mTooSlowWithoutShadows{false}; + +    bool            mTuned{false}; +  private:  	LLViewerStats::PhaseMap mPhases; @@ -1144,6 +1172,8 @@ public:  	// COF version of last appearance message received for this av.  	S32 mLastUpdateReceivedCOFVersion; +    U64 getLastART() const { return mRenderTime; } +  /**                    Diagnostics   **                                                                            **   *******************************************************************************/ diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2e7ccc8334..51925b4129 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -88,6 +88,7 @@  #include "llcallstack.h"  #include "llsculptidsize.h"  #include "llavatarappearancedefines.h" +#include "llperfstats.h"   const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;  const F32 FORCE_CULL_AREA = 8.f; @@ -5436,7 +5437,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			}  		} -		if (type == LLRenderPass::PASS_ALPHA) +		// if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr  		{ //for alpha sorting  			facep->setDrawInfo(draw_info);  		} @@ -5637,6 +5638,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)          LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");  		//get all the faces into a list +        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();                drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ @@ -5668,6 +5670,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				continue;  			} +            if(vobj->isAttachment()) +            { +                trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr); +            } +  			LLVolume* volume = vobj->getVolume();  			if (volume)  			{ @@ -6058,6 +6065,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  			U32 buffer_count = 0; +            std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};  			for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  			{  				LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); @@ -6067,6 +6075,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  					LLVOVolume* vobj = drawablep->getVOVolume();  					if (!vobj) continue; + +                    if (vobj->isAttachment()) +                    { +                        trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr ); +                    }  					if (debugLoggingEnabled("AnimatedObjectsLinkset"))  					{ @@ -6503,10 +6516,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  		U32 indices_index = 0;  		U16 index_offset = 0; -		while (face_iter < i) +        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr; +        while (face_iter < i)  		{  			//update face indices for new buffer  			facep = *face_iter; +            LLViewerObject* vobj = facep->getViewerObject(); +            if(vobj && vobj->isAttachment()) +            { +                trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr); +            }  			if (buffer.isNull())  			{  				// Bulk allocation failed diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 3201440b95..1266011e0a 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -33,6 +33,7 @@  #include "llstl.h"  #include "llagent.h" +#include "llagentcamera.h"  #include "llviewercontrol.h"  #include "lldrawpool.h"  #include "llglheaders.h" @@ -1420,6 +1421,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); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 5dee8eea0f..b2be36d72c 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -51,6 +51,7 @@ class LLHost;  class LLViewerObject;  class LLSurfacePatch; +class LLCharacter;  class LLCloudPuff;  class LLCloudGroup;  class LLVOAvatar; @@ -171,6 +172,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:      void clearHoleWaterObjects();      void clearEdgeWaterObjects(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d00ac5db76..bbff6c889f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -43,6 +43,7 @@  #include "llui.h"   #include "llglheaders.h"  #include "llrender.h" +#include "llstartup.h"  #include "llwindow.h"	// swapBuffers()  // newview includes @@ -149,6 +150,7 @@ U32 LLPipeline::RenderFSAASamples;  U32 LLPipeline::RenderResolutionDivisor;  bool LLPipeline::RenderUIBuffer;  S32 LLPipeline::RenderShadowDetail; +S32 LLPipeline::RenderShadowSplits;  bool LLPipeline::RenderDeferredSSAO;  F32 LLPipeline::RenderShadowResolutionScale;  bool LLPipeline::RenderLocalLights; @@ -544,6 +546,7 @@ void LLPipeline::init()  	connectRefreshCachedSettingsSafe("RenderResolutionDivisor");  	connectRefreshCachedSettingsSafe("RenderUIBuffer");  	connectRefreshCachedSettingsSafe("RenderShadowDetail"); +    connectRefreshCachedSettingsSafe("RenderShadowSplits");  	connectRefreshCachedSettingsSafe("RenderDeferredSSAO");  	connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");  	connectRefreshCachedSettingsSafe("RenderLocalLights"); @@ -615,7 +618,6 @@ void LLPipeline::init()  LLPipeline::~LLPipeline()  { -  }  void LLPipeline::cleanup() @@ -1075,6 +1077,7 @@ void LLPipeline::refreshCachedSettings()  	RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");  	RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");  	RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); +    RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits");  	RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");  	RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");  	RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); @@ -6002,7 +6005,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)  			LLDrawable* drawable = light->drawable;              const LLViewerObject *vobj = light->drawable->getVObj();              if(vobj && vobj->getAvatar()  -               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()) +               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlow())                 )              {                  drawable->clearState(LLDrawable::NEARBY_LIGHT); @@ -6081,7 +6084,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)  				continue;  			}              LLVOAvatar * av = light->getAvatar(); -            if (av && (av->isTooComplex() || av->isInMuteList())) +            if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlow()))              {                  // avatars that are already in the list will be removed by removeMutedAVsLights                  continue; @@ -10247,14 +10250,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	if (mSunDiffuse == LLColor4::black)  	{ //sun diffuse is totally black, shadows don't matter -		LLGLDepthTest depth(GL_TRUE); - -		for (S32 j = 0; j < 4; j++) -		{ -			mShadow[j].bindTarget(); -			mShadow[j].clear(); -			mShadow[j].flush(); -		} +        skipRenderingShadows();  	}  	else  	{ @@ -10309,7 +10305,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			std::vector<LLVector3> fp; -			if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) +			if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir) +                || j > RenderShadowSplits)  			{  				//no possible shadow receivers  				if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) @@ -10871,10 +10868,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)                                << " is " << ( too_complex ? "" : "not ") << "too complex"                                << LL_ENDL; -	pushRenderTypeMask(); -	 -	if (visually_muted || too_complex) -	{ +    pushRenderTypeMask(); + +    if (visually_muted || too_complex) +    {          // only show jelly doll geometry  		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,  							LLPipeline::RENDER_TYPE_CONTROL_AV, @@ -11534,3 +11531,27 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )  	}  } +void LLPipeline::skipRenderingShadows() +{ +    LLGLDepthTest depth(GL_TRUE); + +    for (S32 j = 0; j < 4; j++) +    { +        mShadow[j].bindTarget(); +        mShadow[j].clear(); +        mShadow[j].flush(); +    } +} + +void LLPipeline::handleShadowDetailChanged() +{ +    if (RenderShadowDetail > gSavedSettings.getS32("RenderShadowDetail")) +    { +        skipRenderingShadows(); +    } +    else +    { +        LLViewerShaderMgr::instance()->setShaders(); +    } +} + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 0830d4a2ea..6580c6216c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -425,6 +425,7 @@ public:  	void skipRenderingOfTerrain( bool flag );  	void hideObject( const LLUUID& id );  	void restoreHiddenObject( const LLUUID& id ); +    void handleShadowDetailChanged();  private:  	void unloadShaders(); @@ -436,6 +437,7 @@ private:  	void connectRefreshCachedSettingsSafe(const std::string name);  	void hideDrawable( LLDrawable *pDrawable );  	void unhideDrawable( LLDrawable *pDrawable ); +    void skipRenderingShadows();  public:  	enum {GPU_CLASS_MAX = 3 }; @@ -717,7 +719,6 @@ protected:  	U64						mOldRenderDebugMask;  	std::stack<U32>			mRenderDebugFeatureStack; -	  	/////////////////////////////////////////////  	//  	// @@ -912,6 +913,7 @@ public:  	static U32 RenderResolutionDivisor;  	static bool RenderUIBuffer;  	static S32 RenderShadowDetail; +    static S32 RenderShadowSplits;  	static bool RenderDeferredSSAO;  	static F32 RenderShadowResolutionScale;  	static bool RenderLocalLights; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 8bb3feaeb0..6efe302f30 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -983,12 +983,15 @@      name="OutfitGalleryItemUnselected"      value="0.4 0.4 0.4 1" />    <color -    name="AddPaymentPanel" +    name="PanelGray"      value="0.27 0.27 0.27 1" />    <color +    name="PerformanceMid" +    value="1 0.8 0 1" /> +  <color      name="OutfitSnapshotMacMask"      value="0.115 0.115 0.115 1"/> - <color -   name="OutfitSnapshotMacMask2" -   value="0.1 0.1 0.1 1"/> +  <color +    name="OutfitSnapshotMacMask2" +    value="0.1 0.1 0.1 1"/>  </colors> diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1f2c0867c4..72c8f03017 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -150,6 +150,7 @@ with the same filename but different name    <texture name="Command_Move_Icon"         file_name="toolbar_icons/move.png"         preload="true" />    <texture name="Command_Environments_Icon" file_name="toolbar_icons/environments.png" preload="true" />    <texture name="Command_People_Icon"       file_name="toolbar_icons/people.png"       preload="true" /> +  <texture name="Command_Performance_Icon"  file_name="toolbar_icons/performance.png"  preload="true" />    <texture name="Command_Picks_Icon"        file_name="toolbar_icons/picks.png"        preload="true" />    <texture name="Command_Places_Icon"       file_name="toolbar_icons/places.png"       preload="true" />    <texture name="Command_Preferences_Icon"  file_name="toolbar_icons/preferences.png"  preload="true" /> diff --git a/indra/newview/skins/default/textures/toolbar_icons/performance.png b/indra/newview/skins/default/textures/toolbar_icons/performance.pngBinary files differ new file mode 100644 index 0000000000..91baf849c8 --- /dev/null +++ b/indra/newview/skins/default/textures/toolbar_icons/performance.png diff --git a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml index 1f980564d4..ac88263aa1 100644 --- a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml +++ b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml @@ -19,7 +19,7 @@    </floater.string>    <panel     background_opaque="false" -   bg_alpha_color="AddPaymentPanel" +   bg_alpha_color="PanelGray"     border_visible="false"     background_visible="true"     label="wrapper_panel" diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml index e088d4d2a1..d222dca98b 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml @@ -10,7 +10,7 @@   save_rect="true"   single_instance="true"   reuse_instance="true" - title="AVATAR RENDER SETTINGS" + title="AVATAR DISPLAY EXCEPTIONS"   width="300">      <string       name="av_never_render" @@ -18,53 +18,45 @@      <string       name="av_always_render"       value="Always"/> -    <filter_editor -     follows="left|top|right" -     height="23" -     layout="topleft" -     left="8" -     right="-47" -     label="Filter People" -     max_length_chars="300" -     name="people_filter_input" -     text_color="Black" -     text_pad_left="10" -     top="4" /> -    <menu_button -     follows="top|right" -     height="25" -     image_hover_unselected="Toolbar_Middle_Over" -     image_overlay="AddItem_Off" -     image_selected="Toolbar_Middle_Selected" -     image_unselected="Toolbar_Middle_Off" -     layout="topleft" -     left_pad="7" -     menu_filename="menu_avatar_rendering_settings_add.xml" -     menu_position="bottomleft" -     name="plus_btn" -     tool_tip="Actions on selected person" -     top="3" -     width="31" />      <name_list -     bottom="-8" +     bottom="-33"       draw_heading="true"       follows="all"       left="8"       multi_select="false"       name="render_settings_list"       right="-8" -     top="32"> +     top="0">          <name_list.columns           label="Name"           name="name" -         relative_width="0.5" /> +         relative_width="0.65" />          <name_list.columns -         label="Render setting" +         label="Full detail"           name="setting" -         relative_width="0.25" /> -        <name_list.columns -         label="Date added" -         name="timestamp" -         relative_width="0.25" /> +         relative_width="0.35" />       </name_list> +    <panel +     bg_alpha_color="ScrollBgWriteableColor" +     background_visible="true" +     background_opaque="false" +     bevel_style="none" +     follows="bottom|left|right" +     name="add_subpanel" +     layout="topleft" +     height="28" +     top_pad="0"> +     <menu_button +       follows="bottom|left" +       height="25" +       label="Add someone..." +       layout="topleft" +       menu_filename="menu_avatar_rendering_settings_add.xml" +       menu_position="bottomleft" +       name="plus_btn" +       tool_tip="Actions on selected person" +       top="1" +       left="8" +       width="120" /> +     </panel>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml new file mode 100644 index 0000000000..d1a1119f77 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_performance.xml @@ -0,0 +1,368 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + height="642" + layout="topleft" + name="performance" + save_rect="true" + reuse_instance="true" + title="IMPROVE GRAPHICS SPEED" + width="580"> +  <string +   name="fps_text" +   value="frames per second"/> +  <string +   name="max_text" +   value=" (maximum)"/> +  <panel +   bevel_style="none" +   follows="left|top" +   height="540" +   width="580" +   name="panel_top" +   visible="true" +   layout="topleft" +   left="0"    +   top="0"> +    <panel +     bg_alpha_color="black" +     background_visible="true" +     background_opaque="false" +     border="false" +     bevel_style="none" +     follows="left|top" +     height="40" +     width="560" +     name="fps_subpanel" +     layout="topleft" +     left="10" +     top="5"> +      <text +       follows="left|top" +       font="SansSerifHuge" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       top="8" +       name="fps_value" +       width="42"> +          167 +      </text> +      <text +       follows="left|top" +       font="SansSerifLarge" +       text_color="White" +       height="20" +       layout="topleft" +       left_pad="3" +       top="13" +       name="fps_lbl" +       width="450"> +          frames per second +      </text> +      <text +       follows="left|top" +       text_color="White" +       height="20" +       layout="topleft" +       left="395" +       top="7" +       name="fps_desc1_lbl" +       width="150"> +        Allow 5-10 seconds for +      </text> +      <text +       follows="left|top" +       text_color="White" +       height="20" +       layout="topleft" +       top_pad="-3" +       name="fps_desc2_lbl" +       width="150"> +        changes to take full effect. +      </text> +    </panel> +  </panel> +  <panel +   bevel_style="none" +   follows="left|top" +   height="540" +   width="580" +   name="panel_performance_main" +   visible="true" +   layout="topleft" +   left="0"    +   top="60">     +    <panel +     bg_alpha_color="PanelGray" +     background_visible="true" +     background_opaque="false" +     border="true" +     bevel_style="none" +     follows="left|top" +     height="50" +     width="560" +     name="autoadjustments_subpanel" +     layout="topleft" +     left="10" +     top="5"> +        <text +         follows="left|top" +         font="SansSerifBoldLarge" +         text_color="White" +         height="20" +         layout="topleft" +         left="10" +         name="auto_adj_lbl" +         top="7" +         width="375"> +         Auto-adjust settings (recommended) +        </text> +        <text +         follows="left|top" +         font="SansSerif" +         text_color="White" +         height="20" +         layout="topleft" +         left="10" +         name="auto_adj_desc" +         top_pad="0" +         width="485"> +         Allow automatic adjustments to reach your preferred frame rate. +        </text> +        <icon +         height="16" +         width="16" +         image_name="Arrow_Right_Off" +         mouse_opaque="true" +         name="icon_arrow4" +         follows="right|top" +         top="19" +         right="-20"/> +    </panel> +    <panel +     bg_alpha_color="PanelGray" +     background_visible="true" +     background_opaque="false" +     border="true" +     bevel_style="none" +     follows="left|top" +     height="50" +     width="560" +     name="settings_subpanel" +     layout="topleft" +     top_pad="10"> +        <text +         follows="left|top" +         font="SansSerifLarge" +         text_color="White" +         height="20" +         layout="topleft" +         left="10" +         name="settings_lbl" +         top="7" +         width="180"> +          Graphics settings +        </text> +        <text +         follows="left|top" +         font="SansSerif" +         text_color="White" +         height="20" +         layout="topleft" +         left="10" +         name="settings_desc" +         top_pad="0" +         width="395"> +          Choose settings for distance, water, lighting and more. +        </text> +        <icon +         height="16" +         width="16" +         image_name="Arrow_Right_Off" +         mouse_opaque="true" +         name="icon_arrow3" +         follows="right|top" +         top="19" +         right="-20"/> +      </panel> +    <panel +     bg_alpha_color="PanelGray" +     background_visible="true" +     background_opaque="false" +     border="true" +     bevel_style="none" +     follows="left|top" +     height="50" +     width="560" +     name="nearby_subpanel" +     layout="topleft" +     top_pad="10"> +      <text +       follows="left|top" +       font="SansSerifLarge" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       name="avatars_nearby_lbl" +       top="7" +       width="205"> +          Avatars nearby +      </text> +      <text +       follows="left|top" +       font="SansSerif" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       name="avatars_nearby_desc" +       top_pad="0" +       width="395"> +          Manage which nearby avatars are fully displayed. +      </text> +      <icon +       height="16" +       width="16" +       image_name="Arrow_Right_Off" +       mouse_opaque="true" +       name="icon_arrow2" +       follows="right|top" +       top="19" +       right="-20"/> +    </panel> +    <panel +     bg_alpha_color="PanelGray" +     background_visible="true" +     background_opaque="false" +     border="true" +     bevel_style="none" +     follows="left|top" +     height="50" +     width="560" +     name="complexity_subpanel" +     layout="topleft" +     top_pad="10"> +      <text +       follows="left|top" +       font="SansSerifLarge" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       name="complexity_lbl" +       top="7" +       width="180"> +          Your avatar complexity +      </text> +      <text +       follows="left|top" +       font="SansSerif" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       name="complexity_info" +       top_pad="0" +       width="455"> +          Reduce the complexity of your avatar if you aren't satisfied with current FPS. +      </text> +      <icon +       height="16" +       width="16" +       image_name="Arrow_Right_Off" +       mouse_opaque="true" +       name="icon_arrow4" +       follows="right|top" +       top="19" +       right="-20"/> +    </panel> +    <panel +     bg_alpha_color="PanelGray" +     background_visible="true" +     background_opaque="false" +     border="true" +     bevel_style="none" +     follows="left|top" +     height="50" +     width="560" +     name="huds_subpanel" +     layout="topleft" +     top_pad="10"> +      <text +       follows="left|top" +       font="SansSerifLarge" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       name="huds_lbl" +       top="7" +       width="135"> +          Your active HUDs +      </text> +      <text +       follows="left|top" +       font="SansSerif" +       text_color="White" +       height="20" +       layout="topleft" +       left="10" +       name="huds_desc" +       top_pad="0" +       width="395"> +          Removing HUDs you are not using can improve speed. +      </text> +      <icon +       height="16" +       width="16" +       image_name="Arrow_Right_Off" +       mouse_opaque="true" +       name="icon_arrow4" +       follows="right|top" +       top="19" +       right="-20"/> +    </panel> +  </panel> +  <panel +    filename="panel_performance_nearby.xml" +    follows="all" +    layout="topleft" +    left="0" +    name="panel_performance_nearby" +    visible="false" +    top="55" /> +  <panel +    filename="panel_performance_complexity.xml" +    follows="all" +    layout="topleft" +    left="0" +    name="panel_performance_complexity" +    visible="false" +    top="55" /> +  <panel +    filename="panel_performance_preferences.xml" +    follows="all" +    layout="topleft" +    left="0" +    name="panel_performance_preferences" +    visible="false" +    top="55" /> +  <panel +    filename="panel_performance_huds.xml" +    follows="all" +    layout="topleft" +    left="0" +    name="panel_performance_huds" +    visible="false" +    top="55" /> +  <panel +    filename="panel_performance_autoadjustments.xml" +    follows="all" +    layout="topleft" +    left="0" +    name="panel_performance_autoadjustments" +    visible="false" +    top="55" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index d1e167df64..11c2d11987 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -39,7 +39,8 @@      max_val="512"      name="DrawDistance"      top_delta="16" -    width="330" /> +    width="330"> +    </slider>    <text      type="string"      length="1" @@ -521,8 +522,8 @@      label_width="185"      layout="topleft"      left="420" -    min_val="1" -    max_val="2" +    min_val="0" +    max_val="4"      name="ObjectMeshDetail"      show_text="false"      top_delta="16" diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml index 2abd8ec5c0..37efbe654e 100644 --- a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml @@ -410,6 +410,59 @@            </stat_view>  			  </stat_view>  		  </stat_view> +      <stat_view  +        name="frame_stats" +        label="Frame breakdown" +        show_label="true"> +          <stat_bar name="packet_loss" +            label="Scenery" +            orientation="horizontal" +            unit_label=" %" +            stat="scenery_frame_pct" +            bar_max="100" +            tick_spacing="0.5" +            show_bar="false"/> +          <stat_bar name="packet_loss" +            label="Avatar" +            orientation="horizontal" +            unit_label=" %" +            stat="avatar_frame_pct" +            bar_max="100" +            tick_spacing="0.5" +            show_bar="false"/> +          <stat_bar name="packet_loss" +            label="UI" +            orientation="horizontal" +            unit_label=" %" +            stat="ui_frame_pct" +            bar_max="100" +            tick_spacing="0.5" +            show_bar="false"/> +          <stat_bar name="packet_loss" +            label="HUDs" +            orientation="horizontal" +            unit_label=" %" +            stat="huds_frame_pct" +            bar_max="100" +            tick_spacing="0.5" +            show_bar="false"/> +        <stat_bar name="packet_loss" +            label="Swap" +            orientation="horizontal" +            unit_label=" %" +            stat="swap_frame_pct" +            bar_max="100" +            tick_spacing="0.5" +            show_bar="false"/> +        <stat_bar name="packet_loss" +            label="Tasks" +            orientation="horizontal" +            unit_label=" %" +            stat="idle_frame_pct" +            bar_max="100" +            tick_spacing="0.5" +            show_bar="false"/> +      </stat_view>      </container_view>    </scroll_container>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 7ad692038e..22006c287f 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -131,22 +131,12 @@     <menu_item_separator />        <context_menu -       label="Render Avatar" +       label="Display this avatar"         layout="topleft" -        name="Render Avatar"> -      <menu_item_check -        name="RenderNormally" -        label="Default"> -        <menu_item_check.on_check -          function="Avatar.CheckImpostorMode" -          parameter="0" /> -	    <menu_item_check.on_click -	      function="Avatar.SetImpostorMode" -	      parameter="0" /> -      </menu_item_check> +       name="Render Avatar">        <menu_item_check          name="AlwaysRenderFully" -        label="Always"> +        label="Always full detail">          <menu_item_check.on_check            function="Avatar.CheckImpostorMode"            parameter="2" /> @@ -156,7 +146,7 @@        </menu_item_check>        <menu_item_check          name="DoNotRender" -        label="Never"> +        label="Never full detail">          <menu_item_check.on_check            function="Avatar.CheckImpostorMode"            parameter="1" /> @@ -164,6 +154,16 @@  	      function="Avatar.SetImpostorMode"  	      parameter="1" />        </menu_item_check> +      <menu_item_call +        name="RenderNormally" +        label="Remove from exceptions"> +          <menu_item_call.on_visible +            function="Avatar.CheckImpostorMode" +            parameter="4" /> +          <menu_item_call.on_click +            function="Avatar.SetImpostorMode" +            parameter="0" /> +      </menu_item_call>        <menu_item_separator />        <menu_item_call          label="Exceptions..." diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index acbb9b860d..665eb9a82f 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -122,39 +122,39 @@     <menu_item_separator />   <context_menu -       label="Render Avatar" +       label="Display this avatar"         layout="topleft" -        name="Render Avatar"> -      <menu_item_check -        name="RenderNormally" -        label="Default"> -        <menu_item_check.on_check -          function="Avatar.CheckImpostorMode" -          parameter="0" /> -	    <menu_item_check.on_click -	      function="Avatar.SetImpostorMode" -	      parameter="0" /> -      </menu_item_check> -      <menu_item_check -        name="AlwaysRenderFully" -        label="Always"> -        <menu_item_check.on_check -          function="Avatar.CheckImpostorMode" -          parameter="2" /> -	    <menu_item_check.on_click -	      function="Avatar.SetImpostorMode" -	      parameter="2" /> -      </menu_item_check> -      <menu_item_check -        name="DoNotRender" -        label="Never"> -        <menu_item_check.on_check -          function="Avatar.CheckImpostorMode" -          parameter="1" /> -	    <menu_item_check.on_click -	      function="Avatar.SetImpostorMode" -	      parameter="1" /> -      </menu_item_check> +       name="Render Avatar"> +       <menu_item_check +         name="AlwaysRenderFully" +         label="Always full detail"> +         <menu_item_check.on_check +           function="Avatar.CheckImpostorMode" +           parameter="2" /> +         <menu_item_check.on_click +           function="Avatar.SetImpostorMode" +           parameter="2" /> +       </menu_item_check> +       <menu_item_check +         name="DoNotRender" +         label="Never full detail"> +         <menu_item_check.on_check +           function="Avatar.CheckImpostorMode" +           parameter="1" /> +         <menu_item_check.on_click +           function="Avatar.SetImpostorMode" +           parameter="1" /> +       </menu_item_check> +       <menu_item_call +         name="RenderNormally" +         label="Remove from exceptions"> +         <menu_item_call.on_visible +           function="Avatar.CheckImpostorMode" +           parameter="4" /> +         <menu_item_call.on_click +           function="Avatar.SetImpostorMode" +           parameter="0" /> +       </menu_item_call>        <menu_item_separator />        <menu_item_call          label="Exceptions..." diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml index 5163cd3115..1a18483418 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml @@ -3,24 +3,25 @@   layout="topleft"   name="Settings">      <menu_item_check -     label="Default" -     layout="topleft" -     name="default"> -        <on_click function="Settings.SetRendering" parameter="default"/> -	<on_check function="Settings.IsSelected" parameter="default" />   -    </menu_item_check> -    <menu_item_check -     label="Always render" +     label="Always full detail"       layout="topleft"       name="always_render">          <on_click function="Settings.SetRendering" parameter="always"/> -	<on_check function="Settings.IsSelected" parameter="always" />   +        <on_check function="Settings.IsSelected" parameter="always" />        </menu_item_check>      <menu_item_check -     label="Never render" +     label="Never full detail"       layout="topleft"       name="never_render">          <on_click function="Settings.SetRendering" parameter="never"/> -	<on_check function="Settings.IsSelected" parameter="never" />   -    </menu_item_check>   +        <on_check function="Settings.IsSelected" parameter="never" /> +    </menu_item_check> +    <menu_item_check +     label="Remove from exceptions" +     layout="topleft" +     name="default"> +        <on_click function="Settings.SetRendering" parameter="default"/> +        <on_check function="Settings.IsSelected" parameter="default" /> +        <on_visible function="Settings.IsSelected" parameter="non_default" /> +  </menu_item_check>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml index c64b24ed70..6e09eb5981 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml @@ -4,13 +4,13 @@       left="0" bottom="0" visible="false"       mouse_opaque="false">    <menu_item_call -   label="Always Render a Resident..." +   label="Always full detail..."     name="add_avatar_always_render">        <on_click         function="Settings.AddNewEntry" parameter="always"/>    </menu_item_call>    <menu_item_call -   label="Never Render a Resident..." +   label="Never full detail..."     name="add_avatar_never_render">        <on_click         function="Settings.AddNewEntry"  parameter="never"/> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 64167a9a5d..7db316f498 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -884,7 +884,16 @@                 parameter="UseDebugMenus" />            </menu_item_check>          </menu> - +        <menu_item_check +          label="Improve graphics speed..." +          name="Performance"> +          <menu_item_check.on_click +           function="Floater.Toggle" +           parameter="performance" /> +          <menu_item_check.on_check +           function="Floater.Visible" +           parameter="performance" /> +        </menu_item_check>          <menu_item_separator/>      <!--    <menu_item_check           label="Show Navigation Bar" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d1a99133f0..f9211600ea 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1900,6 +1900,41 @@ Graphics Quality can be raised in Preferences > Graphics.    <notification     icon="alertmodal.tga" +   name="AutoFPSConfirmDisable" +   type="alertmodal"> +Changing this setting will disable automatic adjustment and turn off 'Automatic settings'. +Are you sure you want to continue? +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="Continue"/> +  </notification> +  <notification +   icon="alertmodal.tga" +   name="AdvancedLightingConfirm" +   type="alertmodal"> +To turn on advanced lighting, we need to increase quality to level 4. +    <tag>confirm</tag> +  <usetemplate +   name="okcancelbuttons" +   notext="Cancel" +   yestext="OK"/> +  </notification> +  <notification + icon="alertmodal.tga" +   name="ShadowsConfirm" +   type="alertmodal"> +To enable shadows, we need to increase quality to level 4. +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="RegionNoTerraforming"     type="alertmodal">  The region [REGION] does not allow terraforming. @@ -11930,4 +11965,18 @@ If you want others to see this object, remove it and re-attach it to an avatar a          yestext="OK"/>    </notification> +  <notification +   icon="alertmodal.tga" +   name="EnableAutoFPSWarning" +   type="alertmodal"> +You are about to enable AutoFPS. All unsaved graphics settings will be lost. + +Would you like to save them first? +      <tag>confirm</tag> +      <usetemplate +       name="okcancelbuttons" +       notext="No" +       yestext="Yes"/> +  </notification> +      </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml new file mode 100644 index 0000000000..904ce1cc52 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml @@ -0,0 +1,387 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="left|top" + height="580" + width="580" + name="panel_performance_autoadjustments" + layout="topleft" + left="0" + top="0"> +  <button +    height="16" +    width="16" +    layout="topleft" +    mouse_opaque="true" +    follows="left|top" +    name="back_btn" +    top="7" +    image_selected="Arrow_Left_Off" +    image_pressed="Arrow_Left_Off" +    image_unselected="Arrow_Left_Off" +    left="15" +    is_toggle="true"> +  </button> +  <text +   follows="left|top" +   height="18" +   layout="topleft" +   left_pad="0" +   valign="center" +   halign="center" +   top="6" +   name="back_lbl" +   width="32"> +    Back +  </text> +  <text +   follows="left|top" +   font="SansSerifLarge" +   text_color="white" +   height="20" +   layout="topleft" +   left="20" +   top_pad="15" +   name="settings_title" +   width="300"> +    Auto-adjust settings +  </text> +  <button +   follows="top|left" +   height="23" +   label="Reset to recommended settings" +   layout="topleft" +   left="360" +   name="defaults_btn" +   top_delta="0" +   width="200"/> +  <view_border +   bevel_style="in" +   height="0" +   layout="topleft" +   name="border0" +   top_pad="15" +   left="20" +   width="540"/> +  <text +   follows="left|top" +   font="SansSerif" +   text_color="White" +   height="20" +   layout="topleft" +   left="20" +   name="targetfps_desc" +   wrap="true" +   width="115" +   top_pad="20"> +    Desired frame rate +  </text> +  <spinner +   name="target_fps" +   control_name="TargetFPS" +   font="SansSerifLarge" +   tool_tip="The viewer will attempt to achieve this by adjusting your graphics settings." +   layout="topleft" +   follows="left|top" +   left_pad="25" +   top_delta="0" +   height="25" +   visible="true" +   decimal_digits="0" +   increment="1" +   initial_value="25" +   max_val="300" +   min_val="1" +   width="48" +   label_width="0" /> + <text +   follows="left|top" +   text_color="White" +   height="20" +   layout="topleft" +   name="display_desc" +   top_delta="5" +   left_pad="15" +   wrap="true" +   width="225"> +  Your display supports up to [FPS_LIMIT] fps. +  </text> +  <text +   follows="left|top" +   font="SansSerif" +   text_color="White" +   height="20" +   layout="topleft" +   left="20" +   name="settings_desc" +   top_pad="15" +   wrap="true" +   width="115"> +    Settings affect +  </text> +  <combo_box +   follows="top|left" +   font="SansSerif" +   height="20" +   layout="topleft" +   left_pad="25" +   control_name="TuningFPSStrategy" +   name="TuningFPSStrategy" +   width="160"> +    <combo_box.item +     label="Avatars Only" +     name="av_only" +     value="0" /> +    <combo_box.item +     label="Avatars and World" +     name="av_and_scene" +     value="1" /> +	<combo_box.item +     label="World Only" +     name="scene_only" +     value="2" /> +  </combo_box> +  <button +   follows="top|left" +   height="22" +   image_pressed="PushButton_Press" +   image_pressed_selected="PushButton_Selected_Press" +   image_selected="PushButton_Selected_Press" +   label="Auto-adjust now" +   layout="topleft" +   top_pad="15" +   left="20" +   name="start_autotune" +   tool_tip="The viewer will attempt to adjust settings to meet the target FPS then stop." +   width="124"/> +  <button +   follows="top|left" +   height="22" +   image_pressed="PushButton_Press" +   image_pressed_selected="PushButton_Selected_Press" +   image_selected="PushButton_Selected_Press" +   label="Cancel" +   layout="topleft" +   left_pad="15" +   name="stop_autotune" +   tool_tip="Stop adjusting settings." +   width="90"/> +  <text +   follows="left|top" +   text_color="Yellow" +   height="20" +   layout="topleft" +   name="wip_desc" +   top_delta="5" +   left_pad="20" +   wrap="true" +   width="115"> +  Working on it... +  </text> +  <check_box +   control_name="AutoTuneLock" +   follows="top|left" +   height="20" +   initial_value="true" +   image_pressed="PushButton_Press" +   image_pressed_selected="PushButton_Selected_Press" +   image_selected="PushButton_Selected_Press" +   is_toggle="true" +   label="Adjust continuously" +   layout="topleft" +   left="17" +   top_pad="10" +   name="AutoTuneContinuous" +   tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed." +   width="64"> +  </check_box> +  <radio_group +   control_name="KeepAutoTuneLock" +   enabled_control="AutoTuneLock" +   height="50" +   layout="topleft" +   follows="top|left" +   name="autotune_lock_type" +   top_pad="5" +   left_delta="15" +   width="120"> +    <radio_item +     height="16" +     label="This login session only" +     layout="topleft" +     name="one_session_lock" +     value="0" +     width="120" /> +    <radio_item +     height="16" +     label="Future login sessions" +     layout="topleft" +     name="next_session_lock" +     value="1" +     width="120" /> +  </radio_group> +  <view_border +   bevel_style="in" +   height="0" +   layout="topleft" +   name="border_vsync" +   top_pad="3" +   left="20" +   width="540"/> +  <check_box +   control_name="RenderVSyncEnable" +   height="16" +   left="17" +   initial_value="true" +   label="Enable VSync" +   label_text.text_color="White" +   layout="topleft" +   top_pad="12" +   name="vsync" +   tool_tip="Enable Vertical synchronization to reduce screen tearing and stuttering." +   width="315" /> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left="20" +   top_pad="15" +   name="vsync_desc" +   width="580"> +    Matches monitor refresh rate with frame rate. +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="3" +   left="20" +   name="vsync_desc_limit" +   width="580"> +    Note: Turning on VSync limits frame rate to [FPS_LIMIT] fps. +  </text> +  <view_border +   bevel_style="in" +   height="0" +   layout="topleft" +   name="border1" +   top_pad="10" +   left="20" +   width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left="20" +   top_pad="15" +   name="simplify_dist_desc" +   width="580"> +    Reducing detail shown on avatars that are far away will improve graphics speed. +  </text> +  <check_box +   control_name="AutoTuneImpostorByDistEnabled" +   height="19" +   label="Simplify avatars beyond" +   label_text.text_color="White" +   layout="topleft" +   follows="top|left" +   name="AutoTuneImpostorByDistEnabled" +   tool_tip="When enabled the viewer will adjust the MaxNonImpostors setting to limit fully rendered avatars to those within the defined radius." +   top_pad="15" +   width="190" /> +  <spinner +   control_name="AutoTuneImpostorFarAwayDistance" +   height="20" +   layout="topleft" +   follows="top|left" +   name="ffa_autotune" +   left_pad="20" +   decimal_digits="2" +   min_val="16" +   max_val="256" +   width="60" > +  </spinner> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left_pad="10" +   name="dist_meters" +   width="70"> +    meters +  </text> +  <view_border +   bevel_style="in" +   height="0" +   layout="topleft" +   name="border2" +   top_pad="20" +   left="20" +   width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left="20" +   top_pad="15" +   name="dist_limits_desc" +   width="580"> +    Choose the distance range that automatic settings will affect. +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="15" +   name="min_dist_lbl" +   width="120"> +    Minimum distance +  </text> +  <spinner +   control_name="AutoTuneRenderFarClipMin" +   height="20" +   layout="topleft" +   left_pad="15" +   follows="top|left" +   name="min_dd_autotune" +   decimal_digits="2" +   min_val="32" +   max_val="256" +   width="60"> +  </spinner> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="15" +   left="20" +   name="pref_dist_lbl" +   width="120"> +    Maximum distance +  </text> +  <spinner +   control_name="AutoTuneRenderFarClipTarget" +   height="20" +   layout="topleft" +   follows="top|left" +   name="pref_dd_autotune" +   left_pad="15" +   min_val="32" +   max_val="256" +   width="60"> +  </spinner> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml new file mode 100644 index 0000000000..cd3f610a92 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="left|top" + height="580" + width="580" + name="panel_performance_complexity" + layout="topleft" + left="0" + top="0"> +  <button +    height="16" +    width="16" +    layout="topleft" +    mouse_opaque="true" +    follows="left|top" +    name="back_btn" +    top="7" +    image_selected="Arrow_Left_Off" +    image_pressed="Arrow_Left_Off" +    image_unselected="Arrow_Left_Off" +    left="15" +    is_toggle="true"> +  </button> +  <text +   follows="left|top" +   height="18" +   layout="topleft" +   left_pad="0" +   valign="center" +   halign="center" +   top="6" +   name="back_lbl" +   width="32"> +    Back +  </text> +  <text +   follows="left|top" +   font="SansSerifLarge" +   text_color="white" +   height="20" +   layout="topleft" +   left="20" +   top_pad="15" +   name="attachments_title" +   width="195"> +    Your avatar complexity  +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="5" +   left="20" +   name="attachments_desc1" +   width="580"> +    Attachments make your avatar more complex. If your avatar is very complex, some other  +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="3" +   left="20" +   name="attachments_desc2" +   width="580"> +    people may not see you in full detail, and your graphics speed may be reduced. Removing +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="3" +   left="20" +   name="attachments_desc3" +   width="580"> +    heavy attachments that you don’t need can help. +  </text> +  <name_list +    column_padding="0" +    draw_stripes="true" +    height="429" +    follows="left|top" +    layout="topleft" +    name="obj_list" +    top_pad="10" +    width="540"> +      <name_list.columns +       label="" +       name="complex_visual" +       width="90" /> +      <name_list.columns +       label="" +       name="complex_value" +       width="40" /> +      <name_list.columns +       label="" +       name="name"/> +  </name_list> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml new file mode 100644 index 0000000000..2fddcb3b9e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="left|top" + height="580" + width="580" + name="panel_performance_huds" + layout="topleft" + left="0" + top="0"> +  <button +    height="16" +    width="16" +    layout="topleft" +    mouse_opaque="true" +    follows="left|top" +    name="back_btn" +    top="7" +    image_selected="Arrow_Left_Off" +    image_pressed="Arrow_Left_Off" +    image_unselected="Arrow_Left_Off" +    left="15" +    is_toggle="true"> +  </button> +  <text +   follows="left|top" +   height="18" +   layout="topleft" +   left_pad="0" +   valign="center" +   halign="center" +   top="6" +   name="back_lbl" +   width="32"> +    Back +  </text> +  <text +   follows="left|top" +   font="SansSerifLarge" +   text_color="White" +   height="20" +   layout="topleft" +   left="20" +   top_pad="15" +   name="huds_title" +   width="135"> +    Your active HUDs +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="5" +   left="20" +   name="huds_desc1" +   width="540"> +    Detaching HUDs you aren't using saves memory and can make Second Life run faster. +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="3" +   left="20" +   name="huds_desc2" +   width="540"> +    Note: Using a HUD's minimize button does not detach it.  +  </text> +  <name_list +    column_padding="0" +    draw_stripes="true" +    height="450" +    follows="left|top" +    layout="topleft" +    name="hud_list" +    top_pad="10" +    width="540"> +        <name_list.columns +         label="" +         name="complex_visual" +         width="90" /> +        <name_list.columns +         label="" +         name="complex_value" +         width="40" /> +        <name_list.columns +         label="" +         name="name"/> +  </name_list> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml new file mode 100644 index 0000000000..cb795e59a9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml @@ -0,0 +1,216 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="left|top" + height="530" + width="580" + name="panel_performance_nearby" + layout="topleft" + left="0" + top="0"> +  <button +    height="16" +    width="16" +    layout="topleft" +    mouse_opaque="true" +    follows="left|top" +    name="back_btn" +    top="7" +    image_selected="Arrow_Left_Off" +    image_pressed="Arrow_Left_Off" +    image_unselected="Arrow_Left_Off" +    left="15" +    is_toggle="true"> +  </button> +  <text +   follows="left|top" +   height="18" +   layout="topleft" +   left_pad="0" +   valign="center" +   halign="center" +   top="6" +   name="back_lbl" +   width="32"> +    Back +  </text> +  <text +   follows="left|top" +   font="SansSerifLarge" +   text_color="White" +   height="20" +   layout="topleft" +   left="20" +   top_pad="15" +   name="av_nearby_title" +   width="205"> +    Avatars nearby +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left="20" +   top_pad="5" +   name="av_nearby_desc" +   width="580"> +    Hide the most complex avatars to boost speed. +  </text> +  <slider +    control_name="RenderAvatarMaxART" +    tool_tip="Controls when a visually complex avatar is considered to be taking too long to render (unit: microseconds)" +    follows="left|top" +    height="16" +    initial_value="4.7" +    increment="0.01" +    label="Maximum render time (μs)" +    text_color="White" +    label_width="165" +    layout="topleft" +    min_val="2" +    max_val="4.7" +    name="RenderAvatarMaxART" +    show_text="false" +    top_pad="10" +    width="490"> +  </slider> +  <text +    type="string" +    length="1" +    follows="left|top" +    height="16" +    layout="topleft" +    top_delta="0" +    left_pad="5" +    text_color="White" +    name="RenderAvatarMaxARTText" +    width="65"> +    no limit +  </text> +  <name_list +    column_padding="0" +    draw_stripes="true" +    height="280" +    left="20" +    follows="left|top" +    layout="topleft" +    sort_column="complex_value" +    short_names="true" +    name="nearby_list" +    name_column="name" +    top_pad="10" +    width="540"> +        <name_list.columns +         label="" +         name="complex_visual" +         width="90" /> +        <name_list.columns +         label="" +         name="complex_value" +         width="50" /> +        <name_list.columns +         label="" +         name="name"/> +  </name_list> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left="20" +   top_pad="10" +   name="av_nearby_desc2" +   width="580"> +     You can also right-click on an avatar in-world to control display. +  </text> +  <button +    height="23" +    label="Exceptions..." +    layout="topleft" +    left="460" +    top_delta="2" +    name="exceptions_btn" +    width="100"> +  </button> +  <check_box +    control_name="AlwaysRenderFriends" +    height="16" +    initial_value="true" +    label="Always display friends in full detail" +    label_text.text_color="White" +    layout="topleft" +    name="display_friends" +    top_pad="3" +    left="18" +    width="256"> +  </check_box> +  <view_border +    bevel_style="in" +    height="0" +    layout="topleft" +    name="border" +    top_pad="15" +    left="20" +    width="540"/> +  <check_box +    height="16" +    initial_value="true" +    label="Hide avatars completely (good for landscape photos)" +    layout="topleft" +    name="hide_avatars" +    top_delta="15" +    left="18" +    width="280"> +   </check_box> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="15" +   layout="topleft" +   left="20" +   name="name_tags_textbox" +   top_pad="10" +   width="400"> +    Name tags: +  </text> +  <radio_group +    control_name="AvatarNameTagMode" +    height="20" +    layout="topleft" +    left="120" +    top_delta="0" +    name="name_tag_mode"> +    <radio_item +     label="Off" +     name="radio" +     top_delta="20" +     layout="topleft" +     height="16" +     left="0" +     value="0" +     width="75" /> +    <radio_item +     label="On" +     left_pad="0" +     layout="topleft" +     top_delta="0" +     height="16" +     name="radio2" +     value="1" +     width="75" /> +    <radio_item +     label="Show briefly" +     left_pad="0" +     name="radio3" +     height="16" +     layout="topleft" +     top_delta="0" +     value="2" +     width="160" /> +  </radio_group> +  +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml new file mode 100644 index 0000000000..b52c19d5e3 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml @@ -0,0 +1,565 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + bevel_style="none" + follows="left|top" + height="580" + width="580" + name="panel_performance_preferences" + layout="topleft" + left="0" + top="0"> +  <button +    height="16" +    width="16" +    layout="topleft" +    mouse_opaque="true" +    follows="left|top" +    name="back_btn" +    top="7" +    image_selected="Arrow_Left_Off" +    image_pressed="Arrow_Left_Off" +    image_unselected="Arrow_Left_Off" +    left="15" +    is_toggle="true"> +  </button> +  <text +   follows="left|top" +   height="18" +   layout="topleft" +   left_pad="0" +   valign="center" +   halign="center" +   top="6" +   name="back_lbl" +   width="32"> +    Back +  </text> +  <text +   follows="left|top" +   font="SansSerifLarge" +   text_color="white" +   height="20" +   layout="topleft" +   left="20" +   top_pad="15" +   name="settings_title" +   width="300"> +    Graphics settings +  </text> +  <button +   follows="top|left" +   height="23" +   label="Open Advanced Settings" +   layout="topleft" +   left="360" +   name="advanced_btn" +   top_delta="-35" +   width="200"/> +  <button +   follows="top|left" +   height="23" +   label="Reset to recommended settings" +   layout="topleft" +   left="350" +   name="defaults_btn" +   top_pad="10" +   width="210"/> +  <view_border +   bevel_style="in" +   height="0" +   layout="topleft" +   name="border0" +   top_pad="8" +   left="20" +   width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="30" +   name="quality_lbl" +   width="100"> +    Quality & Speed +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left_pad="40" +   name="fastest_lbl" +   width="40"> +    Fastest +  </text> +  <radio_group +   control_name="RenderQualityPerformance" +   follows="top|left" +   draw_border="false" +   height="25" +   layout="topleft" +   left_pad="5" +   name="graphics_quality" +   top_delta="0" +   width="243"> +    <radio_item +     height="16" +     layout="topleft" +     left="3" +     name="0" +     top="0" +     width="7" /> +    <radio_item +     height="16" +     layout="topleft" +     left_pad="30" +     name="1" +     width="7" /> +    <radio_item +     height="16" +     layout="topleft" +     left_pad="30" +     name="2" +     width="7" /> +    <radio_item +     height="16" +     layout="topleft" +     left_pad="30" +     name="3" +     width="7" /> +    <radio_item +     height="16" +     layout="topleft" +     left_pad="30" +     name="4" +     width="7" /> +    <radio_item +     height="16" +     layout="topleft" +     left_pad="30" +     name="5" +     width="7" /> +    <radio_item +     height="16" +     layout="topleft" +     left_pad="30" +     name="6" +     width="7" /> +  </radio_group> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left_pad="10" +   top_delta="1" +   name="quality_lbl" +   width="70"> +    Best quality +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="15" +   left="160" +   name="quality_desc" +   width="380"> +    Choosing a shortcut will reset all manual changes you have made. +  </text> +  <view_border +    bevel_style="in" +    height="0" +    layout="topleft" +    name="border2" +    top_pad="5" +    left="20" +    width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="20" +   left="20" +   name="distance_lbl" +   width="100"> +    Visibility distance +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left_pad="40" +   name="faster_lbl" +   width="40"> +    Faster +  </text> +  <slider +    control_name="RenderFarClip" +    decimal_digits="0" +    follows="left|top" +    top_delta="-1" +    height="16" +    increment="8" +    initial_value="160" +    label_width="90" +    layout="topleft" +    min_val="64" +    max_val="512" +    name="draw_distance" +    left_pad="5" +    width="250"> +  </slider> +  <text +    type="string" +    length="1" +    follows="left|top" +    height="12" +    layout="topleft" +    left_pad="1" +    top_delta="0" +    name="draw_distance_m" +    width="20"> +    m +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   left_pad="10" +   top_delta="1" +   name="farther_lbl" +   width="40"> +    Farther +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="15" +   left="160" +   name="distance_desc1" +   width="350"> +    To see more land when you zoom out, increase the distance. +  </text> +  <view_border +    bevel_style="in" +    height="0" +    layout="topleft" +    name="border3" +    top_pad="5" +    left="20" +    width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="20" +   left="20" +   name="environment_lbl" +   width="100"> +    Environment +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_delta="0" +   left="160" +   name="enhancements_desc" +   width="350"> +    Each enhancement improves realism but can reduce speed. +  </text> +  <check_box +    control_name="WindLightUseAtmosShaders" +    height="16" +    initial_value="true" +    label="Atmospheric shaders" +    layout="topleft" +    name="atmospheric_shaders" +    top_pad="5" +    left="157" +    width="280"> +  </check_box> +  <check_box +    control_name="RenderDeferred" +    height="16" +    initial_value="true" +    label="Advanced Lighting" +    layout="topleft" +    name="advanced_lighting_model" +    top_delta="24" +    width="280"> +  </check_box>   +  <text +    type="string" +    length="1" +    follows="left|top" +    height="16" +    layout="topleft" +    left="160" +    name="RenderShadowDetailText" +    text_readonly_color="LabelDisabledColor" +    top_pad="10" +    width="128"> +    Shadows: +  </text> +  <combo_box +   control_name="RenderShadowDetail" +   height="18" +   layout="topleft" +   left_delta="150" +   top_delta="0" +   name="ShadowDetail" +   width="150"> +    <combo_box.item +      label="None" +      name="0" +      value="0"/> +    <combo_box.item +      label="Sun/Moon" +      name="1" +      value="1"/> +    <combo_box.item +      label="Sun/Moon + Projectors" +      name="2" +      value="2"/> +  </combo_box> +  <view_border +    bevel_style="in" +    height="0" +    layout="topleft" +    name="border3" +    top_pad="7" +    left="20" +    width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="20" +   left="20" +   name="water_lbl" +   width="100"> +    Water +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_delta="0" +   left="160" +   name="water_desc" +   width="380"> +    Reducing or turning off water effects can greatly improve frame rate. +  </text> +  <check_box +    control_name="RenderTransparentWater" +    height="16" +    initial_value="true" +    label="Transparent Water" +    layout="topleft" +    name="TransparentWater" +    top_delta="24" +    left="157" +    width="280"> +  </check_box> +  <text +    type="string" +    length="1" +    follows="left|top" +    height="16" +    layout="topleft" +    name="ReflectionsText" +    text_readonly_color="LabelDisabledColor" +    top_pad="16" +    left="160" +    width="128"> +    Water Reflections: +  </text> +  <combo_box +    control_name="RenderReflectionDetail" +    height="18" +    layout="topleft" +    left_delta="150" +    top_delta="0" +    name="Reflections" +    width="150"> +    <combo_box.item +      label="None; opaque" +      name="0" +      value="-2"/> +    <combo_box.item +      label="None; transparent" +      name="0" +      value="-1"/> +    <combo_box.item +      label="Minimal" +      name="0" +      value="0"/> +    <combo_box.item +      label="Terrain and trees" +      name="1" +      value="1"/> +    <combo_box.item +      label="All static objects" +      name="2" +      value="2"/> +    <combo_box.item +      label="All avatars and objects" +      name="3" +      value="3"/> +    <combo_box.item +      label="Everything" +      name="4" +      value="4"/> +  </combo_box> +  <view_border +    bevel_style="in" +    height="0" +    layout="topleft" +    name="border4" +    top_pad="7" +    left="20" +    width="540"/> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_pad="20" +   left="20" +   name="photo_lbl" +   width="100"> +    Photography +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   text_color="White" +   height="18" +   layout="topleft" +   top_delta="0" +   left="160" +   name="photo_desc" +   width="350"> +    Maximum detail is good for photos, but can slow frame rate. +  </text> +  <spinner +   control_name="RenderVolumeLODFactor" +   follows="left|top" +   height="23" +   increment="0.125" +   label="Distance detail:" +   label_width="95" +   layout="topleft" +   max_val="4" +   min_val="0" +   name="render_volume_lod" +   top_pad="10" +   width="150" /> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   top_delta="3" +   left_pad="10" +   name="photo_desc" +   width="180"> +      (Enter value between 0.0 and 4.0) +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   top="80" +   left="213" +   name="1_lbl" +   width="7"> +    1 +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   left_pad="31" +   name="2_lbl" +   width="7"> +    2 +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   left_pad="30" +   name="3_lbl" +   width="7"> +    3 +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   left_pad="30" +   name="4_lbl" +   width="7"> +    4 +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   left_pad="30" +   name="5_lbl" +   width="7"> +    5 +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   left_pad="30" +   name="6_lbl" +   width="7"> +      6 +  </text> +  <text +   follows="left|top" +   font="SansSerifSmall" +   height="18" +   layout="topleft" +   left_pad="30" +   name="7_lbl" +   width="7"> +    7 +  </text> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 5aff7a5127..ad02df3087 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -258,6 +258,18 @@      <check_box.commit_callback        function="Pref.RenderOptionUpdate" />    </check_box> + +  <button +  height="23" +  label="Automatic adjustments settings" +  layout="topleft" +  left="30" +  name="AutoAdjustmentsButton" +  top_delta="30" +  width="200"> +    <button.commit_callback +      function="Pref.AutoAdjustments"/> +  </button>    <slider      control_name="IndirectMaxComplexity" @@ -274,7 +286,7 @@      max_val="101"      name="IndirectMaxComplexity"      show_text="false" -    top_delta="60" +    top_delta="40"      width="300">      <slider.commit_callback        function="Pref.UpdateIndirectMaxComplexity" diff --git a/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml b/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml index b87dda2315..b3d165c4fd 100644 --- a/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml +++ b/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml @@ -8,7 +8,7 @@   border="false"   chrome="true"   follows="bottom" - height="155" + height="185"   layout="topleft"   name="presets_pulldown"   width="225"> @@ -57,7 +57,7 @@      width="215" />    <button      name="open_prefs_btn" -    label="Open Graphics Preferences" +    label="Graphics Preferences"      tool_tip = "Bring up graphics prefs"      top_delta="5"      left="15" @@ -66,4 +66,15 @@      <button.commit_callback        function="Presets.GoGraphicsPrefs" />    </button> +  <button +    name="open_autofps_btn" +    label="Auto-FPS settings" +    tool_tip = "Bring up auto-adjust settings" +    top_pad="5" +    left="15" +    height="20" +    width="200"> +    <button.commit_callback +     function="Presets.GoAutofpsPrefs" /> +  </button>  </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index fb39646ddd..0b19ad1473 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -4162,6 +4162,7 @@ name="Command_360_Capture_Label">360 snapshot</string>    <string name="Command_MiniMap_Label">Mini-map</string>    <string name="Command_Move_Label">Walk / run / fly</string>    <string name="Command_People_Label">People</string> +  <string name="Command_Performance_Label">Graphics speed</string>    <string name="Command_Picks_Label">Picks</string>    <string name="Command_Places_Label">Places</string>    <string name="Command_Preferences_Label">Preferences</string> @@ -4194,6 +4195,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>    <string name="Command_MiniMap_Tooltip">Show nearby people</string>    <string name="Command_Move_Tooltip">Moving your avatar</string>    <string name="Command_People_Tooltip">Friends, groups, and nearby people</string> +  <string name="Command_Performance_Tooltip">Improve graphics speed</string>    <string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>    <string name="Command_Places_Tooltip">Places you've saved</string>    <string name="Command_Preferences_Tooltip">Preferences</string> @@ -4292,7 +4294,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>    <string name="preset_combo_label">-Empty list-</string>    <string name="Default">Default</string>    <string name="none_paren_cap">(None)</string> -  <string name="no_limit">No Limit</string> +  <string name="no_limit">No limit</string>    <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">        The physics shape contains triangles which are too small. Try simplifying the physics model. | 
