Migrate perfstats away from telemetry/profiling
perfstats is now a standalone module.master
parent
af4fe2fd2d
commit
390c136430
|
|
@ -258,13 +258,18 @@ set(llcommon_HEADER_FILES
|
|||
StackWalker.h
|
||||
)
|
||||
|
||||
# <FS:ND> Add all nd* files. memory pool, intrinsics, ...
|
||||
# <FS:Beq> Tracy Profiler support
|
||||
list(APPEND llcommon_SOURCE_FILES fstelemetry.cpp)
|
||||
if (USE_TRACY_PROFILER)
|
||||
list(APPEND llcommon_SOURCE_FILES fstracyclient.cpp)
|
||||
endif()
|
||||
|
||||
# <FS:Beq> Tracy Profiler support
|
||||
list(APPEND llcommon_SOURCE_FILES fstelemetry.cpp)
|
||||
if (USE_TRACY_PROFILER)
|
||||
list(APPEND llcommon_SOURCE_FILES fstracyclient.cpp)
|
||||
endif()
|
||||
# </FS:Beq> Tracy Profiler support
|
||||
# <FS:Beq> Performance stast support
|
||||
list(APPEND llcommon_SOURCE_FILES fsperfstats.cpp)
|
||||
list(APPEND llcommon_HEADER_FILES fsperfstats.h)
|
||||
# </FS:Beq>
|
||||
|
||||
# <FS:ND> Add all nd* files. memory pool, intrinsics, ...
|
||||
SET( llcommon_ND_SOURCE_FILES
|
||||
nd/ndexceptions.cpp
|
||||
nd/ndlogthrottle.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file fsperfstats.cpp
|
||||
* @brief Stats collection to support perf floater and auto tune
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2021, The Phoenix Firestorm Project, 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
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include "fsperfstats.h"
|
||||
namespace FSPerfStats
|
||||
{
|
||||
int RecordSceneTime::writeBuffer{0};
|
||||
|
||||
bool RecordSceneTime::collectionEnabled{true};
|
||||
|
||||
std::array< typename RecordSceneTime::StatsArray, 2 > RecordSceneTime::stats{ {} };
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
#pragma once
|
||||
#ifndef FS_PERFSTATS_H_INCLUDED
|
||||
#define FS_PERFSTATS_H_INCLUDED
|
||||
/**
|
||||
* @file fsperfstats.h
|
||||
* @brief Statistics collection to support autotune and perf flaoter.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2021, The Phoenix Firestorm Project, 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
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace FSPerfStats
|
||||
{
|
||||
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,
|
||||
RENDER_IDLE,
|
||||
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
|
||||
constexpr auto period{500};
|
||||
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;
|
||||
|
||||
// auto& statsMap = stats[writeBuffer];
|
||||
// for(auto& stat_entry : statsMap)
|
||||
// {
|
||||
// auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)];
|
||||
// auto avg = stats[(writeBuffer+1)%2][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)];
|
||||
// stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val/500) - (avg/500);
|
||||
// }
|
||||
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)];}
|
||||
};
|
||||
template <typename T>
|
||||
class RecordAttachmentTime
|
||||
{
|
||||
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;
|
||||
|
||||
RecordAttachmentTime(const RecordAttachmentTime&) = delete;
|
||||
RecordAttachmentTime() = 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);};
|
||||
|
||||
RecordAttachmentTime(T key, ObjStatType type):start{std::chrono::steady_clock::now()}, key{key}, type{type} {}
|
||||
|
||||
~RecordAttachmentTime()
|
||||
{
|
||||
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();
|
||||
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{ {{}} };
|
||||
|
||||
template< typename T >
|
||||
int RecordAttachmentTime<T>::writeBuffer{0};
|
||||
|
||||
template< typename T >
|
||||
bool RecordAttachmentTime<T>::collectionEnabled{true};
|
||||
|
||||
template< typename T >
|
||||
std::array< typename RecordAttachmentTime< T >::StatsArray, 2 > RecordAttachmentTime<T>::max;
|
||||
|
||||
template< typename T >
|
||||
std::array< typename RecordAttachmentTime< T >::StatsArray, 2 > RecordAttachmentTime<T>::sum;
|
||||
|
||||
template< typename T >
|
||||
std::array< typename RecordAttachmentTime< T >::StatsBlock, 2 > RecordAttachmentTime< T >::stats{ {{}} };
|
||||
}// namespace FSPerfStats
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -29,10 +29,4 @@ namespace FSTelemetry
|
|||
{
|
||||
bool active{false};
|
||||
|
||||
int RecordSceneTime::writeBuffer{0};
|
||||
|
||||
bool RecordSceneTime::collectionEnabled{true};
|
||||
|
||||
std::array< typename RecordSceneTime::StatsArray, 2 > RecordSceneTime::stats{ {} };
|
||||
|
||||
}
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
#define FSPlot( name, value ) TracyPlot( name, value)
|
||||
#define FSFrameMark FrameMark
|
||||
#define FSThreadName( name ) tracy::SetThreadName( name )
|
||||
#define FSMessageL ( message ) tracy::Profiler::Message( message, 0 )
|
||||
#define FSTelemetryIsConnected TracyIsConnected
|
||||
|
||||
#else // (no telemetry)
|
||||
|
|
@ -60,6 +61,7 @@
|
|||
#define FSPlot( name, value )
|
||||
#define FSFrameMark
|
||||
#define FSThreadName( name )
|
||||
#define FSMessageL ( message )
|
||||
#define FSTelemetryIsConnected
|
||||
#endif // TRACY_ENABLE
|
||||
|
||||
|
|
@ -71,171 +73,6 @@ 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,
|
||||
RENDER_IDLE,
|
||||
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
|
||||
|
|
@ -286,6 +286,7 @@
|
|||
#include "fsassetblacklist.h"
|
||||
|
||||
#include "fstelemetry.h" // <FS:Beq> Tracy profiler support
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
#if LL_LINUX && LL_GTK
|
||||
#include "glib.h"
|
||||
|
|
@ -1632,7 +1633,7 @@ bool LLAppViewer::frame()
|
|||
bool LLAppViewer::doFrame()
|
||||
{
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_FRAME);
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::SceneStatType::RENDER_FRAME);
|
||||
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
LLSD newFrame;
|
||||
|
|
@ -1770,7 +1771,7 @@ bool LLAppViewer::doFrame()
|
|||
|
||||
// Update state based on messages, user input, object idle.
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_IDLE);
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::SceneStatType::RENDER_IDLE);
|
||||
|
||||
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
|
||||
|
||||
|
|
@ -1850,7 +1851,7 @@ bool LLAppViewer::doFrame()
|
|||
// of equal priority on Windows
|
||||
if (milliseconds_to_sleep > 0)
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T ( FSTelemetry::SceneStatType::RENDER_SLEEP );
|
||||
FSPerfStats::RecordSceneTime T ( FSPerfStats::SceneStatType::RENDER_SLEEP );
|
||||
ms_sleep(milliseconds_to_sleep);
|
||||
// also pause worker threads during this wait period
|
||||
LLAppViewer::getTextureCache()->pause();
|
||||
|
|
@ -1928,7 +1929,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);
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::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)
|
||||
|
|
@ -1969,8 +1970,9 @@ bool LLAppViewer::doFrame()
|
|||
FSFrameMark; // <FS:Beq> Tracy support delineate Frame
|
||||
LLPROFILE_UPDATE();
|
||||
}
|
||||
FSTelemetry::RecordSceneTime::toggleBuffer();
|
||||
FSTelemetry::RecordObjectTime<const LLVOAvatar*>::toggleBuffer();
|
||||
FSPerfStats::RecordSceneTime::toggleBuffer();
|
||||
FSPerfStats::RecordObjectTime<const LLVOAvatar*>::toggleBuffer();
|
||||
FSPerfStats::RecordAttachmentTime<U32>::toggleBuffer();
|
||||
|
||||
return ! LLApp::isRunning();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
#define LL_llavatarrendernotifier_H
|
||||
|
||||
#include "llnotificationptr.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llhudobject.h"
|
||||
|
||||
|
||||
class LLViewerRegion;
|
||||
|
||||
|
|
@ -45,6 +48,7 @@ struct LLHUDComplexity
|
|||
objectName = "";
|
||||
objectsCost = 0;
|
||||
objectsCount = 0;
|
||||
objectPtr = nullptr;
|
||||
texturesCost = 0;
|
||||
texturesCount = 0;
|
||||
largeTexturesCount = 0;
|
||||
|
|
@ -58,6 +62,7 @@ struct LLHUDComplexity
|
|||
U32 texturesCost;
|
||||
U32 texturesCount;
|
||||
U32 largeTexturesCount;
|
||||
const LLViewerObject * objectPtr;
|
||||
F64Bytes texturesMemoryTotal;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "lldrawpoolwlsky.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llglcommonfunc.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
S32 LLDrawPool::sNumDrawPools = 0;
|
||||
|
||||
|
|
@ -452,6 +453,27 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
|
|||
|
||||
void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
LLViewerObject* rootAtt{};
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLViewerObject*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLViewerObject*)par->getParent();
|
||||
}
|
||||
LL_INFOS() << "pushBatch recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << " as " << rootAtt->getAttachmentItemID().getCRC32() << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
if (!params.mCount)
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "lldrawpoolwater.h"
|
||||
#include "llspatialpartition.h"
|
||||
#include "llglcommonfunc.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
|
||||
|
||||
|
|
@ -352,6 +353,27 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
|||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LLDrawInfo& params = **k;
|
||||
// <FS:Beq> Capture render times
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* rootAtt{};
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLViewerObject*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLViewerObject*)par->getParent();
|
||||
}
|
||||
LL_INFOS() << "recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << " as " << rootAtt->getAttachmentItemID().getCRC32() << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
if (params.mParticle)
|
||||
{
|
||||
|
|
@ -679,6 +701,28 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
continue;
|
||||
}
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* rootAtt{};
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLViewerObject*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLViewerObject*)par->getParent();
|
||||
}
|
||||
LL_INFOS() << "ALPHA recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << " as " << rootAtt->getAttachmentItemID().getCRC32() << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
// Fix for bug - NORSPEC-271
|
||||
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
|
||||
// We don't want the nearly invisible objects to cause of DoF effects
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
// void drawBoxOutline(const LLVector3& pos,const LLVector3& size); // llspatialpartition.cpp
|
||||
// </FS:Zi>
|
||||
#include "llnetmap.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
|
||||
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
|
||||
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
|
||||
|
|
@ -579,7 +581,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
|
|||
{
|
||||
return;
|
||||
}
|
||||
FSTelemetry::RecordObjectTime<const LLVOAvatar*> T(avatarp, FSTelemetry::ObjStatType::RENDER_SHADOWS);
|
||||
FSPerfStats::RecordObjectTime<const LLVOAvatar*> T(avatarp, FSPerfStats::ObjStatType::RENDER_SHADOWS);
|
||||
|
||||
LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
|
||||
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
|
||||
|
|
@ -1465,6 +1467,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == -1)
|
||||
{
|
||||
FSZoneN("pass -1");
|
||||
for (S32 i = 1; i < getNumPasses(); i++)
|
||||
{ //skip foot shadows
|
||||
prerender();
|
||||
|
|
@ -1481,7 +1484,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
return;
|
||||
}
|
||||
|
||||
LLVOAvatar *avatarp = NULL;
|
||||
LLVOAvatar *avatarp { nullptr };
|
||||
|
||||
if (single_avatar)
|
||||
{
|
||||
|
|
@ -1501,12 +1504,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
{
|
||||
return;
|
||||
}
|
||||
FSTelemetry::RecordObjectTime<const LLVOAvatar*> T(avatarp, FSTelemetry::ObjStatType::RENDER_GEOMETRY);
|
||||
FSPerfStats::RecordObjectTime<const LLVOAvatar*> T(avatarp, FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
|
||||
// <FS:Zi> Add avatar hitbox debug
|
||||
static LLCachedControl<bool> render_hitbox(gSavedSettings, "DebugRenderHitboxes", false);
|
||||
if (render_hitbox && pass == 2)
|
||||
{
|
||||
FSZoneN("render_hitbox");
|
||||
LLGLSLShader* current_shader_program = NULL;
|
||||
|
||||
// load the debug output shader
|
||||
|
|
@ -1589,6 +1593,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (!single_avatar && !avatarp->isFullyLoaded() )
|
||||
{
|
||||
FSZoneN("avatar not loaded");
|
||||
if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0))
|
||||
{
|
||||
// debug code to draw a sphere in place of avatar
|
||||
|
|
@ -1636,6 +1641,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 0)
|
||||
{
|
||||
FSZoneN("pass 0");
|
||||
if (!LLPipeline::sReflectionRender)
|
||||
{
|
||||
LLVOAvatar::sNumVisibleAvatars++;
|
||||
|
|
@ -1644,6 +1650,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
// if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
|
||||
if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()))
|
||||
{
|
||||
FSZoneN("render impostor");
|
||||
if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())
|
||||
{
|
||||
// <FS:Ansariel> FIRE-9179: Crash fix
|
||||
|
|
@ -1669,6 +1676,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 1)
|
||||
{
|
||||
FSZoneN("render rigid meshes (eyeballs)");
|
||||
// render rigid meshes (eyeballs) first
|
||||
avatarp->renderRigid();
|
||||
return;
|
||||
|
|
@ -1676,12 +1684,15 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 3)
|
||||
{
|
||||
FSZoneN("pass 3");
|
||||
if (is_deferred_render)
|
||||
{
|
||||
FSZoneN("deferred rigged simple");
|
||||
renderDeferredRiggedSimple(avatarp);
|
||||
}
|
||||
else
|
||||
{
|
||||
FSZoneN("non-deferred rigged");
|
||||
renderRiggedSimple(avatarp);
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
|
|
@ -1705,12 +1716,15 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 4)
|
||||
{
|
||||
FSZoneN("pass 4");
|
||||
if (is_deferred_render)
|
||||
{
|
||||
FSZoneN("deferred rigged bump");
|
||||
renderDeferredRiggedBump(avatarp);
|
||||
}
|
||||
else
|
||||
{
|
||||
FSZoneN("non-deferred fullbright");
|
||||
renderRiggedFullbright(avatarp);
|
||||
}
|
||||
|
||||
|
|
@ -1719,6 +1733,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (is_deferred_render && pass >= 5 && pass <= 21)
|
||||
{
|
||||
FSZoneN("deferred passes 5-21");
|
||||
S32 p = pass-5;
|
||||
|
||||
if (p != 1 &&
|
||||
|
|
@ -1726,6 +1741,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
p != 9 &&
|
||||
p != 13)
|
||||
{
|
||||
FSZoneN("deferred rigged material");
|
||||
renderDeferredRiggedMaterial(avatarp, p);
|
||||
}
|
||||
return;
|
||||
|
|
@ -1736,6 +1752,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 5)
|
||||
{
|
||||
FSZoneN("rigged shiny");
|
||||
renderRiggedShinySimple(avatarp);
|
||||
|
||||
return;
|
||||
|
|
@ -1743,6 +1760,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 6)
|
||||
{
|
||||
FSZoneN("rigged FB shiny");
|
||||
renderRiggedFullbrightShiny(avatarp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1751,10 +1769,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
{
|
||||
if (pass == 7)
|
||||
{
|
||||
FSZoneN("pass 7 rigged Alpha");
|
||||
renderRiggedAlpha(avatarp);
|
||||
|
||||
if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
|
||||
{ //render transparent materials under water
|
||||
FSZoneN("rigged Alpha Blend");
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
|
|
@ -1775,6 +1795,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 8)
|
||||
{
|
||||
FSZoneN("pass 8 rigged FB Alpha");
|
||||
renderRiggedFullbrightAlpha(avatarp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1791,6 +1812,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
|
||||
{
|
||||
FSZoneN("post deferred rigged Alpha");
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
renderDeferredRiggedMaterial(avatarp, p);
|
||||
}
|
||||
|
|
@ -1798,6 +1820,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
else if (pass == 9)
|
||||
{
|
||||
FSZoneN("pass 9 - rigged glow");
|
||||
renderRiggedGlow(avatarp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1805,6 +1828,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 13)
|
||||
{
|
||||
FSZoneN("pass 13 - rigged glow");
|
||||
renderRiggedGlow(avatarp);
|
||||
|
||||
return;
|
||||
|
|
@ -1812,6 +1836,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
|
||||
{
|
||||
FSZoneN("shader level > CLOTH");
|
||||
LLMatrix4 rot_mat;
|
||||
LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat);
|
||||
LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
|
||||
|
|
@ -1837,6 +1862,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if( !single_avatar || (avatarp == single_avatar) )
|
||||
{
|
||||
FSZoneN("renderSkinned");
|
||||
avatarp->renderSkinned();
|
||||
}
|
||||
}
|
||||
|
|
@ -2254,7 +2280,24 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto self = avatar->isSelf();
|
||||
LLViewerObject * parentAttachment{nullptr};
|
||||
if(self && vobj->isAttachment())
|
||||
{
|
||||
LLViewerObject * vtop = vobj;
|
||||
LLViewerObject * par = (LLViewerObject *) vobj->getParent();
|
||||
|
||||
while (par && !(par->asAvatar()))
|
||||
{
|
||||
vtop = par;
|
||||
par = (LLViewerObject *)vtop->getParent();
|
||||
}
|
||||
parentAttachment = vtop;
|
||||
}
|
||||
FSPerfStats::RecordAttachmentTime<U32> T(parentAttachment?parentAttachment->getAttachmentItemID().getCRC32():0, FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
|
||||
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
S32 te = face->getTEOffset();
|
||||
|
||||
|
|
@ -2555,6 +2598,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
|
|||
{
|
||||
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
|
||||
{
|
||||
FSZoneN("updateRiggedVBO");
|
||||
LLFace* face = mRiggedFace[type][i];
|
||||
LLDrawable* drawable = face->getDrawable();
|
||||
if (!drawable)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "llspatialpartition.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
//#include "llimagebmp.h"
|
||||
//#include "../tools/imdebug/imdebug.h"
|
||||
|
|
@ -646,7 +647,24 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
|
|||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LLDrawInfo& params = **k;
|
||||
// <FS:Beq> Capture render times
|
||||
LLViewerObject* rootAtt{};
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLViewerObject*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLViewerObject*)par->getParent();
|
||||
}
|
||||
LL_INFOS() << "recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << " as " << rootAtt->getAttachmentItemID().getCRC32() << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
// </FS:Beq>
|
||||
applyModelMatrix(params);
|
||||
|
||||
if (params.mGroup)
|
||||
|
|
@ -1512,6 +1530,27 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
|
|||
|
||||
void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* rootAtt{};
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLViewerObject*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLViewerObject*)par->getParent();
|
||||
}
|
||||
// LL_INFOS() << "recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << " as " << rootAtt->getAttachmentItemID().getCRC32() << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
applyModelMatrix(params);
|
||||
|
||||
bool tex_setup = false;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llviewershadermgr.h"
|
||||
#include "pipeline.h"
|
||||
#include "llglcommonfunc.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
S32 diffuse_channel = -1;
|
||||
|
||||
|
|
@ -138,7 +139,29 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
|
|||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* rootAtt{};
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLViewerObject*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLViewerObject*)par->getParent();
|
||||
}
|
||||
LL_INFOS() << "MATERIALS recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << " as " << rootAtt->getAttachmentItemID().getCRC32() << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
#if LL_LINUX
|
||||
// Work-around spurious used before init warning on Vector4a
|
||||
|
|
@ -642,6 +643,20 @@ void renderFace(LLDrawable* drawable, LLFace *face)
|
|||
LLVOVolume* vobj = drawable->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
LLVOVolume* rootAtt{};
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>> T{};
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLVOVolume*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLVOVolume*)par->getParent();
|
||||
}
|
||||
// LL_INFOS() << "recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << LL_ENDL;
|
||||
if(rootAtt){T = std::unique_ptr<FSPerfStats::RecordAttachmentTime<U32>>(new FSPerfStats::RecordAttachmentTime<U32>(rootAtt->getAttachmentItemID().getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY));}
|
||||
}
|
||||
LLVolume* volume = NULL;
|
||||
|
||||
if (drawable->isState(LLDrawable::RIGGED))
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "fsavatarrenderpersistence.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
const F32 REFRESH_INTERVAL = 1.0f;
|
||||
const S32 BAR_LEFT_PAD = 2;
|
||||
|
|
@ -176,13 +177,13 @@ void LLFloaterPerformance::draw()
|
|||
getChild<LLTextBox>("fps_value")->setValue((S32)llround(fps));
|
||||
auto tot_frame_time_ns = 1000000000/fps;
|
||||
auto target_frame_time_ns = 1000000000/(target_fps==0?1:target_fps);
|
||||
auto tot_avatar_time = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::getSum(FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
auto tot_huds_time = FSTelemetry::RecordSceneTime::get(FSTelemetry::SceneStatType::RENDER_HUDS) ;
|
||||
auto tot_sleep_time = FSTelemetry::RecordSceneTime::get(FSTelemetry::SceneStatType::RENDER_SLEEP);
|
||||
auto tot_ui_time = FSTelemetry::RecordSceneTime::get(FSTelemetry::SceneStatType::RENDER_UI);
|
||||
auto tot_idle_time = FSTelemetry::RecordSceneTime::get(FSTelemetry::SceneStatType::RENDER_IDLE);
|
||||
auto tot_limit_time = FSTelemetry::RecordSceneTime::get(FSTelemetry::SceneStatType::RENDER_FPSLIMIT);
|
||||
auto tot_swap_time = FSTelemetry::RecordSceneTime::get(FSTelemetry::SceneStatType::RENDER_SWAP);
|
||||
auto tot_avatar_time = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::getSum(FSPerfStats::ObjStatType::RENDER_COMBINED);
|
||||
auto tot_huds_time = FSPerfStats::RecordSceneTime::get(FSPerfStats::SceneStatType::RENDER_HUDS) ;
|
||||
auto tot_sleep_time = FSPerfStats::RecordSceneTime::get(FSPerfStats::SceneStatType::RENDER_SLEEP);
|
||||
auto tot_ui_time = FSPerfStats::RecordSceneTime::get(FSPerfStats::SceneStatType::RENDER_UI);
|
||||
auto tot_idle_time = FSPerfStats::RecordSceneTime::get(FSPerfStats::SceneStatType::RENDER_IDLE);
|
||||
auto tot_limit_time = FSPerfStats::RecordSceneTime::get(FSPerfStats::SceneStatType::RENDER_FPSLIMIT);
|
||||
auto tot_swap_time = FSPerfStats::RecordSceneTime::get(FSPerfStats::SceneStatType::RENDER_SWAP);
|
||||
|
||||
// once the rest is extracted what is left is the scene cost (we don't include non-render activities such as network here prlloy should.)
|
||||
auto tot_scene_time = tot_frame_time_ns - tot_avatar_time - tot_huds_time - tot_ui_time - tot_sleep_time - tot_limit_time - tot_swap_time;
|
||||
|
|
@ -241,7 +242,7 @@ void LLFloaterPerformance::draw()
|
|||
|
||||
if( auto_tune )
|
||||
{
|
||||
auto av_render_max = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::getMax(FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
auto av_render_max = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::getMax(FSPerfStats::ObjStatType::RENDER_COMBINED);
|
||||
|
||||
// if( target_frame_time_ns <= tot_frame_time_ns )
|
||||
// {
|
||||
|
|
@ -344,10 +345,12 @@ void LLFloaterPerformance::populateHUDList()
|
|||
max_complexity = llmax(max_complexity, (*iter).objectsCost);
|
||||
}
|
||||
|
||||
auto huds_max_render_time = FSPerfStats::RecordObjectTime<LLHUDObject*>::getMax(FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
for (iter = complexity_list.begin(); iter != end; ++iter)
|
||||
{
|
||||
LLHUDComplexity hud_object_complexity = *iter;
|
||||
S32 obj_cost_short = llmax((S32)hud_object_complexity.objectsCost / 1000, 1);
|
||||
LLHUDComplexity hud_object_complexity = *iter;
|
||||
auto hud_ptr = hud_object_complexity.objectPtr;
|
||||
auto hud_render_time = FSPerfStats::RecordObjectTime<const LLViewerObject*>::get(hud_ptr, FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
LLSD item;
|
||||
item["special_id"] = hud_object_complexity.objectId;
|
||||
item["target"] = LLNameListCtrl::SPECIAL;
|
||||
|
|
@ -404,10 +407,13 @@ void LLFloaterPerformance::populateObjectList()
|
|||
max_complexity = llmax(max_complexity, (*iter).objectCost);
|
||||
}
|
||||
|
||||
auto max_render_time = FSPerfStats::RecordAttachmentTime<U32>::getMax(FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
|
||||
for (iter = complexity_list.begin(); iter != end; ++iter)
|
||||
{
|
||||
LLObjectComplexity object_complexity = *iter;
|
||||
S32 obj_cost_short = llmax((S32)object_complexity.objectCost / 1000, 1);
|
||||
// S32 obj_cost_short = llmax((S32)object_complexity.objectCost / 1000, 1);
|
||||
auto attach_render_time = FSPerfStats::RecordAttachmentTime<U32>::get(object_complexity.objectId.getCRC32(), FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
LLSD item;
|
||||
item["special_id"] = object_complexity.objectId;
|
||||
item["target"] = LLNameListCtrl::SPECIAL;
|
||||
|
|
@ -415,14 +421,15 @@ void LLFloaterPerformance::populateObjectList()
|
|||
row[0]["column"] = "complex_visual";
|
||||
row[0]["type"] = "bar";
|
||||
LLSD& value = row[0]["value"];
|
||||
value["ratio"] = (F32)obj_cost_short / max_complexity * 1000;
|
||||
value["ratio"] = (F32)attach_render_time / max_render_time;
|
||||
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]["value"] = std::to_string(obj_cost_short);
|
||||
row[1]["value"] = llformat("%.3f",((double)attach_render_time / 1000000));
|
||||
row[1]["font"]["name"] = "SANSSERIF";
|
||||
|
||||
row[2]["column"] = "name";
|
||||
|
|
@ -460,7 +467,7 @@ void LLFloaterPerformance::populateNearbyList()
|
|||
getNearbyAvatars(valid_nearby_avs);
|
||||
|
||||
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
|
||||
auto render_max = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::getMax(FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
auto render_max = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::getMax(FSPerfStats::ObjStatType::RENDER_COMBINED);
|
||||
while (char_iter != valid_nearby_avs.end())
|
||||
{
|
||||
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
|
||||
|
|
@ -471,7 +478,7 @@ void LLFloaterPerformance::populateNearbyList()
|
|||
continue;
|
||||
|
||||
// S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);
|
||||
auto render_av = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(avatar,FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
auto render_av = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::get(avatar,FSPerfStats::ObjStatType::RENDER_COMBINED);
|
||||
auto is_slow = avatar->isTooSlow(true);
|
||||
// auto is_slow_without_shadows = avatar->isTooSlow();
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
// [/RLVa:KB]
|
||||
#include "llpresetsmanager.h"
|
||||
#include "fsdata.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
extern LLPointer<LLViewerTexture> gStartTexture;
|
||||
extern bool gShiftFrame;
|
||||
|
|
@ -1192,7 +1193,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
void render_hud_attachments()
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_HUDS);
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::SceneStatType::RENDER_HUDS);
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
|
@ -1400,7 +1401,7 @@ bool setup_hud_matrices(const LLRect& screen_region)
|
|||
|
||||
void render_ui(F32 zoom_factor, int subfield)
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_UI);
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::SceneStatType::RENDER_UI);
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
|
||||
|
||||
LLGLState::checkStates();
|
||||
|
|
@ -1486,7 +1487,7 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
|
|||
|
||||
void swap()
|
||||
{
|
||||
FSTelemetry::RecordSceneTime T (FSTelemetry::SceneStatType::RENDER_SWAP);
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::SceneStatType::RENDER_SWAP);
|
||||
LL_RECORD_BLOCK_TIME(FTM_SWAP);
|
||||
|
||||
if (gDisplaySwapBuffers)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "m3math.h"
|
||||
#include "m4math.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
#if !LL_DARWIN && !LL_LINUX
|
||||
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
|
||||
|
|
@ -222,6 +223,7 @@ int compare_int(const void *a, const void *b)
|
|||
//--------------------------------------------------------------------
|
||||
U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
{
|
||||
FSZone;
|
||||
if (!mValid || !mMesh || !mFace || !mVisible ||
|
||||
!mFace->getVertexBuffer() ||
|
||||
mMesh->getNumFaces() == 0 ||
|
||||
|
|
@ -230,6 +232,22 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
auto vobj = mFace->getViewerObject();
|
||||
if(vobj && !vobj->asAvatar() && vobj->getAvatar()->isSelf())
|
||||
{
|
||||
LLViewerObject * vtop = vobj;
|
||||
LLViewerObject * par = (LLViewerObject *) vobj->getParent();
|
||||
|
||||
while (par && !(par->asAvatar()))
|
||||
{
|
||||
vtop = par;
|
||||
par = (LLViewerObject *)vtop->getParent();
|
||||
}
|
||||
vobj = vtop;
|
||||
}
|
||||
FSPerfStats::RecordAttachmentTime<U32> T(vobj?vobj->getAttachmentItemID().getCRC32():0, FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
|
||||
U32 triangle_count = 0;
|
||||
|
||||
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@
|
|||
#include "fslslbridge.h" // <FS:PP> Movelock position refresh
|
||||
|
||||
#include "fsdiscordconnect.h" // <FS:LO> tapping a place that happens on landing in world to start up discord
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
extern F32 SPEED_ADJUST_MAX;
|
||||
extern F32 SPEED_ADJUST_MAX_SEC;
|
||||
|
|
@ -6928,6 +6929,7 @@ const LLUUID& LLVOAvatar::getID() const
|
|||
LLJoint *LLVOAvatar::getJoint( const JointKey &name )
|
||||
// </FS:ND>
|
||||
{
|
||||
FSZone;
|
||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
||||
//joint_map_t::iterator iter = mJointMap.find( name );
|
||||
|
||||
|
|
@ -9161,8 +9163,8 @@ bool LLVOAvatar::isTooSlow(bool combined) const
|
|||
if(!mARTCapped)
|
||||
{
|
||||
// no cap, so we use the live values
|
||||
render_time = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
render_geom_time = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_GEOMETRY);
|
||||
render_time = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::get(this,FSPerfStats::ObjStatType::RENDER_COMBINED);
|
||||
render_geom_time = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::get(this,FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -9175,8 +9177,8 @@ bool LLVOAvatar::isTooSlow(bool combined) const
|
|||
if(!mARTCapped)
|
||||
{
|
||||
// if we weren't capped, we are now
|
||||
abuse_constness->mRenderTime = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_COMBINED);
|
||||
abuse_constness->mGeomTime = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_GEOMETRY);
|
||||
abuse_constness->mRenderTime = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::get(this,FSPerfStats::ObjStatType::RENDER_COMBINED);
|
||||
abuse_constness->mGeomTime = FSPerfStats::RecordObjectTime<const LLVOAvatar*>::get(this,FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
abuse_constness->mARTStale = false;
|
||||
abuse_constness->mARTCapped = true;
|
||||
abuse_constness->mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
|
||||
|
|
@ -10500,8 +10502,6 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte
|
|||
|
||||
updateMeshTextures();
|
||||
updateMeshVisibility();
|
||||
markARTStale();
|
||||
|
||||
}
|
||||
|
||||
LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te)
|
||||
|
|
@ -11682,6 +11682,7 @@ void LLVOAvatar::updateVisualComplexity()
|
|||
LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL;
|
||||
// Set the cache time to in the past so it's updated ASAP
|
||||
mVisualComplexityStale = true;
|
||||
markARTStale();
|
||||
}
|
||||
|
||||
// Account for the complexity of a single top-level object associated
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
#include "rlvlocks.h"
|
||||
// [/RLVa:KB]
|
||||
#include "llviewernetwork.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
|
||||
const F32 FORCE_CULL_AREA = 8.f;
|
||||
|
|
@ -6360,7 +6361,7 @@ static LLTrace::BlockTimerStatHandle FTM_REBUILD_MESH_FLUSH("Flush Mesh");
|
|||
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
{
|
||||
llassert(group);
|
||||
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// <FS:Beq> move out one scope (but are these even useful as dupes?)
|
||||
// LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// <FS:Beq> High volume remove (roughly 1000:1 ratio to inside the if statement)
|
||||
if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
|
||||
{
|
||||
// LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// <FS:Beq> move out one scope (but are these even useful as dupes?)
|
||||
|
|
@ -6382,6 +6383,19 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
|||
if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
|
||||
{
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
LLVOVolume* rootAtt{};
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
auto par = (LLVOVolume*)vobj->getParent();
|
||||
rootAtt = vobj;
|
||||
while( par->isAttachment() )
|
||||
{
|
||||
rootAtt = par;
|
||||
par = (LLVOVolume*)par->getParent();
|
||||
}
|
||||
LL_INFOS() << "recording time for ATT@" << rootAtt << " " << (rootAtt?rootAtt->getAttachmentItemName():"null") << LL_ENDL;
|
||||
}
|
||||
FSPerfStats::RecordAttachmentTime<U32> T(rootAtt?rootAtt->getAttachmentItemID().getCRC32():0, FSPerfStats::ObjStatType::RENDER_GEOMETRY);
|
||||
//<FS:Beq> avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
|
|
|
|||
Loading…
Reference in New Issue