initial merge form DRTVWR-539 branch

master
Beq 2022-11-02 22:37:24 +00:00
commit dedee8ba50
37 changed files with 2765 additions and 872 deletions

View File

@ -284,7 +284,7 @@ Beq Janus
SL-11300 SL-11300
SL-15709 SL-15709
SL-16021 SL-16021
SL-16027 SL-18202
Beth Walcher Beth Walcher
Bezilon Kasei Bezilon Kasei
Biancaluce Robbiani Biancaluce Robbiani

View File

@ -53,6 +53,8 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card);
const char* cursorIDToName(int id); const char* cursorIDToName(int id);
// </FS:CR> // </FS:CR>
const S32 DEFAULT_REFRESH_RATE = 60;
namespace namespace
{ {
NSKeyEventRef mRawKeyEvent = NULL; NSKeyEventRef mRawKeyEvent = NULL;
@ -666,6 +668,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
} }
mRefreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(mDisplay)); mRefreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(mDisplay));
if(mRefreshRate == 0)
{
//consider adding more appropriate fallback later
mRefreshRate = DEFAULT_REFRESH_RATE;
}
// Disable vertical sync for swap // Disable vertical sync for swap
toggleVSync(enable_vsync); toggleVSync(enable_vsync);

View File

@ -1665,6 +1665,9 @@ set(viewer_HEADER_FILES
NACLfloaterexploresounds.h NACLfloaterexploresounds.h
) )
list(APPEND viewer_SOURCE_FILES llperfstats.cpp)
list(APPEND viewer_HEADER_FILES llperfstats.h)
# <exodus> # <exodus>
# Generate the flickr keys header. # Generate the flickr keys header.
configure_file( configure_file(

View File

@ -21990,62 +21990,148 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>AutoFPS</key> <key>TargetFPS</key>
<map>
<key>Comment</key>
<string>
Allow dynamic adjustment of graphics preferences
</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AutoAdjustmentTimeout</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>Time before next iteration of automatic adjustments</string> <string>Desired minimum FPS</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <integer>1</integer>
<key>Type</key> <key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>30</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>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> <string>F32</string>
<key>Value</key> <key>Value</key>
<real>5</real> <real>4.699</real>
</map> </map>
<key>InitialAdjustmentTimeout</key> <key>AutoTuneRenderFarClipMin</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>Time before first iteration of automatic adjustments after login to the world, teleporting, maximizing Viewer etc.</string> <string>The lowest draw distance that auto tune is allowed to use</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <integer>0</integer>
<key>Type</key> <key>Type</key>
<string>F32</string> <string>F32</string>
<key>Value</key> <key>Value</key>
<real>10</real> <real>32.0</real>
</map> </map>
<key>AutoFPSLowerBoundary</key> <key>AutoTuneRenderFarClipTarget</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>FPS lower boundary when automatic adjustments are occured to reduce graphics quality to increase FPS</string> <string>The draw distance that auto tune will try to achieve</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <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> <key>Type</key>
<string>S32</string> <string>S32</string>
<key>Value</key> <key>Value</key>
<real>30</real> <integer>4</integer>
</map> </map>
<key>AutoFPSUpperBoundary</key> <key>PerfStatsCaptureEnabled</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>FPS upper boundary when automatic adjustments are occured to increase graphics quality</string> <string>Enable/disable render time data to support autotune.</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <integer>1</integer>
<key>Type</key> <key>Type</key>
<string>S32</string> <string>Boolean</string>
<key>Value</key> <key>Value</key>
<real>50</real> <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.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map> </map>
<key>CameraOpacity</key> <key>CameraOpacity</key>
<map> <map>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<toolbars>
<bottom_toolbar
button_display_mode="icons_with_text">
<command name="chat"/>
<command name="speak"/>
<command name="destinations"/>
<command name="people"/>
<command name="profile"/>
<command name="map"/>
<command name="move"/>
<command name="view"/>
<command name="howto"/>
</bottom_toolbar>
<left_toolbar
button_display_mode="icons_only">
<command name="avatar"/>
<command name="appearance"/>
<command name="inventory"/>
<command name="search"/>
<command name="places"/>
<command name="voice"/>
<command name="minimap"/>
<command name="snapshot"/>
<command name="performance"/>
</left_toolbar>
<right_toolbar
button_display_mode="icons_only">
</right_toolbar>
</toolbars>

View File

@ -4888,8 +4888,6 @@ void LLAgent::handleTeleportFinished()
} }
} }
// <FS:Ansariel> [FS performance floater]
//gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
} }
void LLAgent::handleTeleportFailed() void LLAgent::handleTeleportFailed()
@ -4922,8 +4920,6 @@ void LLAgent::handleTeleportFailed()
mTPNeedsNeabyChatSeparator = false; mTPNeedsNeabyChatSeparator = false;
// <FS:Ansariel> [FS performance floater]
//gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
} }
/*static*/ /*static*/

View File

@ -122,6 +122,7 @@
#include "llscenemonitor.h" #include "llscenemonitor.h"
#include "llavatarrenderinfoaccountant.h" #include "llavatarrenderinfoaccountant.h"
#include "lllocalbitmaps.h" #include "lllocalbitmaps.h"
#include "llperfstats.h"
// Linden library includes // Linden library includes
#include "llavatarnamecache.h" #include "llavatarnamecache.h"
@ -1591,25 +1592,23 @@ bool LLAppViewer::frame()
bool LLAppViewer::doFrame() bool LLAppViewer::doFrame()
{ {
LL_RECORD_BLOCK_TIME(FTM_FRAME); LL_RECORD_BLOCK_TIME(FTM_FRAME);
// <FS:Beq> Perfstats collection Frame boundary
{
// and now adjust the visuals from previous frame.
if(FSPerfStats::tunables.userAutoTuneEnabled && FSPerfStats::tunables.tuningFlag != FSPerfStats::Tunables::Nothing)
{ {
FSPerfStats::tunables.applyUpdates(); // and now adjust the visuals from previous frame.
if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing)
{
LLPerfStats::tunables.applyUpdates();
} }
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_FRAME); LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_FRAME);
if (!LLWorld::instanceExists()) if (!LLWorld::instanceExists())
{ {
LLWorld::createInstance(); LLWorld::createInstance();
} }
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame; LLSD newFrame;
{
// <FS:Beq> profiling enablement. // <FS:Beq> profiling enablement.
// This ifdef is optional but better to avoid even low overhead code in main loop where not needed. // This ifdef is optional but better to avoid even low overhead code in main loop where not needed.
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
@ -1645,76 +1644,75 @@ bool LLAppViewer::doFrame()
// </FS:Beq> // </FS:Beq>
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux // <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
LLTimer frameTimer; LLTimer frameTimer;
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq/> perf stats LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); // perf stats
nd::etw::logFrame(); // <FS:ND> Write the start of each frame. Even if our Provider (Firestorm) would be enabled, this has only light impact. Does nothing on OSX and Linux. nd::etw::logFrame(); // <FS:ND> Write the start of each frame. Even if our Provider (Firestorm) would be enabled, this has only light impact. Does nothing on OSX and Linux.
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace");
if (LLFloaterReg::instanceVisible("block_timers"))
{ {
LLTrace::BlockTimer::processTimes(); LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace");
if (LLFloaterReg::instanceVisible("block_timers"))
{
LLTrace::BlockTimer::processTimes();
}
LLTrace::get_frame_recording().nextPeriod();
LLTrace::BlockTimer::logStats();
} }
LLTrace::get_frame_recording().nextPeriod();
LLTrace::BlockTimer::logStats();
}
LLTrace::get_thread_recorder()->pullFromChildren(); LLTrace::get_thread_recorder()->pullFromChildren();
//clear call stack records //clear call stack records
LL_CLEAR_CALLSTACKS(); LL_CLEAR_CALLSTACKS();
} // <FS:Beq/> perf stats (close NonRender/IDLE tracking starting at event pump) } // <FS:Beq/> perf stats (close NonRender/IDLE tracking starting at event pump)
{ {
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq> ensure we have the entire top scope of frame covered (input event and coro) {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df processMiscNativeEvents" ) LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df processMiscNativeEvents")
pingMainloopTimeout("Main:MiscNativeWindowEvents"); pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow) if (gViewerWindow)
{ {
LL_RECORD_BLOCK_TIME(FTM_MESSAGES); LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
gViewerWindow->getWindow()->processMiscNativeEvents(); gViewerWindow->getWindow()->processMiscNativeEvents();
} }
{ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gatherInput" ) LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df gatherInput")
pingMainloopTimeout("Main:GatherInput"); pingMainloopTimeout("Main:GatherInput");
} }
if (gViewerWindow) if (gViewerWindow)
{ {
LL_RECORD_BLOCK_TIME(FTM_MESSAGES2); LL_RECORD_BLOCK_TIME(FTM_MESSAGES2);
if (!restoreErrorTrap()) if (!restoreErrorTrap())
{ {
LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
} }
gViewerWindow->getWindow()->gatherInput(); gViewerWindow->getWindow()->gatherInput();
} }
//memory leaking simulation //memory leaking simulation
if (gSimulateMemLeak) if (gSimulateMemLeak)
{ {
LLFloaterMemLeak* mem_leak_instance = LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if (mem_leak_instance) if (mem_leak_instance)
{ {
mem_leak_instance->idle(); mem_leak_instance->idle();
} }
} }
{ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df mainloop" ) LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df mainloop")
// canonical per-frame event // canonical per-frame event
mainloop.post(newFrame); mainloop.post(newFrame);
} }
{ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" ) LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend")
// give listeners a chance to run // give listeners a chance to run
llcoro::suspend(); llcoro::suspend();
// if one of our coroutines threw an uncaught exception, rethrow it now }
LLCoros::instance().rethrow(); }
}
}// <FS:Beq> ensure we have the entire top scope of frame covered (close input event and coro "idle") }// <FS:Beq> ensure we have the entire top scope of frame covered (close input event and coro "idle")
if (!LLApp::isExiting()) if (!LLApp::isExiting())
@ -1732,8 +1730,7 @@ bool LLAppViewer::doFrame()
&& (gHeadlessClient || !gViewerWindow->getShowProgress()) && (gHeadlessClient || !gViewerWindow->getShowProgress())
&& !gFocusMgr.focusLocked()) && !gFocusMgr.focusLocked())
{ {
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" )
joystick->scanJoystick(); joystick->scanJoystick();
gKeyboard->scanKeyboard(); gKeyboard->scanKeyboard();
gViewerInput.scanMouse(); gViewerInput.scanMouse();
@ -1749,19 +1746,21 @@ bool LLAppViewer::doFrame()
// Update state based on messages, user input, object idle. // Update state based on messages, user input, object idle.
{ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) {
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
} pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
}
{ {
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE); LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle(); idle();
} }
{ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
resumeMainloopTimeout(); resumeMainloopTimeout();
}
} }
if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
@ -1789,15 +1788,15 @@ bool LLAppViewer::doFrame()
display(); display();
{ {
FSPerfStats::RecordSceneTime T(FSPerfStats::StatType_t::RENDER_IDLE); LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot") LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot"); pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update(); LLFloaterOutfitSnapshot::update();
gGLActive = FALSE; gGLActive = FALSE;
} }
} }
} }
{ {
@ -1842,8 +1841,8 @@ bool LLAppViewer::doFrame()
// of equal priority on Windows // of equal priority on Windows
if (milliseconds_to_sleep > 0) if (milliseconds_to_sleep > 0)
{ {
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SLEEP ); LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SLEEP );
ms_sleep(milliseconds_to_sleep); ms_sleep(milliseconds_to_sleep);
// also pause worker threads during this wait period // also pause worker threads during this wait period
LLAppViewer::getTextureCache()->pause(); LLAppViewer::getTextureCache()->pause();
LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getImageDecodeThread()->pause();
@ -1966,8 +1965,7 @@ bool LLAppViewer::doFrame()
LL_INFOS() << "Exiting main_loop" << LL_ENDL; LL_INFOS() << "Exiting main_loop" << LL_ENDL;
} }
}LLPerfStats::StatsRecorder::endFrame();
}FSPerfStats::StatsRecorder::endFrame();
LL_PROFILER_FRAME_END LL_PROFILER_FRAME_END
return ! LLApp::isRunning(); return ! LLApp::isRunning();

View File

@ -52,7 +52,7 @@
#include "llglcommonfunc.h" #include "llglcommonfunc.h"
#include "llvoavatar.h" #include "llvoavatar.h"
#include "llviewershadermgr.h" #include "llviewershadermgr.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support #include "llperfstats.h"
S32 LLDrawPool::sNumDrawPools = 0; S32 LLDrawPool::sNumDrawPools = 0;
@ -392,24 +392,22 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
{ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{ {
LLDrawInfo *pparams = *k; LLDrawInfo *pparams = *k;
if (pparams) if (pparams)
{ {
// <FS:Beq> Capture render times if(pparams->mFace)
if(pparams->mFace) {
{ LLViewerObject* vobj = pparams->mFace->getViewerObject();
LLViewerObject* vobj = pparams->mFace->getViewerObject(); if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments(vobj, false, &ratPtr);
trackAttachments( vobj, false,&ratPtr); }
} }
} pushBatch(*pparams, mask, texture);
// </FS:Beq>
pushBatch(*pparams, mask, texture);
} }
} }
} }
@ -422,22 +420,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
U64 lastMeshId = 0; U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4; mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{ {
LLDrawInfo* pparams = *k; LLDrawInfo* pparams = *k;
if (pparams) if (pparams)
{ {
// <FS:Beq> Capture render times if(pparams->mFace)
if(pparams->mFace) {
{ LLViewerObject* vobj = pparams->mFace->getViewerObject();
LLViewerObject* vobj = pparams->mFace->getViewerObject(); if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments( vobj, true ,&ratPtr);
trackAttachments( vobj, true ,&ratPtr); }
} }
}
// </FS:Beq>
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{ {
uploadMatrixPalette(*pparams); uploadMatrixPalette(*pparams);
@ -453,23 +450,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{ {
LLDrawInfo* pparams = *i; LLDrawInfo* pparams = *i;
if (pparams) if (pparams)
{ {
// <FS:Beq> Capture render times if(pparams->mFace)
if(pparams->mFace) {
{ LLViewerObject* vobj = pparams->mFace->getViewerObject();
LLViewerObject* vobj = pparams->mFace->getViewerObject(); if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments( vobj, false, &ratPtr);
trackAttachments( vobj, false, &ratPtr); }
} }
} pushBatch(*pparams, mask, texture, batch_textures);
// </FS:Beq>
pushBatch(*pparams, mask, texture, batch_textures);
} }
} }
} }
@ -480,22 +475,21 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
LLVOAvatar* lastAvatar = nullptr; LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0; U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4; mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{ {
LLDrawInfo* pparams = *i; LLDrawInfo* pparams = *i;
if (pparams) if (pparams)
{ {
// <FS:Beq> Capture render times if(pparams->mFace)
if(pparams->mFace) {
{ LLViewerObject* vobj = pparams->mFace->getViewerObject();
LLViewerObject* vobj = pparams->mFace->getViewerObject(); if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments( vobj, true, &ratPtr);
trackAttachments( vobj, true, &ratPtr); }
} }
}
// </FS:Beq>
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)) if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{ {
uploadMatrixPalette(*pparams); uploadMatrixPalette(*pparams);
@ -511,22 +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) void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{ {
LLDrawInfo* pparams = *i; LLDrawInfo* pparams = *i;
if (pparams) if (pparams)
{ {
// <FS:Beq> Capture render times if((*pparams).mFace)
if((*pparams).mFace) {
{ LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments( vobj, false, &ratPtr);
trackAttachments( vobj, false, &ratPtr); }
} }
}
// </FS:Beq>
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
pushBatch(*pparams, mask, texture, batch_textures); pushBatch(*pparams, mask, texture, batch_textures);
} }
@ -538,22 +530,20 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOAvatar* lastAvatar = nullptr; LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0; U64 lastMeshId = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{ {
LLDrawInfo* pparams = *i; LLDrawInfo* pparams = *i;
if (pparams) if (pparams)
{ {
// <FS:Beq> Capture render times if((*pparams).mFace)
if((*pparams).mFace) {
{ LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments( vobj, true, &ratPtr);
trackAttachments( vobj, true, &ratPtr); }
} }
}
// </FS:Beq>
if (LLGLSLShader::sCurBoundShaderPtr) if (LLGLSLShader::sCurBoundShaderPtr)
{ {
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);

View File

@ -49,7 +49,7 @@
#include "llspatialpartition.h" #include "llspatialpartition.h"
#include "llglcommonfunc.h" #include "llglcommonfunc.h"
#include "llvoavatar.h" #include "llvoavatar.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support #include "llperfstats.h"
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
BOOL LLDrawPoolAlpha::sShowDebugAlphaRigged = FALSE; BOOL LLDrawPoolAlpha::sShowDebugAlphaRigged = FALSE;
@ -346,11 +346,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 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<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection 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) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{ {
LLDrawInfo& params = **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) if (params.mParticle)
{ {
continue; continue;
@ -543,17 +552,15 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
mask |= LLVertexBuffer::MAP_WEIGHT4; mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLDrawInfo* draw : emissives) for (LLDrawInfo* draw : emissives)
{ {
// <FS:Beq> Capture render times LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives"); auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr; if(vobj && vobj->isAttachment())
if(vobj && vobj->isAttachment()) {
{ trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr ); }
}
// </FS:Beq>
bool tex_setup = TexSetup(draw, false); bool tex_setup = TexSetup(draw, false);
if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash) if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
@ -628,8 +635,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]; LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection 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) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{ {
LLDrawInfo& params = **k; LLDrawInfo& params = **k;
if ((bool)params.mAvatar != rigged) if ((bool)params.mAvatar != rigged)
@ -651,17 +658,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
continue; continue;
} }
// <FS:Beq> Capture render times if(params.mFace)
if(params.mFace) {
{ LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj->isAttachment())
if(vobj->isAttachment()) {
{ trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); }
} }
}
// </FS:Beq>
if(depth_only) if(depth_only)
{ {
@ -854,6 +859,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 ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
// </FS:Beq> // </FS:Beq>
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 // render emissive faces into alpha channel for bloom effects
if (!depth_only) if (!depth_only)
{ {

View File

@ -52,6 +52,7 @@
#include "llviewerpartsim.h" #include "llviewerpartsim.h"
#include "llviewercontrol.h" // for gSavedSettings #include "llviewercontrol.h" // for gSavedSettings
#include "llviewertexturelist.h" #include "llviewertexturelist.h"
#include "llperfstats.h"
// <FS:Zi> Add avatar hitbox debug // <FS:Zi> Add avatar hitbox debug
#include "llviewercontrol.h" #include "llviewercontrol.h"
@ -389,14 +390,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
{ {
return; return;
} }
FSPerfStats::RecordAvatarTime T(avatarp->getID(), FSPerfStats::StatType_t::RENDER_SHADOWS); LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS);
LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
// <FS:Beq> no shadows if the shadows are causing this avatar to breach the limit. // no shadows if the shadows are causing this avatar to breach the limit.
//if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE)) if (avatarp->isTooSlowWithShadows() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
if (avatarp->isTooSlowWithShadows() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
// </FS:Beq>
{ {
// No shadows for impostored (including jellydolled) or invisible avs. // No shadows for impostored (including jellydolled) or invisible avs.
return; return;
@ -805,7 +804,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{ {
return; return;
} }
FSPerfStats::RecordAvatarTime T(avatarp->getID(), FSPerfStats::StatType_t::RENDER_GEOMETRY); LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);
// <FS:Zi> Add avatar hitbox debug // <FS:Zi> Add avatar hitbox debug
static LLCachedControl<bool> render_hitbox(gSavedSettings, "DebugRenderHitboxes", false); static LLCachedControl<bool> render_hitbox(gSavedSettings, "DebugRenderHitboxes", false);

View File

@ -48,7 +48,7 @@
#include "llspatialpartition.h" #include "llspatialpartition.h"
#include "llviewershadermgr.h" #include "llviewershadermgr.h"
#include "llmodel.h" #include "llmodel.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support #include "llperfstats.h"
//#include "llimagebmp.h" //#include "llimagebmp.h"
//#include "../tools/imdebug/imdebug.h" //#include "../tools/imdebug/imdebug.h"
@ -543,18 +543,20 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{ {
LLDrawInfo& params = **k; LLDrawInfo& params = **k;
// <FS:Beq> Capture render times // <FS:Beq> Capture render times
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() ) LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); if( vobj && vobj->isAttachment() )
} {
// </FS:Beq> trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
applyModelMatrix(params); applyModelMatrix(params);
if (params.mGroup) if (params.mGroup)
@ -723,22 +725,20 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLVOAvatar* avatar = nullptr; LLVOAvatar* avatar = nullptr;
U64 skin = 0; U64 skin = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{ {
LLDrawInfo& params = **i; LLDrawInfo& params = **i;
// <FS:Beq> Capture render times
if(params.mFace) if(params.mFace)
{ {
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj && vobj->isAttachment()) if(vobj && vobj->isAttachment())
{ {
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
} }
} }
// </FS:Beq>
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
LLDrawPoolBump::bindBumpMap(params, bump_channel); LLDrawPoolBump::bindBumpMap(params, bump_channel);
@ -1371,7 +1371,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{ {
LLDrawInfo& params = **i; LLDrawInfo& params = **i;
@ -1387,6 +1387,16 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
} }
// </FS:Beq> // </FS:Beq>
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 (LLDrawPoolBump::bindBumpMap(params))
{ {
if (mRigged) if (mRigged)

View File

@ -32,7 +32,7 @@
#include "pipeline.h" #include "pipeline.h"
#include "llglcommonfunc.h" #include "llglcommonfunc.h"
#include "llvoavatar.h" #include "llvoavatar.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support #include "llperfstats.h"
S32 diffuse_channel = -1; S32 diffuse_channel = -1;
@ -165,23 +165,21 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{ {
LLDrawInfo& params = **i; LLDrawInfo& params = **i;
// <FS:Beq> Capture render times if(params.mFace)
if(params.mFace) {
{ LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
// </FS:Beq>
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->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); mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);

View File

@ -38,6 +38,7 @@
#include "llfloaterreg.h" #include "llfloaterreg.h"
#include "llnamelistctrl.h" #include "llnamelistctrl.h"
#include "llnotificationsutil.h" #include "llnotificationsutil.h"
#include "llperfstats.h"
#include "llradiogroup.h" #include "llradiogroup.h"
#include "llsliderctrl.h" #include "llsliderctrl.h"
#include "lltextbox.h" #include "lltextbox.h"
@ -54,6 +55,10 @@ const S32 BAR_LEFT_PAD = 2;
const S32 BAR_RIGHT_PAD = 5; const S32 BAR_RIGHT_PAD = 5;
const S32 BAR_BOTTOM_PAD = 9; 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 class LLExceptionsContextMenu : public LLListContextMenu
{ {
public: public:
@ -81,13 +86,11 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
mNearbyMaxComplexity(0) mNearbyMaxComplexity(0)
{ {
mContextMenu = new LLExceptionsContextMenu(this); mContextMenu = new LLExceptionsContextMenu(this);
mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
} }
LLFloaterPerformance::~LLFloaterPerformance() LLFloaterPerformance::~LLFloaterPerformance()
{ {
mComplexityChangedSignal.disconnect(); mMaxARTChangedSignal.disconnect();
delete mContextMenu; delete mContextMenu;
delete mUpdateTimer; delete mUpdateTimer;
} }
@ -99,16 +102,19 @@ BOOL LLFloaterPerformance::postBuild()
mComplexityPanel = getChild<LLPanel>("panel_performance_complexity"); mComplexityPanel = getChild<LLPanel>("panel_performance_complexity");
mSettingsPanel = getChild<LLPanel>("panel_performance_preferences"); mSettingsPanel = getChild<LLPanel>("panel_performance_preferences");
mHUDsPanel = getChild<LLPanel>("panel_performance_huds"); 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>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel)); getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel));
getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel)); getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel)); 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(mNearbyPanel);
initBackBtn(mComplexityPanel); initBackBtn(mComplexityPanel);
initBackBtn(mSettingsPanel); initBackBtn(mSettingsPanel);
initBackBtn(mHUDsPanel); initBackBtn(mHUDsPanel);
initBackBtn(mAutoadjustmentsPanel);
mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list"); mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
mHUDList->setNameListType(LLNameListCtrl::SPECIAL); mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
@ -124,7 +130,6 @@ BOOL LLFloaterPerformance::postBuild()
mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2)); 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<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this));
mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this)); mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this));
mSettingsPanel->getChild<LLComboBox>("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, 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")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
@ -132,11 +137,15 @@ BOOL LLFloaterPerformance::postBuild()
mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list"); mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3)); mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
updateComplexityText(); mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this)); mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this));
LLAvatarComplexityControls::setIndirectMaxArc(); // 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);
}
return TRUE; return TRUE;
} }
@ -161,6 +170,11 @@ void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
} }
} }
void LLFloaterPerformance::showAutoadjustmentsPanel()
{
showSelectedPanel(mAutoadjustmentsPanel);
}
void LLFloaterPerformance::draw() void LLFloaterPerformance::draw()
{ {
if (mUpdateTimer->hasExpired()) if (mUpdateTimer->hasExpired())
@ -180,6 +194,12 @@ void LLFloaterPerformance::draw()
populateObjectList(); populateObjectList();
} }
auto button = getChild<LLButton>("AutoTuneFPS");
if((bool)button->getToggleState() != LLPerfStats::tunables.userAutoTuneEnabled)
{
button->toggleState();
}
mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL); mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
} }
LLFloater::draw(); LLFloater::draw();
@ -197,6 +217,7 @@ void LLFloaterPerformance::hidePanels()
mComplexityPanel->setVisible(FALSE); mComplexityPanel->setVisible(FALSE);
mHUDsPanel->setVisible(FALSE); mHUDsPanel->setVisible(FALSE);
mSettingsPanel->setVisible(FALSE); mSettingsPanel->setVisible(FALSE);
mAutoadjustmentsPanel->setVisible(FALSE);
} }
void LLFloaterPerformance::initBackBtn(LLPanel* panel) void LLFloaterPerformance::initBackBtn(LLPanel* panel)
@ -220,16 +241,13 @@ void LLFloaterPerformance::populateHUDList()
hud_complexity_list_t::iterator iter = complexity_list.begin(); hud_complexity_list_t::iterator iter = complexity_list.begin();
hud_complexity_list_t::iterator end = complexity_list.end(); hud_complexity_list_t::iterator end = complexity_list.end();
U32 max_complexity = 0; auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY);
for (; iter != end; ++iter)
{
max_complexity = llmax(max_complexity, (*iter).objectsCost);
}
for (iter = complexity_list.begin(); iter != end; ++iter) for (iter = complexity_list.begin(); iter != end; ++iter)
{ {
LLHUDComplexity hud_object_complexity = *iter; LLHUDComplexity hud_object_complexity = *iter;
S32 obj_cost_short = llmax((S32)hud_object_complexity.objectsCost / 1000, 1);
auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY);
LLSD item; LLSD item;
item["special_id"] = hud_object_complexity.objectId; item["special_id"] = hud_object_complexity.objectId;
item["target"] = LLNameListCtrl::SPECIAL; item["target"] = LLNameListCtrl::SPECIAL;
@ -237,14 +255,14 @@ void LLFloaterPerformance::populateHUDList()
row[0]["column"] = "complex_visual"; row[0]["column"] = "complex_visual";
row[0]["type"] = "bar"; row[0]["type"] = "bar";
LLSD& value = row[0]["value"]; LLSD& value = row[0]["value"];
value["ratio"] = (F32)obj_cost_short / max_complexity * 1000; value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw;
value["bottom"] = BAR_BOTTOM_PAD; value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD; value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD; value["right_pad"] = BAR_RIGHT_PAD;
row[1]["column"] = "complex_value"; row[1]["column"] = "complex_value";
row[1]["type"] = "text"; row[1]["type"] = "text";
row[1]["value"] = std::to_string(obj_cost_short); row[1]["value"] = llformat( "%.f",LLPerfStats::raw_to_us(hud_render_time_raw) );
row[1]["font"]["name"] = "SANSSERIF"; row[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "name"; row[2]["column"] = "name";
@ -279,45 +297,46 @@ void LLFloaterPerformance::populateObjectList()
object_complexity_list_t::iterator iter = complexity_list.begin(); object_complexity_list_t::iterator iter = complexity_list.begin();
object_complexity_list_t::iterator end = complexity_list.end(); object_complexity_list_t::iterator end = complexity_list.end();
U32 max_complexity = 0; // 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
for (; iter != end; ++iter)
{ {
max_complexity = llmax(max_complexity, (*iter).objectCost); 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) for (iter = complexity_list.begin(); iter != end; ++iter)
{
LLObjectComplexity object_complexity = *iter;
S32 obj_cost_short = llmax((S32)object_complexity.objectCost / 1000, 1);
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)obj_cost_short / max_complexity * 1000;
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"] = std::to_string(obj_cost_short);
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)); LLObjectComplexity object_complexity = *iter;
if (value_text)
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", LLPerfStats::raw_to_us(attach_render_time_raw));
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)
{ {
value_text->setAlignment(LLFontGL::HCENTER); LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
if (value_text)
{
value_text->setAlignment(LLFontGL::HCENTER);
}
} }
} }
} }
@ -328,6 +347,7 @@ void LLFloaterPerformance::populateObjectList()
void LLFloaterPerformance::populateNearbyList() void LLFloaterPerformance::populateNearbyList()
{ {
static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");
S32 prev_pos = mNearbyList->getScrollPos(); S32 prev_pos = mNearbyList->getScrollPos();
LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem(); LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
mNearbyList->clearRows(); mNearbyList->clearRows();
@ -338,26 +358,44 @@ void LLFloaterPerformance::populateNearbyList()
mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs); mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin(); 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()) while (char_iter != valid_nearby_avs.end())
{ {
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter); LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance())) if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
{ {
S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);; 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->isTooSlowWithShadows();
LLSD item; LLSD item;
item["id"] = avatar->getID(); item["id"] = avatar->getID();
LLSD& row = item["columns"]; LLSD& row = item["columns"];
row[0]["column"] = "complex_visual"; row[0]["column"] = "complex_visual";
row[0]["type"] = "bar"; row[0]["type"] = "bar";
LLSD& value = row[0]["value"]; LLSD& value = row[0]["value"];
value["ratio"] = (F32)complexity_short / mNearbyMaxComplexity * 1000; // 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["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD; value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD; value["right_pad"] = BAR_RIGHT_PAD;
row[1]["column"] = "complex_value"; row[1]["column"] = "complex_value";
row[1]["type"] = "text"; row[1]["type"] = "text";
row[1]["value"] = std::to_string(complexity_short); 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[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "name"; row[2]["column"] = "name";
@ -383,7 +421,7 @@ void LLFloaterPerformance::populateNearbyList()
else else
{ {
std::string color = "white"; std::string color = "white";
if (LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance()) if (is_slow || LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
{ {
color = "LabelDisabledColor"; color = "LabelDisabledColor";
LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0)); LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
@ -458,18 +496,11 @@ void LLFloaterPerformance::onClickExceptions()
LLFloaterReg::showInstance("avatar_render_settings"); LLFloaterReg::showInstance("avatar_render_settings");
} }
void LLFloaterPerformance::updateMaxComplexity() void LLFloaterPerformance::updateMaxRenderTime()
{ {
LLAvatarComplexityControls::updateMax( LLAvatarComplexityControls::updateMaxRenderTime(
mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity"), mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART"),
mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText"), mNearbyPanel->getChild<LLTextBox>("RenderAvatarMaxARTText"),
true);
}
void LLFloaterPerformance::updateComplexityText()
{
LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText", true),
true); true);
} }
@ -585,8 +616,7 @@ bool is_ALM_available()
return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny && bumpshiny &&
shaders && shaders;
gGLManager.mHasFramebufferObject;
} }
void LLFloaterPerformance::onClickAdvancedLighting() void LLFloaterPerformance::onClickAdvancedLighting()
@ -599,16 +629,10 @@ void LLFloaterPerformance::onClickAdvancedLighting()
void LLFloaterPerformance::onClickShadows() void LLFloaterPerformance::onClickShadows()
{ {
if (gSavedSettings.getBOOL("AutoFPS")) if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred"))
{ {
LLFloaterPreference::showAutoAdjustWarning(); changeQualityLevel("ShadowsConfirm");
}
else
{
if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred"))
{
changeQualityLevel("ShadowsConfirm");
}
} }
} }
// EOF // EOF

View File

@ -44,6 +44,7 @@ public:
void showSelectedPanel(LLPanel* selected_panel); void showSelectedPanel(LLPanel* selected_panel);
void showMainPanel(); void showMainPanel();
void hidePanels(); void hidePanels();
void showAutoadjustmentsPanel();
void detachItem(const LLUUID& item_id); void detachItem(const LLUUID& item_id);
@ -66,8 +67,7 @@ private:
void onClickShadows(); void onClickShadows();
void onClickAdvancedLighting(); void onClickAdvancedLighting();
void updateMaxComplexity(); void updateMaxRenderTime();
void updateComplexityText();
static void changeQualityLevel(const std::string& notif); static void changeQualityLevel(const std::string& notif);
@ -76,6 +76,7 @@ private:
LLPanel* mComplexityPanel; LLPanel* mComplexityPanel;
LLPanel* mHUDsPanel; LLPanel* mHUDsPanel;
LLPanel* mSettingsPanel; LLPanel* mSettingsPanel;
LLPanel* mAutoadjustmentsPanel;
LLNameListCtrl* mHUDList; LLNameListCtrl* mHUDList;
LLNameListCtrl* mObjectList; LLNameListCtrl* mObjectList;
LLNameListCtrl* mNearbyList; LLNameListCtrl* mNearbyList;
@ -86,7 +87,7 @@ private:
S32 mNearbyMaxComplexity; S32 mNearbyMaxComplexity;
boost::signals2::connection mComplexityChangedSignal; boost::signals2::connection mMaxARTChangedSignal;
}; };
#endif // LL_LLFLOATERPERFORMANCE_H #endif // LL_LLFLOATERPERFORMANCE_H

View File

@ -54,6 +54,7 @@
#include "llfloaterabout.h" #include "llfloaterabout.h"
#include "llfavoritesbar.h" #include "llfavoritesbar.h"
#include "llfloaterpreferencesgraphicsadvanced.h" #include "llfloaterpreferencesgraphicsadvanced.h"
#include "llfloaterperformance.h"
#include "llfloatersidepanelcontainer.h" #include "llfloatersidepanelcontainer.h"
// <FS:Ansariel> [FS communication UI] // <FS:Ansariel> [FS communication UI]
//#include "llfloaterimsession.h" //#include "llfloaterimsession.h"
@ -128,6 +129,7 @@
#include "llpresetsmanager.h" #include "llpresetsmanager.h"
#include "llsearchableui.h" #include "llsearchableui.h"
#include "llperfstats.h"
// Firestorm Includes // Firestorm Includes
#include "exogroupmutelist.h" #include "exogroupmutelist.h"
@ -468,6 +470,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
// </FS:Zi> // </FS:Zi>
mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this)); mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
mCommitCallbackRegistrar.add("Pref.RenderExceptions", boost::bind(&LLFloaterPreference::onClickRenderExceptions, 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.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this)); mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this)); mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
@ -487,7 +490,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this)); mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this)); mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this)); mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
// <FS:Ansariel> Improved graphics preferences // <FS:Ansariel> Improved graphics preferences
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreference::updateMaxNonImpostors, this)); mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreference::updateMaxNonImpostors, this));
@ -1232,17 +1234,18 @@ void LLFloaterPreference::onOpen(const LLSD& key)
// <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well // <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well
//bool started = (LLStartUp::getStartupState() == STATE_STARTED); //bool started = (LLStartUp::getStartupState() == STATE_STARTED);
//LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
//LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
//LLButton* save_btn = findChild<LLButton>("PrefSaveButton"); //LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
//LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton"); //LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
//LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton"); //LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
//if (load_btn && save_btn && delete_btn && exceptions_btn) // LLButton* auto_adjustments_btn = findChild<LLButton>("AutoAdjustmentsButton");
//if (load_btn && save_btn && delete_btn && exceptions_btn && auto_adjustments_btn)
//{ //{
// load_btn->setEnabled(started); // load_btn->setEnabled(started);
// save_btn->setEnabled(started); // save_btn->setEnabled(started);
// delete_btn->setEnabled(started); // delete_btn->setEnabled(started);
// exceptions_btn->setEnabled(started); // exceptions_btn->setEnabled(started);
// auto_adjustments_btn->setEnabled(started);
//} //}
// </FS:Ansariel> // </FS:Ansariel>
collectSearchableItems(); collectSearchableItems();
@ -1255,6 +1258,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
tabcontainer->selectFirstTab(); tabcontainer->selectFirstTab();
// </FS:ND> // </FS:ND>
} }
// <FS:Zi> Support for tab/subtab links like: // <FS:Zi> Support for tab/subtab links like:
// secondlife:///app/openfloater/preferences?tab=backup // secondlife:///app/openfloater/preferences?tab=backup
@ -2843,24 +2847,23 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool sh
} }
} }
// <FS:Beq> redner time controls
void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val) void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
{ {
setRenderTimeText((F32)(FSPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val); setRenderTimeText((F32)(LLPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
} }
void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val) void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)
{ {
if (0 == value) if (0 == value)
{ {
text_box->setText(LLTrans::getString("no_limit")); text_box->setText(LLTrans::getString("no_limit"));
} }
else else
{ {
text_box->setText(llformat("%.0f", value)); text_box->setText(llformat("%.0f", value));
} }
} }
// </FS:Beq>
void LLFloaterPreference::updateMaxComplexity() void LLFloaterPreference::updateMaxComplexity()
{ {
// Called when the IndirectMaxComplexity control changes // Called when the IndirectMaxComplexity control changes
@ -3024,6 +3027,15 @@ void LLFloaterPreference::onClickRenderExceptions()
LLFloaterReg::showInstance("avatar_render_settings"); LLFloaterReg::showInstance("avatar_render_settings");
} }
void LLFloaterPreference::onClickAutoAdjustments()
{
LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
if (performance_floater)
{
performance_floater->showAutoadjustmentsPanel();
}
}
void LLFloaterPreference::onClickAdvanced() void LLFloaterPreference::onClickAdvanced()
{ {
LLFloaterReg::showInstance("prefs_graphics_advanced"); LLFloaterReg::showInstance("prefs_graphics_advanced");
@ -3201,23 +3213,6 @@ void LLFloaterPreference::updateSearchableItems()
mSearchDataDirty = true; mSearchDataDirty = true;
} }
void LLFloaterPreference::showAutoAdjustWarning()
{
static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
if (use_auto_adjust)
{
LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
[](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
gSavedSettings.setBOOL("AutoFPS", FALSE);
}
});
}
}
void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param) void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
{ {
LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue())); LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));

View File

@ -120,8 +120,6 @@ public:
void updateClickActionViews(); void updateClickActionViews();
void updateSearchableItems(); void updateSearchableItems();
static void showAutoAdjustWarning();
void onBtnOK(const LLSD& userdata); void onBtnOK(const LLSD& userdata);
void onBtnCancel(const LLSD& userdata); void onBtnCancel(const LLSD& userdata);
@ -275,6 +273,7 @@ public:
void onClickAutoReplace(); void onClickAutoReplace();
void onClickSpellChecker(); void onClickSpellChecker();
void onClickRenderExceptions(); void onClickRenderExceptions();
void onClickAutoAdjustments();
void onClickAdvanced(); void onClickAdvanced();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param); void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param); void getUIColor(LLUICtrl* ctrl, const LLSD& param);
@ -483,10 +482,8 @@ class LLAvatarComplexityControls
public: public:
static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false); 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 setText(U32 value, LLTextBox* text_box, bool short_val = false);
// <FS:Beq> for render time support
static void updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, 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 setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false);
// </FS:Beq>
static void setIndirectControls(); static void setIndirectControls();
static void setIndirectMaxNonImpostors(); static void setIndirectMaxNonImpostors();
static void setIndirectMaxArc(); static void setIndirectMaxArc();

View File

@ -50,8 +50,6 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this)); mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this)); mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2)); mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2)); mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
@ -82,9 +80,6 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this)); mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
getChild<LLComboBox>("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
return TRUE; return TRUE;
} }
@ -277,8 +272,7 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
} }
// disabled deferred // disabled deferred
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") || if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
!gGLManager.mHasFramebufferObject)
{ {
ctrl_shadows->setEnabled(FALSE); ctrl_shadows->setEnabled(FALSE);
ctrl_shadows->setValue(0); ctrl_shadows->setValue(0);
@ -415,7 +409,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) && ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
gGLManager.mHasFramebufferObject &&
(ctrl_wind_light->get()) ? TRUE : FALSE; (ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled); ctrl_deferred->setEnabled(enabled);

View File

@ -0,0 +1,469 @@
/**
* @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 "llvoavatar.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};
std::mutex bufferToggleLock{};
Tunables tunables;
std::atomic<int> StatsRecorder::writeBuffer{0};
bool StatsRecorder::collectionEnabled{true};
LLUUID StatsRecorder::focusAv{LLUUID::null};
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.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
LLPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("AutoTuneFPS");
LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock");
// 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();
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(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();
}
// static
void StatsRecorder::updateAvatarParams()
{
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);
// 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;
return;
}
// The frametime budget we have based on the target FPS selected
auto target_frame_time_raw = (U64)llround((F64)LLTrace::BlockTimer::countsPerSecond()/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
// 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 > 25?inferredFPS:25};
/*if( tot_limit_time_raw != 0)
{
// This could be problematic.
tot_frame_time_raw -= tot_limit_time_raw;
}*/
// 1) Is the target frame time lower than current?
if( target_frame_time_raw <= tot_frame_time_raw )
{
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_SCENE_AND_AVATARS)
{
// 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 )
{
// 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) )
{
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( LLPerfStats::tunedAvatars > 0 )
{
// if we have more time to spare let's shift up little in the hope we'll restore an avatar.
renderAvatarMaxART_ns += LLPerfStats::ART_MIN_ADJUST_UP_NANOS;
tunables.updateSettingsFromRenderCostLimit();
return;
}
if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
{
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) );
}
}
}
}
}
}

454
indra/newview/llperfstats.h Normal file
View File

@ -0,0 +1,454 @@
/**
* @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{10000};
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};
extern std::atomic<int64_t> tunedAvatars;
extern std::atomic<U64> renderAvatarMaxART_ns;
extern bool belowTargetFPS;
extern U32 lastGlobalPrefChange;
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};
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 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);
// 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 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) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
inline double raw_to_us(U64 raw) { return (static_cast<double>(raw) * 1000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
inline double raw_to_ms(U64 raw) { return (static_cast<double>(raw) * 1000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
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

View File

@ -214,6 +214,7 @@
#include "llstacktrace.h" #include "llstacktrace.h"
#include "fsperfstats.h" #include "fsperfstats.h"
#include "threadpool.h" #include "threadpool.h"
#include "llperfstats.h"
#if LL_WINDOWS #if LL_WINDOWS
@ -2214,9 +2215,8 @@ bool idle_startup()
update_static_eyes(); update_static_eyes();
// </FS:KC> // </FS:KC>
// <FS:Beq>
gAgent.addRegionChangedCallback(boost::bind(&FSPerfStats::StatsRecorder::clearStats)); gAgent.addRegionChangedCallback(boost::bind(&LLPerfStats::StatsRecorder::clearStats));
// </FS:Beq>
// *Note: this is where gWorldMap used to be initialized. // *Note: this is where gWorldMap used to be initialized.
@ -4401,6 +4401,9 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
} }
// [/SL:KB] // [/SL:KB]
LLPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("PerfStatsCaptureEnabled"));
LLPerfStats::StatsRecorder::setFocusAv(gAgentID);
// Agent id needed for parcel info request in LLUrlEntryParcel // Agent id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name. // to resolve parcel name.
LLUrlEntryParcel::setAgentID(gAgentID); LLUrlEntryParcel::setAgentID(gAgentID);

View File

@ -85,6 +85,7 @@
#include "llspellcheck.h" #include "llspellcheck.h"
#include "llslurl.h" #include "llslurl.h"
#include "llstartup.h" #include "llstartup.h"
#include "llperfstats.h"
// [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0) // [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0)
#include "llvisualeffect.h" #include "llvisualeffect.h"
#include "rlvactions.h" #include "rlvactions.h"
@ -112,7 +113,6 @@
#include "llviewerregion.h" #include "llviewerregion.h"
#include "NACLantispam.h" #include "NACLantispam.h"
#include "nd/ndlogthrottle.h" #include "nd/ndlogthrottle.h"
#include "fsperfstats.h"
// <FS:Zi> Run Prio 0 default bento pose in the background to fix splayed hands, open mouths, etc. // <FS:Zi> Run Prio 0 default bento pose in the background to fix splayed hands, open mouths, etc.
#include "llanimationstates.h" #include "llanimationstates.h"
@ -1080,68 +1080,65 @@ void handleDiskCacheSizeChanged(const LLSD& newValue)
} }
// </FS:Ansariel> // </FS:Ansariel>
// <FS:Beq> perrf floater stuffs
void handleTargetFPSChanged(const LLSD& newValue) void handleTargetFPSChanged(const LLSD& newValue)
{ {
const auto targetFPS = gSavedSettings.getU32("FSTargetFPS"); const auto targetFPS = gSavedSettings.getU32("TargetFPS");
FSPerfStats::tunables.userTargetFPS = targetFPS; LLPerfStats::tunables.userTargetFPS = targetFPS;
} }
// <FS:Beq> perf floater stuffs
void handleAutoTuneLockChanged(const LLSD& newValue) void handleAutoTuneLockChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getBOOL("FSAutoTuneLock"); const auto newval = gSavedSettings.getBOOL("AutoTuneLock");
FSPerfStats::tunables.userAutoTuneLock = newval; LLPerfStats::tunables.userAutoTuneLock = newval;
} }
// <FS:Beq> perrf floater stuffs
void handleAutoTuneFPSChanged(const LLSD& newValue) void handleAutoTuneFPSChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getBOOL("FSAutoTuneFPS"); const auto newval = gSavedSettings.getBOOL("AutoTuneFPS");
FSPerfStats::tunables.userAutoTuneEnabled = newval; LLPerfStats::tunables.userAutoTuneEnabled = newval;
if(newval && FSPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max if(newval && LLPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max
{ {
gSavedSettings.setF32("FSRenderAvatarMaxART",log10(FSPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var gSavedSettings.setF32("RenderAvatarMaxART",log10(LLPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var
} }
} }
void handleRenderAvatarMaxARTChanged(const LLSD& newValue) void handleRenderAvatarMaxARTChanged(const LLSD& newValue)
{ {
FSPerfStats::tunables.updateRenderCostLimitFromSettings(); LLPerfStats::tunables.updateRenderCostLimitFromSettings();
} }
void handleUserTargetDrawDistanceChanged(const LLSD& newValue) void handleUserTargetDrawDistanceChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getF32("FSAutoTuneRenderFarClipTarget"); const auto newval = gSavedSettings.getF32("AutoTuneRenderFarClipTarget");
FSPerfStats::tunables.userTargetDrawDistance = newval; LLPerfStats::tunables.userTargetDrawDistance = newval;
} }
void handleUserTargetReflectionsChanged(const LLSD& newValue) void handleUserTargetReflectionsChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getS32("FSUserTargetReflections"); const auto newval = gSavedSettings.getS32("UserTargetReflections");
FSPerfStats::tunables.userTargetReflections = newval; LLPerfStats::tunables.userTargetReflections = newval;
} }
void handlePerformanceStatsEnabledChanged(const LLSD& newValue) void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled"); const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled");
FSPerfStats::StatsRecorder::setEnabled(newval); LLPerfStats::StatsRecorder::setEnabled(newval);
} }
void handleUserImpostorByDistEnabledChanged(const LLSD& newValue) void handleUserImpostorByDistEnabledChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getBOOL("FSAutoTuneImpostorByDistEnabled"); const auto newval = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled");
FSPerfStats::tunables.userImpostorDistanceTuningEnabled = newval; LLPerfStats::tunables.userImpostorDistanceTuningEnabled = newval;
} }
void handleUserImpostorDistanceChanged(const LLSD& newValue) void handleUserImpostorDistanceChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getF32("FSAutoTuneImpostorFarAwayDistance"); const auto newval = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance");
FSPerfStats::tunables.userImpostorDistance = newval; LLPerfStats::tunables.userImpostorDistance = newval;
} }
void handleFPSTuningStrategyChanged(const LLSD& newValue) void handleFPSTuningStrategyChanged(const LLSD& newValue)
{ {
const auto newval = gSavedSettings.getU32("FSTuningFPSStrategy"); const auto newval = gSavedSettings.getU32("TuningFPSStrategy");
FSPerfStats::tunables.userFPSTuningStrategy = newval; LLPerfStats::tunables.userFPSTuningStrategy = newval;
} }
// </FS:Beq>
// <FS:Ansariel> FIRE-6809: Quickly moving the bandwidth slider has no effect // <FS:Ansariel> FIRE-6809: Quickly moving the bandwidth slider has no effect
void handleBandwidthChanged(const LLSD& newValue) void handleBandwidthChanged(const LLSD& newValue)
@ -1194,147 +1191,147 @@ void setting_setup_signal_listener(LLControlGroup& group, const std::string& set
void settings_setup_listeners() void settings_setup_listeners()
{ {
setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged); setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged); setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged); setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 // [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4
setting_setup_signal_listener(gSavedSettings, "RenderResolutionMultiplier", handleRenderResolutionDivisorChanged); setting_setup_signal_listener(gSavedSettings, "RenderResolutionMultiplier", handleRenderResolutionDivisorChanged);
// [/SL:KB] // [/SL:KB]
setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleShadowDetailChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
setting_setup_signal_listener(gSavedSettings, "RenderHiDPI", handleRenderHiDPIChanged); setting_setup_signal_listener(gSavedSettings, "RenderHiDPI", handleRenderHiDPIChanged);
setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged); setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged); setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged); setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged); setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged); setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged); setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged); setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged); setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", 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, "AgentPause", toggle_agent_pause);
// <FS:Zi> Is done inside XUI now, using visibility_control // <FS:Zi> Is done inside XUI now, using visibility_control
// setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); // setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel);
// </FS:Zi> // </FS:Zi>
@ -1342,16 +1339,27 @@ void settings_setup_listeners()
// setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); // setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel);
// </FS: Zi> // </FS: Zi>
setting_setup_signal_listener(gSavedSettings, "ShowMenuBarLocation", toggle_show_menubar_location_panel); setting_setup_signal_listener(gSavedSettings, "ShowMenuBarLocation", toggle_show_menubar_location_panel);
setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost); setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid); setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
// <FS:Ansariel> Show start location setting has no effect on login // <FS:Ansariel> Show start location setting has no effect on login
setting_setup_signal_listener(gSavedSettings, "ShowStartLocation", handleForceShowGrid); setting_setup_signal_listener(gSavedSettings, "ShowStartLocation", handleForceShowGrid);
setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged); setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged); setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged); setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged); setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged); setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged); 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); setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
@ -1439,18 +1447,6 @@ void settings_setup_listeners()
// <FS:Ansariel> Better asset cache size control // <FS:Ansariel> Better asset cache size control
setting_setup_signal_listener(gSavedSettings, "FSDiskCacheSize", handleDiskCacheSizeChanged); setting_setup_signal_listener(gSavedSettings, "FSDiskCacheSize", handleDiskCacheSizeChanged);
// <FS:Beq> perf floater controls
setting_setup_signal_listener(gSavedSettings, "FSTargetFPS", handleTargetFPSChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneFPS", handleAutoTuneFPSChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneLock", handleAutoTuneLockChanged);
setting_setup_signal_listener(gSavedSettings, "FSRenderAvatarMaxART", handleRenderAvatarMaxARTChanged);
setting_setup_signal_listener(gSavedSettings, "FSPerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "FSUserTargetReflections", handleUserTargetReflectionsChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "FSTuningFPSStrategy", handleFPSTuningStrategyChanged);
// </FS:Beq>
// <FS:Zi> Handle IME text input getting enabled or disabled // <FS:Zi> Handle IME text input getting enabled or disabled
#if LL_SDL2 #if LL_SDL2

View File

@ -78,6 +78,7 @@
#include "llscenemonitor.h" #include "llscenemonitor.h"
#include "llenvironment.h" #include "llenvironment.h"
#include "llperfstats.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "llvisualeffect.h" #include "llvisualeffect.h"
#include "rlvactions.h" #include "rlvactions.h"
@ -85,7 +86,6 @@
// [/RLVa:KB] // [/RLVa:KB]
#include "llpresetsmanager.h" #include "llpresetsmanager.h"
#include "fsdata.h" #include "fsdata.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
extern LLPointer<LLViewerTexture> gStartTexture; extern LLPointer<LLViewerTexture> gStartTexture;
extern bool gShiftFrame; extern bool gShiftFrame;
@ -287,8 +287,8 @@ static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");
// Paint the display! // Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{ {
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_DISPLAY); // <FS:Beq/> render time capture - This is the main stat for overall rendering. 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); LL_RECORD_BLOCK_TIME(FTM_RENDER);
LLViewerCamera& camera = LLViewerCamera::instance(); // <FS:Ansariel> Factor out calls to getInstance LLViewerCamera& camera = LLViewerCamera::instance(); // <FS:Ansariel> Factor out calls to getInstance
@ -1167,9 +1167,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.clearReferences(); gPipeline.clearReferences();
gPipeline.rebuildGroups(); gPipeline.rebuildGroups();
// <FS:Ansariel> [FS performance floater]
//gPipeline.autoAdjustSettings();
} }
LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
@ -1197,8 +1194,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
void render_hud_attachments() void render_hud_attachments()
{ {
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_HUDS); // <FS:Beq/> render time capture - Primary contributor to HUDs (though these end up in render batches) 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.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix(); gGL.pushMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix(); gGL.pushMatrix();
@ -1405,8 +1402,8 @@ bool setup_hud_matrices(const LLRect& screen_region)
void render_ui(F32 zoom_factor, int subfield) void render_ui(F32 zoom_factor, int subfield)
{ {
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_UI ); // <FS:Beq/> render time capture - Primary UI stat can have HUD time overlap (TODO) 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); LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
LLGLState::checkStates(); LLGLState::checkStates();
@ -1495,8 +1492,8 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
void swap() void swap()
{ {
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SWAP ); // <FS:Beq/> render time capture - Swap buffer time - can signify excessive data transfer to/from GPU 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); LL_RECORD_BLOCK_TIME(FTM_SWAP);
if (gDisplaySwapBuffers) if (gDisplaySwapBuffers)
{ {

View File

@ -55,7 +55,7 @@
#include "m3math.h" #include "m3math.h"
#include "m4math.h" #include "m4math.h"
#include "llmatrix4a.h" #include "llmatrix4a.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support #include "llperfstats.h"
#if !LL_DARWIN && !LL_LINUX #if !LL_DARWIN && !LL_LINUX
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
@ -232,15 +232,16 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
return 0; return 0;
} }
// <FS:Beq> render time capture // render time capture
// TODO(Beq) This path does not appear to have attachments. Prove this then remove. // This path does not appear to have attachments. Prove this then remove.
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
auto vobj = mFace->getViewerObject(); auto vobj = mFace->getViewerObject();
if( vobj && vobj->isAttachment() ) if( vobj && vobj->isAttachment() )
{ {
trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr ); trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
} LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL;
// </FS:Beq> }
U32 triangle_count = 0; U32 triangle_count = 0;
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel; S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;

View File

@ -718,7 +718,7 @@ void LLViewerPartSim::updateSimulation()
if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME)) if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME))
{ {
if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex()) if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex() && vobj->getAvatar()->isTooSlowWithShadows())
{ {
upd = FALSE; upd = FALSE;
} }

View File

@ -58,6 +58,7 @@
#include "llfeaturemanager.h" #include "llfeaturemanager.h"
#include "llviewernetwork.h" #include "llviewernetwork.h"
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
#include "llperfstats.h"
#include "llsdserialize.h" #include "llsdserialize.h"
#include "llsdutil.h" #include "llsdutil.h"
#include "llcorehttputil.h" #include "llcorehttputil.h"
@ -214,6 +215,13 @@ LLTrace::EventStatHandle<F64Seconds > AVATAR_EDIT_TIME("avataredittime", "Second
LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits"); LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits");
LLTrace::EventStatHandle<F64Seconds > TEXTURE_FETCH_TIME("texture_fetch_time"); 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() LLViewerStats::LLViewerStats()
@ -420,6 +428,89 @@ void update_statistics()
texture_stats_timer.reset(); 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() void update_texture_time()

View File

@ -119,6 +119,8 @@
#include "llrendersphere.h" #include "llrendersphere.h"
#include "llskinningutil.h" #include "llskinningutil.h"
#include "llperfstats.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "fscommon.h" #include "fscommon.h"
@ -2702,10 +2704,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL; LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL;
return; return;
} }
// <FS:Beq> record time and refresh "tooSlow" status // record time and refresh "tooSlow" status
FSPerfStats::RecordAvatarTime T(getID(), FSPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time. LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.
updateTooSlow(); updateTooSlow();
// </FS:Beq>;
static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes"); static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)) if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
&& !disable_all_render_types && !isSelf()) && !disable_all_render_types && !isSelf())
@ -3358,7 +3360,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
// Firestorm Clouds // Firestorm Clouds
// do not generate particles for dummy or overly-complex avatars // do not generate particles for dummy or overly-complex avatars
if (!mIsDummy && !isTooComplex()) if (!mIsDummy && !isTooComplex() && !isTooSlowWithShadows())
{ {
setParticleSource(sCloud, getID()); setParticleSource(sCloud, getID());
} }
@ -4306,7 +4308,7 @@ bool LLVOAvatar::isVisuallyMuted()
// </FS:Ansariel> // </FS:Ansariel>
else else
{ {
muted = isTooComplex(); muted = isTooComplex() || isTooSlowWithShadows();
} }
} }
@ -9311,6 +9313,94 @@ bool LLVOAvatar::isTooComplex() const
return too_complex; return too_complex;
} }
// 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;
}
if( (LLPerfStats::renderAvatarMaxART_ns > 0) &&
(LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns) )
{
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(mTooSlow)
{
LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked.
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// findMotion() // findMotion()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -12382,7 +12472,7 @@ LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
{ // Always want to see this AV as an impostor { // Always want to see this AV as an impostor
result = AOA_JELLYDOLL; result = AOA_JELLYDOLL;
} }
else if (isTooComplex()) else if (isTooComplex() || isTooSlowWithShadows())
{ {
result = AOA_JELLYDOLL; result = AOA_JELLYDOLL;
} }
@ -12417,7 +12507,7 @@ void LLVOAvatar::calcMutedAVColor()
new_color = LLColor4::grey4; new_color = LLColor4::grey4;
change_msg = " blocked: color is grey4"; change_msg = " blocked: color is grey4";
} }
else if (!isTooComplex()) else if (!isTooComplex() && !isTooSlowWithShadows())
{ {
new_color = LLColor4::white; new_color = LLColor4::white;
change_msg = " simple imposter "; change_msg = " simple imposter ";

View File

@ -367,17 +367,18 @@ public:
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public: public:
BOOL isFullyLoaded() const; BOOL isFullyLoaded() const;
// <FS:Beq> check and return current state relative to limits
// default will test only the geometry (combined=false). // check and return current state relative to limits
// this allows us to disable shadows separately on complex avatars. // default will test only the geometry (combined=false).
inline bool isTooSlowWithShadows() const {return mTooSlow;}; // this allows us to disable shadows separately on complex avatars.
inline bool isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;}; inline bool isTooSlowWithShadows() const {return mTooSlow;};
inline bool isTooSlow(bool combined = false) const inline bool isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;};
{ inline bool isTooSlow(bool combined = false) const
return(combined?mTooSlow:mTooSlowWithoutShadows); {
} return(combined?mTooSlow:mTooSlowWithoutShadows);
void updateTooSlow(); }
// </FS:Beq> void updateTooSlow();
virtual bool isTooComplex() const; // <FS:Ansariel> FIRE-29012: Standalone animesh avatars get affected by complexity limit; changed to virtual virtual bool isTooComplex() const; // <FS:Ansariel> FIRE-29012: Standalone animesh avatars get affected by complexity limit; changed to virtual
bool visualParamWeightsAreDefault(); bool visualParamWeightsAreDefault();
virtual bool getIsCloud() const; virtual bool getIsCloud() const;
@ -399,7 +400,7 @@ public:
void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed); void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
void calcMutedAVColor(); void calcMutedAVColor();
void markARTStale(); void markARTStale();
protected: protected:
LLViewerStats::PhaseMap& getPhases() { return mPhases; } LLViewerStats::PhaseMap& getPhases() { return mPhases; }
@ -430,6 +431,15 @@ private:
bool mTooSlowWithoutShadows{false}; bool mTooSlowWithoutShadows{false};
// </FS:Beq> // </FS:Beq>
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};
private: private:
LLViewerStats::PhaseMap mPhases; LLViewerStats::PhaseMap mPhases;
@ -1233,7 +1243,7 @@ public:
// COF version of last appearance message received for this av. // COF version of last appearance message received for this av.
S32 mLastUpdateReceivedCOFVersion; S32 mLastUpdateReceivedCOFVersion;
U64 getLastART() const { return mRenderTime; } U64 getLastART() const { return mRenderTime; }
/** Diagnostics /** Diagnostics
** ** ** **

View File

@ -88,12 +88,12 @@
#include "llcallstack.h" #include "llcallstack.h"
#include "llsculptidsize.h" #include "llsculptidsize.h"
#include "llavatarappearancedefines.h" #include "llavatarappearancedefines.h"
#include "llperfstats.h"
// [RLVa:KB] - Checked: RLVa-2.0.0 // [RLVa:KB] - Checked: RLVa-2.0.0
#include "rlvactions.h" #include "rlvactions.h"
#include "rlvlocks.h" #include "rlvlocks.h"
// [/RLVa:KB] // [/RLVa:KB]
#include "llviewernetwork.h" #include "llviewernetwork.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f; const F32 FORCE_CULL_AREA = 8.f;
@ -5900,7 +5900,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("rebuildGeom - face list"); LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("rebuildGeom - face list");
//get all the faces into a list //get all the faces into a list
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
drawable_iter != group->getDataEnd(); ++drawable_iter) drawable_iter != group->getDataEnd(); ++drawable_iter)
{ {
@ -5943,6 +5943,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
} }
// </FS:Beq> // </FS:Beq>
if(vobj->isAttachment())
{
trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr);
}
LLVolume* volume = vobj->getVolume(); LLVolume* volume = vobj->getVolume();
if (volume) if (volume)
{ {
@ -6372,7 +6377,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
U32 buffer_count = 0; U32 buffer_count = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> capture render times std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{ {
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
@ -6384,8 +6389,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if (!vobj) continue; if (!vobj) continue;
// <FS:Beq> capture render times if (vobj->isAttachment())
if (vobj->isAttachment())
{ {
trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr ); trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr );
} }
@ -6833,18 +6837,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 indices_index = 0; U32 indices_index = 0;
U16 index_offset = 0; U16 index_offset = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr; // <FS:Beq/> capture render times std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr;
while (face_iter < i) while (face_iter < i)
{ {
//update face indices for new buffer //update face indices for new buffer
facep = *face_iter; facep = *face_iter;
LLViewerObject* vobj = facep->getViewerObject(); LLViewerObject* vobj = facep->getViewerObject();
// <FS:Beq> capture render times if(vobj && vobj->isAttachment())
if(vobj && vobj->isAttachment()) {
{ trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr); }
}
// </FS:Beq>
if (buffer.isNull()) if (buffer.isNull())
{ {
// Bulk allocation failed // Bulk allocation failed

View File

@ -140,7 +140,7 @@
// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml // NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables. // NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2; // const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2;
const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1; const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
const S32 WATER_REFLECT_MINIMAL = 0; const S32 WATER_REFLECT_MINIMAL = 0;
// const S32 WATER_REFLECT_TERRAIN = 1; // const S32 WATER_REFLECT_TERRAIN = 1;
@ -438,7 +438,6 @@ LLPipeline::LLPipeline() :
mLightingDetail(0), mLightingDetail(0),
mScreenWidth(0), mScreenWidth(0),
mScreenHeight(0) mScreenHeight(0)
//mUpdateTimer(new LLTimer()) // <FS:Ansariel> [FS performance floater]
{ {
mNoiseMap = 0; mNoiseMap = 0;
mTrueNoiseMap = 0; mTrueNoiseMap = 0;
@ -670,23 +669,19 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("CameraDoFResScale"); connectRefreshCachedSettingsSafe("CameraDoFResScale");
connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
// <FS:Ansariel> [FS performance floater]
//gSavedSettings.getControl("AutoFPS")->getCommitSignal()->connect(boost::bind(&LLPipeline::onToggleAutoFPS));
connectRefreshCachedSettingsSafe("FSRenderVignette"); // <FS:CR> Import Vignette from Exodus connectRefreshCachedSettingsSafe("FSRenderVignette"); // <FS:CR> Import Vignette from Exodus
// <FS:Ansariel> Make change to RenderAttachedLights & RenderAttachedParticles instant // <FS:Ansariel> Make change to RenderAttachedLights & RenderAttachedParticles instant
connectRefreshCachedSettingsSafe("RenderAttachedLights"); connectRefreshCachedSettingsSafe("RenderAttachedLights");
connectRefreshCachedSettingsSafe("RenderAttachedParticles"); connectRefreshCachedSettingsSafe("RenderAttachedParticles");
// </FS:Ansariel> // </FS:Ansariel>
// <FS:Beq> FIRE-16728 Add free aim mouse and focus lock // <FS:Beq> FIRE-16728 Add free aim mouse and focus lock
connectRefreshCachedSettingsSafe("FSFocusPointLocked");
connectRefreshCachedSettingsSafe("FSFocusPointFollowsPointer"); connectRefreshCachedSettingsSafe("FSFocusPointFollowsPointer");
connectRefreshCachedSettingsSafe("FSFocusPointLocked");
// </FS:Beq> // </FS:Beq>
} }
LLPipeline::~LLPipeline() LLPipeline::~LLPipeline()
{ {
// <FS:Ansariel> [FS performance floater]
//delete mUpdateTimer;
} }
void LLPipeline::cleanup() void LLPipeline::cleanup()
@ -6228,7 +6223,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
LLDrawable* drawable = light->drawable; LLDrawable* drawable = light->drawable;
const LLViewerObject *vobj = light->drawable->getVObj(); const LLViewerObject *vobj = light->drawable->getVObj();
if(vobj && vobj->getAvatar() if(vobj && vobj->getAvatar()
&& (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()) && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlowWithShadows())
) )
{ {
drawable->clearState(LLDrawable::NEARBY_LIGHT); drawable->clearState(LLDrawable::NEARBY_LIGHT);
@ -6307,7 +6302,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue; continue;
} }
LLVOAvatar * av = light->getAvatar(); LLVOAvatar * av = light->getAvatar();
if (av && (av->isTooComplex() || av->isInMuteList())) if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlowWithShadows()))
{ {
// avatars that are already in the list will be removed by removeMutedAVsLights // avatars that are already in the list will be removed by removeMutedAVsLights
continue; continue;
@ -11217,12 +11212,12 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
<< " is " << ( too_complex ? "" : "not ") << "too complex" << " is " << ( too_complex ? "" : "not ") << "too complex"
<< LL_ENDL; << LL_ENDL;
bool too_slow = avatar->isTooSlowWithoutShadows(); // <FS:Beq/> only if we really have to do we imposter. bool too_slow = avatar->isTooSlowWithShadows();
pushRenderTypeMask(); pushRenderTypeMask();
if ( !too_slow && ( visually_muted || too_complex ) ) if ( !too_slow && ( visually_muted || too_complex ) )
{ {
// only show jelly doll geometry // only show jelly doll geometry
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_CONTROL_AV,
@ -11938,146 +11933,6 @@ void LLPipeline::handleShadowDetailChanged()
} }
} }
// <FS:Ansariel> [FS performance floater]
//const F32 MIN_DRAW_DISTANCE = 64;
//const F32 MAX_DRAW_DISTANCE = 256;
//
//void update_far_clip(F32 fps_dif)
//{
// F32 DIST_PER_FRAME_DIF = 16;
//
// F32 new_far_clip = llclamp(LLPipeline::RenderFarClip - llmin(fps_dif * DIST_PER_FRAME_DIF, (F32)128), MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE);
// gSavedSettings.setF32("RenderFarClip", new_far_clip);
//}
//
//void update_max_non_impostors(F32 fps_dif, S32 max_avatars)
//{
// const F32 IMPOSTORS_PER_FRAME_DIF = 0.5;
//
// U32 new_non_imp = (U32)llclamp((S32)(LLVOAvatar::sMaxNonImpostors - llmin((S32)(fps_dif / IMPOSTORS_PER_FRAME_DIF), 10)), 1, max_avatars);
// gSavedSettings.setU32("RenderAvatarMaxNonImpostors", new_non_imp);
//}
//
//void LLPipeline::autoAdjustSettings()
//{
// static LLCachedControl<bool> use_auto_adjustment(gSavedSettings,"AutoFPS");
// if (!use_auto_adjustment)
// {
// return;
// }
//
// if (LLStartUp::getStartupState() < STATE_STARTED || LLApp::isExiting())
// {
// return;
// }
//
// static LLCachedControl<F32> adjustment_timeout(gSavedSettings, "AutoAdjustmentTimeout");
// static LLCachedControl<F32> initial_adjustment_timeout(gSavedSettings, "InitialAdjustmentTimeout");
//
// static LLCachedControl<S32> fps_lower_boundary(gSavedSettings, "AutoFPSLowerBoundary");
// static LLCachedControl<S32> fps_upper_boundary(gSavedSettings, "AutoFPSUpperBoundary");
//
// if (gViewerWindow && gViewerWindow->getWindow()->getVisible()
// && gFocusMgr.getAppHasFocus() && !gTeleportDisplay)
// {
// static bool is_init = false;
// if (!is_init)
// {
// //wait for FPS to stabilize after login in-world
// mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
// is_init = true;
// }
// if (mUpdateTimer->hasExpired())
// {
// mUpdateTimer->setTimerExpirySec((F32)adjustment_timeout);
//
// const S32 FPS_STAT_PERIODS = 50;
// S32 fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, FPS_STAT_PERIODS));
// if (fps < fps_lower_boundary)
// {
// S32 fps_dif = fps_lower_boundary - fps;
//
// if (sWaterReflections && RenderReflectionDetail > WATER_REFLECT_NONE_WATER_OPAQUE)
// {
// S32 reflection_detail = llclamp(RenderReflectionDetail - 1, WATER_REFLECT_NONE_WATER_OPAQUE, WATER_REFLECT_MINIMAL);
// gSavedSettings.setS32("RenderReflectionDetail", reflection_detail);
// return;
// }
//
// if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits > 0)
// {
// S32 shadow_splits = llclamp(RenderShadowSplits - 1, 0, 3);
// gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
// return;
// }
//
// if (RenderFarClip > MIN_DRAW_DISTANCE)
// {
// update_far_clip(fps_dif);
// }
//
// std::vector<LLCharacter*> valid_nearby_avs;
// LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
//
// if (valid_nearby_avs.size() > 1 && LLVOAvatar::sMaxNonImpostors > 1)
// {
// update_max_non_impostors(fps_dif, valid_nearby_avs.size());
// }
// }
// else if (fps > fps_upper_boundary)
// {
// S32 fps_dif = fps_upper_boundary - fps;
//
// std::vector<LLCharacter*> valid_nearby_avs;
// LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
// if (valid_nearby_avs.size() > 1 && (LLVOAvatar::sMaxNonImpostors < valid_nearby_avs.size()))
// {
// update_max_non_impostors(fps_dif, valid_nearby_avs.size());
// return;
// }
//
// if (RenderFarClip < MAX_DRAW_DISTANCE)
// {
// update_far_clip(fps_dif);
// }
//
// if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits < 3)
// {
// S32 shadow_splits = llclamp(RenderShadowSplits + 1, 0, 3);
// gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
// return;
// }
//
// if (sWaterReflections && RenderReflectionDetail < WATER_REFLECT_MINIMAL)
// {
// S32 reflection_detail = llclamp(RenderReflectionDetail + 1, WATER_REFLECT_NONE_WATER_OPAQUE, WATER_REFLECT_MINIMAL);
// gSavedSettings.setS32("RenderReflectionDetail", reflection_detail);
// }
// }
// }
// }
// else
// {
// //wait for FPS to stabilize if the window was minimized or not focused before
// mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
// }
//}
//
//void LLPipeline::setAdjustmentTimerExpiry(F32 expiration)
//{
// mUpdateTimer->setTimerExpirySec(expiration);
//}
//
//void LLPipeline::onToggleAutoFPS()
//{
// if (!gSavedSettings.getBOOL("AutoFPS"))
// {
// //reset the number of shadow map splits rendered, when disabling auto-fps
// //probably should be removed, if we'll have actual UI control for this setting
// gSavedSettings.setS32("RenderShadowSplits", 3);
// }
//}
// </FS:Ansariel> [FS performance floater]
// <FS:Ansariel> Reset VB during TP // <FS:Ansariel> Reset VB during TP
void LLPipeline::initDeferredVB() void LLPipeline::initDeferredVB()

View File

@ -418,9 +418,6 @@ public:
static void updateRenderDeferred(); static void updateRenderDeferred();
static void refreshCachedSettings(); static void refreshCachedSettings();
// <FS:Ansariel> [FS performance floater]
//static void onToggleAutoFPS();
void addDebugBlip(const LLVector3& position, const LLColor4& color); void addDebugBlip(const LLVector3& position, const LLColor4& color);
void hidePermanentObjects( std::vector<U32>& restoreList ); void hidePermanentObjects( std::vector<U32>& restoreList );
@ -430,10 +427,6 @@ public:
void restoreHiddenObject( const LLUUID& id ); void restoreHiddenObject( const LLUUID& id );
void handleShadowDetailChanged(); void handleShadowDetailChanged();
// <FS:Ansariel> [FS performance floater]
//void autoAdjustSettings();
//void setAdjustmentTimerExpiry(F32 expiration);
private: private:
void unloadShaders(); void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp ); void addToQuickLookup( LLDrawPool* new_poolp );
@ -757,9 +750,6 @@ protected:
U64 mOldRenderDebugMask; U64 mOldRenderDebugMask;
std::stack<U32> mRenderDebugFeatureStack; std::stack<U32> mRenderDebugFeatureStack;
// <FS:Ansariel> [FS performance floater]
//LLTimer* mUpdateTimer;
///////////////////////////////////////////// /////////////////////////////////////////////
// //
// //

View File

@ -556,6 +556,52 @@ HUDs
top="19" top="19"
right="-20" /> right="-20" />
</panel> </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="autoadjustments_subpanel"
layout="topleft"
top_pad="10">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="auto_adj_lbl"
top="7"
width="175">
Preferred frame rate
</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 (advanced).
</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>
<panel <panel
filename="panel_performance_nearby.xml" filename="panel_performance_nearby.xml"
@ -582,19 +628,19 @@ HUDs
visible="false" visible="false"
top="115" /> top="115" />
<panel <panel
filename="panel_performance_huds.xml" filename="panel_performance_huds.xml"
follows="all" follows="all"
layout="topleft" layout="topleft"
left="0" left="0"
name="panel_performance_huds" name="panel_performance_huds"
visible="false" visible="false"
top="115" /> top="55" />
<panel <panel
filename="panel_performance_autotune.xml" filename="panel_performance_autoadjustments.xml"
follows="all" follows="all"
layout="topleft" layout="topleft"
left="0" left="0"
name="panel_performance_autotune" name="panel_performance_autoadjustments"
visible="false" visible="false"
top="115" /> top="55" />
</floater> </floater>

View File

@ -40,8 +40,6 @@
name="DrawDistance" name="DrawDistance"
top_delta="16" top_delta="16"
width="330"> width="330">
<slider.mouse_down_callback
function="Pref.AutoAdjustWarning" />
</slider> </slider>
<text <text
type="string" type="string"
@ -185,8 +183,6 @@
<slider.commit_callback <slider.commit_callback
function="Pref.UpdateIndirectMaxNonImpostors" function="Pref.UpdateIndirectMaxNonImpostors"
parameter="IndirectNonImpostorsText" /> parameter="IndirectNonImpostorsText" />
<slider.mouse_down_callback
function="Pref.AutoAdjustWarning" />
</slider> </slider>
<text <text
type="string" type="string"

View File

@ -409,6 +409,59 @@
</stat_view> </stat_view>
</stat_view> </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> </container_view>
</scroll_container> </scroll_container>
</floater> </floater>

View File

@ -0,0 +1,315 @@
<?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="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="white"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="settings_title"
width="300">
Preferred frame rate
</text>
<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="140"
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="right|top"
left_pad="5"
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" />
<button
control_name="AutoTuneFPS"
follows="top|right"
height="24"
initial_value="false"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
label="Start"
label_selected="Stop"
layout="topleft"
left_pad="10"
name="AutoTuneFPS"
top_delta="-1"
tool_tip="The viewer will attempt to adjust settings to meet the target FPS."
width="72">
</button>
<check_box
control_name="AutoTuneLock"
follows="top|right"
height="20"
initial_value="true"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
label="Continuous"
layout="topleft"
left_pad="10"
name="AutoTuneContinuous"
top_delta="0"
tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Start button will adjust for the current settings then stop."
width="64">
</check_box>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="20"
name="settings_desc"
top_pad="20"
wrap="true"
width="150">
Settings affect
</text>
<combo_box
follows="top|left"
font="SansSerif"
height="20"
layout="topleft"
left_pad="15"
control_name="TuningFPSStrategy"
name="TuningFPSStrategy"
width="130">
<combo_box.item
label="Avatars Only"
name="av_only"
value="0" />
<combo_box.item
label="Avatars and Scene"
name="av_and_scene"
value="1" />
</combo_box>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border_vsync"
top_pad="20"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="20"
name="vsync_desc"
width="580">
Synchronize the refresh rate and frame rate of a monitor,
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="3"
left="20"
name="vsync_desc2"
width="580">
which can result in smoother performance.
</text>
<check_box
control_name="RenderVSyncEnable"
height="16"
initial_value="true"
label="Enable VSync"
label_text.text_color="White"
layout="topleft"
top_pad="15"
name="vsync"
tool_tip="Enable Vertical synchronization to reduce screen tearing and stuttering."
width="315" />
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border1"
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="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="20"
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>

View File

@ -69,23 +69,22 @@ top="0">
Hide the most complex avatars to boost speed. Hide the most complex avatars to boost speed.
</text> </text>
<slider <slider
control_name="IndirectMaxComplexity" control_name="RenderAvatarMaxART"
visible="false" tool_tip="Controls when a visually complex avatar is considered to be taking too long to render (unit: microseconds)"
tool_tip="Controls at what point a visually complex avatar is drawn as a Impostor"
follows="left|top" follows="left|top"
height="16" height="16"
initial_value="101" initial_value="4.7"
increment="1" increment="0.01"
label="Maximum complexity (K)" label="Maximum render time (μs)"
text_color="White" text_color="White"
label_width="165" label_width="165"
layout="topleft" layout="topleft"
min_val="1" min_val="2"
max_val="101" max_val="4.7"
name="IndirectMaxComplexity" name="RenderAvatarMaxART"
show_text="false" show_text="false"
top_pad="10" top_pad="10"
width="300"> width="490">
</slider> </slider>
<text <text
type="string" type="string"
@ -95,11 +94,11 @@ top="0">
height="16" height="16"
layout="topleft" layout="topleft"
top_delta="0" top_delta="0"
left_delta="304" left_pad="5"
text_color="White" text_color="White"
name="IndirectMaxComplexityText" name="RenderAvatarMaxARTText"
width="65"> width="65">
0 no limit
</text> </text>
<slider <slider
control_name="FSRenderAvatarMaxART" control_name="FSRenderAvatarMaxART"

View File

@ -220,6 +220,94 @@ Faster
Ultra Ultra
</text> </text>
<text <text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="30"
name="quality_lbl"
width="100">
Quality &amp; 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" follows="left|top"
font="SansSerifSmall" font="SansSerifSmall"
text_color="White" text_color="White"
@ -279,7 +367,8 @@ Faster
max_val="1024" max_val="1024"
name="draw_distance" name="draw_distance"
left_pad="5" left_pad="5"
width="310" /> width="250">
</slider>
<text <text
type="string" type="string"
length="1" length="1"
@ -513,4 +602,99 @@ help you find the right balance.
function="Button.SetFloaterToggle" function="Button.SetFloaterToggle"
parameter="phototools"/> parameter="phototools"/>
</button> </button>
<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> </panel>

View File

@ -52,6 +52,175 @@
(None) (None)
</text> </text>
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left="10"
name="QualitySpeed"
top_delta="35"
width="400">
Quality &amp; speed:
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left="118"
name="ShadersPrefText"
top_delta="0"
width="80">
Low
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left_delta="87"
name="ShadersPrefText2"
top_delta="0"
width="80">
Mid
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left_delta="87"
name="ShadersPrefText3"
top_delta="0"
width="80">
High
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left_delta="85"
name="ShadersPrefText4"
top_delta="0"
width="80">
Ultra
</text>
<text
type="string"
length="1"
follows="left|top"
halign="right"
height="12"
layout="topleft"
left="65"
name="FasterText"
top_pad="4"
width="80">
Faster
</text>
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left_delta="360"
name="BetterText"
top_delta="0"
width="100">
Better
</text>
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left="158"
name="LowGraphicsDivet"
top_delta="-2"
width="2" />
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="LowMidGraphicsDivet"
width="2" />
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="MidGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="MidHighGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="HighGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="HighUltraGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="UltraGraphicsDivet"
top_delta="0"
width="2" />
<slider
control_name="RenderQualityPerformance"
decimal_digits="0"
follows="left|top"
height="16"
increment="1"
initial_value="0"
layout="topleft"
left="150"
max_val="6"
name="QualityPerformanceSelection"
show_text="false"
top_delta="-2"
width="275">
<slider.commit_callback
function="Pref.QualityPerformance"/>
</slider>
<text <text
type="string" type="string"
length="1" length="1"
@ -321,42 +490,34 @@
function="Pref.RenderOptionUpdate" /> function="Pref.RenderOptionUpdate" />
</check_box> </check_box>
<text <slider
type="string" control_name="RenderFarClip"
length="1" decimal_digits="0"
top_pad="4" follows="left|top"
follows="top|left" height="16"
height="12" increment="8"
width="110" initial_value="160"
word_wrap="true" label="Draw distance:"
layout="topleft" label_width="90"
left_delta="-5" layout="topleft"
name="shadows_label"> left="30"
Shadows: min_val="64"
</text> max_val="512"
<combo_box name="DrawDistance"
control_name="RenderShadowDetail" top_delta="40"
height="23" width="330" />
layout="topleft" <text
left_delta="5" type="string"
top_pad="3" length="1"
name="ShadowDetail" follows="left|top"
width="150"> height="12"
<combo_box.commit_callback layout="topleft"
function="Pref.RenderOptionUpdate" /> left_delta="330"
<combo_box.item name="DrawDistanceMeterText2"
label="None" top_delta="0"
name="0" width="128">
value="0"/> m
<combo_box.item </text>
label="Sun/Moon"
name="1"
value="1"/>
<combo_box.item
label="Sun/Moon + Projectors"
name="2"
value="2"/>
</combo_box>
<text <text
type="string" type="string"
@ -608,18 +769,65 @@
top_pad="5" top_pad="5"
width="297"/> width="297"/>
<text <button
type="string" height="23"
length="1" label="Automatic adjustments settings"
follows="left|top" layout="topleft"
height="12" left="30"
layout="topleft" name="AutoAdjustmentsButton"
left="200" top_delta="30"
name="MeshDetailText" width="200">
top_pad="10" <button.commit_callback
width="400"> function="Pref.AutoAdjustments"/>
Level of Detail (LOD) Distance Factors: </button>
</text>
<slider
control_name="IndirectMaxComplexity"
tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
follows="left|top"
height="16"
initial_value="101"
increment="1"
label="Avatar Maximum Complexity:"
label_width="165"
layout="topleft"
left="30"
min_val="1"
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
top_delta="40"
width="300">
<slider.commit_callback
function="Pref.UpdateIndirectMaxComplexity"
parameter="IndirectMaxComlexityText" />
</slider>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
top_delta="0"
left_delta="304"
text_readonly_color="LabelDisabledColor"
name="IndirectMaxComplexityText"
width="65">
0
</text>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
left_delta="68"
name="IndirectMaxComplexityLink"
mouse_opaque="false"
top_delta="0"
width="120">
[https://community.secondlife.com/t5/Featured-News/Why-are-all-these-people-made-of-colored-jelly/ba-p/3031255 What's this?]
</text>
<slider <slider
control_name="RenderVolumeLODFactor" control_name="RenderVolumeLODFactor"