Initial intergation of ART with LL Perf floater
parent
31f358f451
commit
8b80fa2779
|
|
@ -28,4 +28,11 @@
|
|||
namespace FSTelemetry
|
||||
{
|
||||
bool active{false};
|
||||
|
||||
int RecordSceneTime::writeBuffer{0};
|
||||
|
||||
bool RecordSceneTime::collectionEnabled{true};
|
||||
|
||||
std::array< typename RecordSceneTime::StatsArray, 2 > RecordSceneTime::stats{ {} };
|
||||
|
||||
}
|
||||
|
|
@ -63,9 +63,178 @@
|
|||
#define FSTelemetryIsConnected
|
||||
#endif // TRACY_ENABLE
|
||||
|
||||
#include <chrono>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace FSTelemetry
|
||||
{
|
||||
extern bool active;
|
||||
}
|
||||
|
||||
enum class ObjStatType_t{
|
||||
RENDER_GEOMETRY=0,
|
||||
RENDER_SHADOWS,
|
||||
RENDER_COMBINED,
|
||||
STATS_COUNT
|
||||
};
|
||||
enum class SceneStatType_t{
|
||||
RENDER_GEOMETRY=0,
|
||||
RENDER_SHADOWS,
|
||||
RENDER_HUDS,
|
||||
RENDER_UI,
|
||||
RENDER_COMBINED,
|
||||
RENDER_SWAP,
|
||||
RENDER_FRAME,
|
||||
RENDER_SLEEP,
|
||||
RENDER_LFS,
|
||||
RENDER_MESHREPO,
|
||||
RENDER_FPSLIMIT,
|
||||
RENDER_FPS,
|
||||
STATS_COUNT
|
||||
};
|
||||
|
||||
using ObjStatType = ObjStatType_t;
|
||||
using SceneStatType = SceneStatType_t;
|
||||
|
||||
class RecordSceneTime
|
||||
{
|
||||
using StatsEnum = SceneStatType;
|
||||
using StatsArray = std::array<uint64_t, static_cast<size_t>(StatsEnum::STATS_COUNT)>;
|
||||
// using StatsBlock = std::unordered_map<T, StatsArray>;
|
||||
|
||||
static int writeBuffer;
|
||||
static std::array<StatsArray,2> stats;
|
||||
static bool collectionEnabled;
|
||||
|
||||
RecordSceneTime(const RecordSceneTime&) = delete;
|
||||
RecordSceneTime() = delete;
|
||||
|
||||
const StatsEnum type;
|
||||
std::chrono::steady_clock::time_point start;
|
||||
public:
|
||||
|
||||
static inline void enable(){collectionEnabled=true;};
|
||||
static inline void disable(){collectionEnabled=false;};
|
||||
static inline bool enabled(){return(collectionEnabled);};
|
||||
|
||||
RecordSceneTime(SceneStatType type):start{std::chrono::steady_clock::now()}, type{type} {}
|
||||
|
||||
~RecordSceneTime()
|
||||
{
|
||||
auto val = std::chrono::duration<uint64_t, std::nano>(std::chrono::steady_clock::now() - start).count();
|
||||
stats[writeBuffer][static_cast<size_t>(type)] += val;
|
||||
};
|
||||
|
||||
static inline void toggleBuffer()
|
||||
{
|
||||
if(enabled())
|
||||
{
|
||||
// stats[writeBuffer][static_cast<size_t>(SceneStatType::RENDER_FPS)] = LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS,3); // last 3 Frames
|
||||
writeBuffer = (writeBuffer+1)%2;
|
||||
}; // not we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display.
|
||||
|
||||
auto& statsArray = stats[writeBuffer];
|
||||
std::fill_n(statsArray.begin() ,static_cast<size_t>(SceneStatType::STATS_COUNT),0);
|
||||
}
|
||||
static inline int getReadBufferIndex(){return (writeBuffer+1)%2;};
|
||||
static inline StatsArray getCurrentStatsBuffer(){ return stats[getReadBufferIndex()];}
|
||||
static inline uint64_t get(StatsEnum type){return stats[getReadBufferIndex()][static_cast<size_t>(type)];}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class RecordObjectTime
|
||||
{
|
||||
using StatsEnum = ObjStatType;
|
||||
using StatsArray = std::array<uint64_t, static_cast<size_t>(StatsEnum::STATS_COUNT)>;
|
||||
using StatsBlock = std::unordered_map<T, StatsArray>;
|
||||
|
||||
static int writeBuffer;
|
||||
static std::array<StatsBlock,2> stats;
|
||||
|
||||
static std::array<StatsArray,2> max;
|
||||
static std::array<StatsArray,2> sum;
|
||||
static bool collectionEnabled;
|
||||
|
||||
RecordObjectTime(const RecordObjectTime&) = delete;
|
||||
RecordObjectTime() = delete;
|
||||
const T key;
|
||||
const StatsEnum type;
|
||||
std::chrono::steady_clock::time_point start;
|
||||
|
||||
public:
|
||||
static inline void enable(){collectionEnabled=true;};
|
||||
static inline void disable(){collectionEnabled=false;};
|
||||
static inline bool enabled(){return(collectionEnabled);};
|
||||
|
||||
RecordObjectTime(T key, ObjStatType type):start{std::chrono::steady_clock::now()}, key{key}, type{type} {}
|
||||
|
||||
~RecordObjectTime()
|
||||
{
|
||||
using ST = StatsEnum;
|
||||
// Note: nullptr is used as the key for global stats
|
||||
auto val = std::chrono::duration<uint64_t, std::nano>(std::chrono::steady_clock::now() - start).count();
|
||||
if(key)
|
||||
{
|
||||
stats[writeBuffer][key][static_cast<size_t>(type)] += val;
|
||||
stats[writeBuffer][key][static_cast<size_t>(ST::RENDER_COMBINED)] += val;
|
||||
if(max[writeBuffer][static_cast<size_t>(type)] < stats[writeBuffer][key][static_cast<size_t>(type)])
|
||||
{
|
||||
max[writeBuffer][static_cast<size_t>(type)] = stats[writeBuffer][key][static_cast<size_t>(type)];
|
||||
}
|
||||
if(max[writeBuffer][static_cast<size_t>(ST::RENDER_COMBINED)] < stats[writeBuffer][key][static_cast<size_t>(ST::RENDER_COMBINED)])
|
||||
{
|
||||
max[writeBuffer][static_cast<size_t>(ST::RENDER_COMBINED)] = stats[writeBuffer][key][static_cast<size_t>(ST::RENDER_COMBINED)];
|
||||
}
|
||||
sum[writeBuffer][static_cast<size_t>(type)] += val;
|
||||
sum[writeBuffer][static_cast<size_t>(ST::RENDER_COMBINED)] += val;
|
||||
}
|
||||
};
|
||||
static inline void toggleBuffer()
|
||||
{
|
||||
using ST = StatsEnum;
|
||||
if(enabled())
|
||||
{
|
||||
writeBuffer = (writeBuffer+1)%2;
|
||||
}; // note we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display.
|
||||
|
||||
auto& statsMap = stats[writeBuffer];
|
||||
for(auto& stat_entry : statsMap)
|
||||
{
|
||||
std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
|
||||
}
|
||||
statsMap.clear();
|
||||
std::fill_n(max[writeBuffer].begin(),static_cast<size_t>(ST::STATS_COUNT),0);
|
||||
std::fill_n(sum[writeBuffer].begin(),static_cast<size_t>(ST::STATS_COUNT),0);
|
||||
}
|
||||
static inline int getReadbufferIndex(){return (writeBuffer+1)%2;};
|
||||
static inline StatsBlock& getCurrentStatsBuffer(){ return stats[(writeBuffer+1)%2]; }
|
||||
static inline uint64_t getMax(StatsEnum type){return max[(writeBuffer+1)%2][static_cast<size_t>(type)];}
|
||||
static inline uint64_t getSum(StatsEnum type){return sum[(writeBuffer+1)%2][static_cast<size_t>(type)];}
|
||||
static inline uint64_t getNum(){return stats[(writeBuffer+1)%2].size();}
|
||||
static inline uint64_t get(T key, StatsEnum type){return stats[(writeBuffer+1)%2][key][static_cast<size_t>(type)];}
|
||||
};
|
||||
|
||||
static inline void toggleBuffer()
|
||||
{
|
||||
// RecordObjectTime<LLVOAvatar*>::toggleBuffer();
|
||||
RecordSceneTime::toggleBuffer();
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
int RecordObjectTime<T>::writeBuffer{0};
|
||||
|
||||
template< typename T >
|
||||
bool RecordObjectTime<T>::collectionEnabled{true};
|
||||
|
||||
template< typename T >
|
||||
std::array< typename RecordObjectTime< T >::StatsArray, 2 > RecordObjectTime<T>::max;
|
||||
|
||||
template< typename T >
|
||||
std::array< typename RecordObjectTime< T >::StatsArray, 2 > RecordObjectTime<T>::sum;
|
||||
|
||||
template< typename T >
|
||||
std::array< typename RecordObjectTime< T >::StatsBlock, 2 > RecordObjectTime< T >::stats{ {{}} };
|
||||
|
||||
}// namespace FSTelemetry
|
||||
|
||||
#endif
|
||||
|
|
@ -1631,6 +1631,9 @@ bool LLAppViewer::frame()
|
|||
|
||||
bool LLAppViewer::doFrame()
|
||||
{
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_FRAME);
|
||||
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
LLSD newFrame;
|
||||
// <FS:Beq> telemetry enabling.
|
||||
|
|
@ -1828,6 +1831,7 @@ bool LLAppViewer::doFrame()
|
|||
static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1);
|
||||
if(yield_time >= 0)
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T ( FSTelemetry::SceneStatType::RENDER_SLEEP );
|
||||
LL_RECORD_BLOCK_TIME(FTM_YIELD);
|
||||
ms_sleep(yield_time);
|
||||
}
|
||||
|
|
@ -1922,6 +1926,7 @@ bool LLAppViewer::doFrame()
|
|||
if (fsLimitFramerate && LLStartUp::getStartupState() == STATE_STARTED && !gTeleportDisplay && !logoutRequestSent() && max_fps > F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
// Sleep a while to limit frame rate.
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_FPSLIMIT);
|
||||
F32 min_frame_time = 1.f / (F32)max_fps;
|
||||
S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000);
|
||||
if (milliseconds_to_sleep > 0)
|
||||
|
|
@ -1961,6 +1966,9 @@ bool LLAppViewer::doFrame()
|
|||
}
|
||||
FSFrameMark; // <FS:Beq> Tracy support delineate Frame
|
||||
LLPROFILE_UPDATE();
|
||||
}
|
||||
FSTelemetry::RecordSceneTime::toggleBuffer();
|
||||
FSTelemetry::RecordObjectTime<LLVOAvatar*>::toggleBuffer();
|
||||
|
||||
return ! LLApp::isRunning();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -579,6 +579,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
|
|||
{
|
||||
return;
|
||||
}
|
||||
FSTelemetry::RecordObjectTime<LLVOAvatar*> T(avatarp, FSTelemetry::ObjStatType::RENDER_SHADOWS);
|
||||
|
||||
LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
|
||||
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
|
||||
if (oa == LLVOAvatar::AOA_INVISIBLE ||
|
||||
|
|
@ -1494,6 +1496,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
{
|
||||
return;
|
||||
}
|
||||
FSTelemetry::RecordObjectTime<LLVOAvatar*> T(avatarp, FSTelemetry::ObjStatType::RENDER_GEOMETRY);
|
||||
|
||||
// <FS:Zi> Add avatar hitbox debug
|
||||
static LLCachedControl<bool> render_hitbox(gSavedSettings, "DebugRenderHitboxes", false);
|
||||
|
|
|
|||
|
|
@ -334,19 +334,21 @@ void LLFloaterPerformance::populateNearbyList()
|
|||
getNearbyAvatars(valid_nearby_avs);
|
||||
|
||||
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
|
||||
auto render_max = FSTelemetry::RecordObjectTime<LLVOAvatar*>::getMax(FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
while (char_iter != valid_nearby_avs.end())
|
||||
{
|
||||
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
|
||||
if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
|
||||
{
|
||||
S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);;
|
||||
S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);
|
||||
auto render_av = FSTelemetry::RecordObjectTime<LLVOAvatar*>::get(avatar,FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
LLSD item;
|
||||
item["id"] = avatar->getID();
|
||||
LLSD& row = item["columns"];
|
||||
row[0]["column"] = "complex_visual";
|
||||
row[0]["type"] = "bar";
|
||||
LLSD& value = row[0]["value"];
|
||||
value["ratio"] = (F32)complexity_short / mNearbyMaxComplexity * 1000;
|
||||
value["ratio"] = (double)render_av / render_max;
|
||||
value["bottom"] = BAR_BOTTOM_PAD;
|
||||
value["left_pad"] = BAR_LEFT_PAD;
|
||||
value["right_pad"] = BAR_RIGHT_PAD;
|
||||
|
|
|
|||
|
|
@ -1192,6 +1192,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
void render_hud_attachments()
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_HUDS);
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
|
@ -1399,6 +1400,7 @@ bool setup_hud_matrices(const LLRect& screen_region)
|
|||
|
||||
void render_ui(F32 zoom_factor, int subfield)
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_UI);
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
|
||||
|
||||
LLGLState::checkStates();
|
||||
|
|
@ -1484,6 +1486,7 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
|
|||
|
||||
void swap()
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_SWAP);
|
||||
LL_RECORD_BLOCK_TIME(FTM_SWAP);
|
||||
|
||||
if (gDisplaySwapBuffers)
|
||||
|
|
|
|||
|
|
@ -390,6 +390,8 @@ bool LLPipeline::sRenderTextures = true;
|
|||
bool LLPipeline::sUseDepthTexture = false;
|
||||
// [/RLVa:KB]
|
||||
|
||||
static U32 sShowTrueARC; // <FS:Beq/> True when we have the TrueArc overlay active.
|
||||
|
||||
// EventHost API LLPipeline listener.
|
||||
static LLPipelineListener sPipelineListener;
|
||||
|
||||
|
|
|
|||
|
|
@ -621,6 +621,8 @@ public:
|
|||
static bool sUseDepthTexture;
|
||||
// [/RLVa:KB]
|
||||
|
||||
static U32 sShowTrueARC; // <FS:Beq/> True when we have the TrueArc overlay active.
|
||||
|
||||
static LLTrace::EventStatHandle<S64> sStatBatchSize;
|
||||
|
||||
//screen texture
|
||||
|
|
|
|||
Loading…
Reference in New Issue