SH-3406 WIP convert fast timers to lltrace system
simplified llfasttimer code down to 2 classes llunit unit conversion now done in floating point or 64 bit integer precision, depending on source typemaster
parent
0bb0bd514b
commit
a3e3e8b4cc
|
|
@ -32,6 +32,7 @@
|
|||
#include "llsingleton.h"
|
||||
#include "lltreeiterators.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llunit.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
|
@ -73,13 +74,13 @@ U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution
|
|||
// FIXME: move these declarations to the relevant modules
|
||||
|
||||
// helper functions
|
||||
typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
|
||||
typedef LLTreeDFSPostIter<LLFastTimer::DeclareTimer, LLFastTimer::DeclareTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
|
||||
|
||||
static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id)
|
||||
static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::DeclareTimer& id)
|
||||
{
|
||||
return timer_tree_bottom_up_iterator_t(&id,
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::beginChildren), _1),
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::endChildren), _1));
|
||||
}
|
||||
|
||||
static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
|
||||
|
|
@ -87,14 +88,14 @@ static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
|
|||
return timer_tree_bottom_up_iterator_t();
|
||||
}
|
||||
|
||||
typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t;
|
||||
typedef LLTreeDFSIter<LLFastTimer::DeclareTimer, LLFastTimer::DeclareTimer::child_const_iter> timer_tree_dfs_iterator_t;
|
||||
|
||||
|
||||
static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
|
||||
static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::DeclareTimer& id)
|
||||
{
|
||||
return timer_tree_dfs_iterator_t(&id,
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::beginChildren), _1),
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::endChildren), _1));
|
||||
}
|
||||
|
||||
static timer_tree_dfs_iterator_t end_timer_tree()
|
||||
|
|
@ -102,75 +103,12 @@ static timer_tree_dfs_iterator_t end_timer_tree()
|
|||
return timer_tree_dfs_iterator_t();
|
||||
}
|
||||
|
||||
// factory class that creates NamedTimers via static DeclareTimer objects
|
||||
class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
|
||||
LLFastTimer::DeclareTimer& LLFastTimer::DeclareTimer::getRootTimer()
|
||||
{
|
||||
public:
|
||||
NamedTimerFactory()
|
||||
: mTimerRoot(NULL)
|
||||
{}
|
||||
|
||||
/*virtual */ void initSingleton()
|
||||
{
|
||||
mTimerRoot = new LLFastTimer::NamedTimer("root");
|
||||
mRootFrameState.setNamedTimer(mTimerRoot);
|
||||
mTimerRoot->setFrameState(&mRootFrameState);
|
||||
mTimerRoot->mParent = mTimerRoot;
|
||||
mTimerRoot->setCollapsed(false);
|
||||
mRootFrameState.mParent = &mRootFrameState;
|
||||
}
|
||||
|
||||
~NamedTimerFactory()
|
||||
{
|
||||
std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
|
||||
|
||||
delete mTimerRoot;
|
||||
}
|
||||
|
||||
LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state)
|
||||
{
|
||||
LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name);
|
||||
timer->setFrameState(state);
|
||||
timer->setParent(mTimerRoot);
|
||||
mTimers.insert(std::make_pair(name, timer));
|
||||
|
||||
return *timer;
|
||||
}
|
||||
|
||||
LLFastTimer::NamedTimer* getTimerByName(const std::string& name)
|
||||
{
|
||||
timer_map_t::iterator found_it = mTimers.find(name);
|
||||
if (found_it != mTimers.end())
|
||||
{
|
||||
return found_it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; }
|
||||
|
||||
typedef std::multimap<std::string, LLFastTimer::NamedTimer*> timer_map_t;
|
||||
timer_map_t::iterator beginTimers() { return mTimers.begin(); }
|
||||
timer_map_t::iterator endTimers() { return mTimers.end(); }
|
||||
S32 timerCount() { return mTimers.size(); }
|
||||
|
||||
private:
|
||||
timer_map_t mTimers;
|
||||
|
||||
LLFastTimer::NamedTimer* mTimerRoot;
|
||||
LLFastTimer::FrameState mRootFrameState;
|
||||
};
|
||||
|
||||
LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open )
|
||||
: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))
|
||||
{
|
||||
mTimer.setCollapsed(!open);
|
||||
static DeclareTimer root_timer("root", true, NULL);
|
||||
return root_timer;
|
||||
}
|
||||
|
||||
LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
|
||||
: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
|
||||
|
|
@ -183,7 +121,7 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
|
|||
{
|
||||
#if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS
|
||||
//getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz
|
||||
static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0);
|
||||
static LLUnit<LLUnits::Hertz, U64> sCPUClockFrequency = LLProcessorInfo().getCPUFrequency();
|
||||
|
||||
// we drop the low-order byte in our timers, so report a lower frequency
|
||||
#else
|
||||
|
|
@ -206,49 +144,44 @@ LLFastTimer::FrameState::FrameState()
|
|||
: mActiveCount(0),
|
||||
mCalls(0),
|
||||
mSelfTimeCounter(0),
|
||||
mParent(NULL),
|
||||
mLastCaller(NULL),
|
||||
mMoveUpTree(false)
|
||||
{}
|
||||
|
||||
|
||||
LLFastTimer::NamedTimer::NamedTimer(const std::string& name)
|
||||
LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open, DeclareTimer* parent)
|
||||
: mName(name),
|
||||
mCollapsed(true),
|
||||
mParent(NULL),
|
||||
mTreeTimeCounter(0),
|
||||
mCountAverage(0),
|
||||
mCallAverage(0),
|
||||
mNeedsSorting(false),
|
||||
mFrameState(NULL)
|
||||
mNeedsSorting(false)
|
||||
{
|
||||
setCollapsed(!open);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
setParent(parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
mParent = this;
|
||||
}
|
||||
|
||||
mCountHistory = new U32[HISTORY_NUM];
|
||||
memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
|
||||
mCallHistory = new U32[HISTORY_NUM];
|
||||
memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
|
||||
}
|
||||
|
||||
LLFastTimer::NamedTimer::~NamedTimer()
|
||||
LLFastTimer::DeclareTimer::~DeclareTimer()
|
||||
{
|
||||
delete[] mCountHistory;
|
||||
delete[] mCallHistory;
|
||||
}
|
||||
|
||||
std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
|
||||
{
|
||||
F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
|
||||
if (history_idx < 0)
|
||||
{
|
||||
// by default, show average number of call
|
||||
return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
|
||||
}
|
||||
else
|
||||
{
|
||||
return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
|
||||
void LLFastTimer::DeclareTimer::setParent(DeclareTimer* parent)
|
||||
{
|
||||
llassert_always(parent != this);
|
||||
llassert_always(parent != NULL);
|
||||
|
|
@ -264,8 +197,8 @@ void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
|
|||
// subtract average timing from previous parent
|
||||
mParent->mCountAverage -= mCountAverage;
|
||||
|
||||
std::vector<NamedTimer*>& children = mParent->getChildren();
|
||||
std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
|
||||
std::vector<DeclareTimer*>& children = mParent->getChildren();
|
||||
std::vector<DeclareTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
|
||||
if (found_it != children.end())
|
||||
{
|
||||
children.erase(found_it);
|
||||
|
|
@ -275,16 +208,15 @@ void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
|
|||
mParent = parent;
|
||||
if (parent)
|
||||
{
|
||||
getFrameState().mParent = &parent->getFrameState();
|
||||
parent->getChildren().push_back(this);
|
||||
parent->mNeedsSorting = true;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLFastTimer::NamedTimer::getDepth()
|
||||
S32 LLFastTimer::DeclareTimer::getDepth()
|
||||
{
|
||||
S32 depth = 0;
|
||||
NamedTimer* timerp = mParent;
|
||||
DeclareTimer* timerp = mParent;
|
||||
while(timerp)
|
||||
{
|
||||
depth++;
|
||||
|
|
@ -295,7 +227,7 @@ S32 LLFastTimer::NamedTimer::getDepth()
|
|||
}
|
||||
|
||||
// static
|
||||
void LLFastTimer::NamedTimer::processTimes()
|
||||
void LLFastTimer::DeclareTimer::processTimes()
|
||||
{
|
||||
if (sCurFrameIndex < 0) return;
|
||||
|
||||
|
|
@ -306,14 +238,14 @@ void LLFastTimer::NamedTimer::processTimes()
|
|||
// sort child timers by name
|
||||
struct SortTimerByName
|
||||
{
|
||||
bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2)
|
||||
bool operator()(const LLFastTimer::DeclareTimer* i1, const LLFastTimer::DeclareTimer* i2)
|
||||
{
|
||||
return i1->getName() < i2->getName();
|
||||
}
|
||||
};
|
||||
|
||||
//static
|
||||
void LLFastTimer::NamedTimer::buildHierarchy()
|
||||
void LLFastTimer::DeclareTimer::buildHierarchy()
|
||||
{
|
||||
if (sCurFrameIndex < 0 ) return;
|
||||
|
||||
|
|
@ -321,16 +253,16 @@ void LLFastTimer::NamedTimer::buildHierarchy()
|
|||
{
|
||||
for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
|
||||
DeclareTimer& timer = *it;
|
||||
if (&timer == &DeclareTimer::getRootTimer()) continue;
|
||||
|
||||
// bootstrap tree construction by attaching to last timer to be on stack
|
||||
// when this timer was called
|
||||
if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
|
||||
if (timer.mLastCaller && timer.mParent == &DeclareTimer::getRootTimer())
|
||||
{
|
||||
timer.setParent(timer.getFrameState().mLastCaller->mTimer);
|
||||
timer.setParent(timer.mLastCaller);
|
||||
// no need to push up tree on first use, flag can be set spuriously
|
||||
timer.getFrameState().mMoveUpTree = false;
|
||||
timer.mMoveUpTree = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -338,22 +270,22 @@ void LLFastTimer::NamedTimer::buildHierarchy()
|
|||
// bump timers up tree if they've been flagged as being in the wrong place
|
||||
// do this in a bottom up order to promote descendants first before promoting ancestors
|
||||
// this preserves partial order derived from current frame's observations
|
||||
for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
|
||||
for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(DeclareTimer::getRootTimer());
|
||||
it != end_timer_tree_bottom_up();
|
||||
++it)
|
||||
{
|
||||
NamedTimer* timerp = *it;
|
||||
DeclareTimer* timerp = *it;
|
||||
// skip root timer
|
||||
if (timerp == NamedTimerFactory::instance().getRootTimer()) continue;
|
||||
if (timerp == &DeclareTimer::getRootTimer()) continue;
|
||||
|
||||
if (timerp->getFrameState().mMoveUpTree)
|
||||
if (timerp->mMoveUpTree)
|
||||
{
|
||||
// since ancestors have already been visited, reparenting won't affect tree traversal
|
||||
//step up tree, bringing our descendants with us
|
||||
LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() <<
|
||||
" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL;
|
||||
timerp->setParent(timerp->getParent()->getParent());
|
||||
timerp->getFrameState().mMoveUpTree = false;
|
||||
timerp->mMoveUpTree = false;
|
||||
|
||||
// don't bubble up any ancestors until descendants are done bubbling up
|
||||
it.skipAncestors();
|
||||
|
|
@ -361,11 +293,11 @@ void LLFastTimer::NamedTimer::buildHierarchy()
|
|||
}
|
||||
|
||||
// sort timers by time last called, so call graph makes sense
|
||||
for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
|
||||
for(timer_tree_dfs_iterator_t it = begin_timer_tree(DeclareTimer::getRootTimer());
|
||||
it != end_timer_tree();
|
||||
++it)
|
||||
{
|
||||
NamedTimer* timerp = (*it);
|
||||
DeclareTimer* timerp = (*it);
|
||||
if (timerp->mNeedsSorting)
|
||||
{
|
||||
std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName());
|
||||
|
|
@ -375,7 +307,7 @@ void LLFastTimer::NamedTimer::buildHierarchy()
|
|||
}
|
||||
|
||||
//static
|
||||
void LLFastTimer::NamedTimer::accumulateTimings()
|
||||
void LLFastTimer::DeclareTimer::accumulateTimings()
|
||||
{
|
||||
U32 cur_time = getCPUClockCount32();
|
||||
|
||||
|
|
@ -388,8 +320,8 @@ void LLFastTimer::NamedTimer::accumulateTimings()
|
|||
U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;
|
||||
U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime;
|
||||
cur_data->mChildTime = 0;
|
||||
cur_data->mFrameState->mSelfTimeCounter += self_time_delta;
|
||||
cur_data->mFrameState->mTotalTimeCounter += cumulative_time_delta;
|
||||
cur_data->mTimerData->mSelfTimeCounter += self_time_delta;
|
||||
cur_data->mTimerData->mTotalTimeCounter += cumulative_time_delta;
|
||||
|
||||
cur_timer->mStartTime = cur_time;
|
||||
|
||||
|
|
@ -400,12 +332,12 @@ void LLFastTimer::NamedTimer::accumulateTimings()
|
|||
}
|
||||
|
||||
// traverse tree in DFS post order, or bottom up
|
||||
for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
|
||||
for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(DeclareTimer::getRootTimer());
|
||||
it != end_timer_tree_bottom_up();
|
||||
++it)
|
||||
{
|
||||
NamedTimer* timerp = (*it);
|
||||
timerp->mTreeTimeCounter = timerp->getFrameState().mSelfTimeCounter;
|
||||
DeclareTimer* timerp = (*it);
|
||||
timerp->mTreeTimeCounter = timerp->mSelfTimeCounter;
|
||||
for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it)
|
||||
{
|
||||
timerp->mTreeTimeCounter += (*child_it)->mTreeTimeCounter;
|
||||
|
|
@ -418,15 +350,15 @@ void LLFastTimer::NamedTimer::accumulateTimings()
|
|||
int hidx = cur_frame % HISTORY_NUM;
|
||||
|
||||
timerp->mCountHistory[hidx] = timerp->mTreeTimeCounter;
|
||||
timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTreeTimeCounter) / (cur_frame+1);
|
||||
timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls;
|
||||
timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
|
||||
timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTreeTimeCounter) / (cur_frame+1);
|
||||
timerp->mCallHistory[hidx] = timerp->mCalls;
|
||||
timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->mCalls) / (cur_frame+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFastTimer::NamedTimer::resetFrame()
|
||||
void LLFastTimer::DeclareTimer::resetFrame()
|
||||
{
|
||||
if (sLog)
|
||||
{ //output current frame counts to performance log
|
||||
|
|
@ -435,11 +367,11 @@ void LLFastTimer::NamedTimer::resetFrame()
|
|||
if (call_count % 100 == 0)
|
||||
{
|
||||
LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL;
|
||||
LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl;
|
||||
LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << LL_ENDL;
|
||||
LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL;
|
||||
LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL;
|
||||
LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL;
|
||||
LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL;
|
||||
LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit<LLUnits::Hertz, F64>(LLProcessorInfo().getCPUFrequency())) << LL_ENDL;
|
||||
}
|
||||
call_count++;
|
||||
|
||||
|
|
@ -451,14 +383,13 @@ void LLFastTimer::NamedTimer::resetFrame()
|
|||
{
|
||||
for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
FrameState& info = timer.getFrameState();
|
||||
sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
|
||||
sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
|
||||
DeclareTimer& timer = *it;
|
||||
sd[timer.getName()]["Time"] = (LLSD::Real) (timer.mSelfTimeCounter*iclock_freq);
|
||||
sd[timer.getName()]["Calls"] = (LLSD::Integer) timer.mCalls;
|
||||
|
||||
// computing total time here because getting the root timer's getCountHistory
|
||||
// doesn't work correctly on the first frame
|
||||
total_time = total_time + info.mSelfTimeCounter * iclock_freq;
|
||||
total_time = total_time + timer.mSelfTimeCounter * iclock_freq;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -474,23 +405,16 @@ void LLFastTimer::NamedTimer::resetFrame()
|
|||
// reset for next frame
|
||||
for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
|
||||
FrameState& info = timer.getFrameState();
|
||||
info.mSelfTimeCounter = 0;
|
||||
info.mCalls = 0;
|
||||
info.mLastCaller = NULL;
|
||||
info.mMoveUpTree = false;
|
||||
// update parent pointer in timer state struct
|
||||
if (timer.mParent)
|
||||
{
|
||||
info.mParent = &timer.mParent->getFrameState();
|
||||
}
|
||||
DeclareTimer& timer = *it;
|
||||
timer.mSelfTimeCounter = 0;
|
||||
timer.mCalls = 0;
|
||||
timer.mLastCaller = NULL;
|
||||
timer.mMoveUpTree = false;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFastTimer::NamedTimer::reset()
|
||||
void LLFastTimer::DeclareTimer::reset()
|
||||
{
|
||||
resetFrame(); // reset frame data
|
||||
|
||||
|
|
@ -514,10 +438,10 @@ void LLFastTimer::NamedTimer::reset()
|
|||
{
|
||||
for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
if (&timer != NamedTimerFactory::instance().getRootTimer())
|
||||
DeclareTimer& timer = *it;
|
||||
if (&timer != &DeclareTimer::getRootTimer())
|
||||
{
|
||||
timer.setParent(NamedTimerFactory::instance().getRootTimer());
|
||||
timer.setParent(&DeclareTimer::getRootTimer());
|
||||
}
|
||||
|
||||
timer.mCountAverage = 0;
|
||||
|
|
@ -531,34 +455,29 @@ void LLFastTimer::NamedTimer::reset()
|
|||
sCurFrameIndex = 0;
|
||||
}
|
||||
|
||||
U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const
|
||||
U32 LLFastTimer::DeclareTimer::getHistoricalCount(S32 history_index) const
|
||||
{
|
||||
S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
|
||||
S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::DeclareTimer::HISTORY_NUM;
|
||||
return mCountHistory[history_idx];
|
||||
}
|
||||
|
||||
U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const
|
||||
U32 LLFastTimer::DeclareTimer::getHistoricalCalls(S32 history_index ) const
|
||||
{
|
||||
S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
|
||||
S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::DeclareTimer::HISTORY_NUM;
|
||||
return mCallHistory[history_idx];
|
||||
}
|
||||
|
||||
LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const
|
||||
{
|
||||
return *mFrameState;
|
||||
}
|
||||
|
||||
std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren()
|
||||
std::vector<LLFastTimer::DeclareTimer*>::const_iterator LLFastTimer::DeclareTimer::beginChildren()
|
||||
{
|
||||
return mChildren.begin();
|
||||
}
|
||||
|
||||
std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren()
|
||||
std::vector<LLFastTimer::DeclareTimer*>::const_iterator LLFastTimer::DeclareTimer::endChildren()
|
||||
{
|
||||
return mChildren.end();
|
||||
}
|
||||
|
||||
std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
|
||||
std::vector<LLFastTimer::DeclareTimer*>& LLFastTimer::DeclareTimer::getChildren()
|
||||
{
|
||||
return mChildren;
|
||||
}
|
||||
|
|
@ -575,12 +494,12 @@ void LLFastTimer::nextFrame()
|
|||
|
||||
if (!sPauseHistory)
|
||||
{
|
||||
NamedTimer::processTimes();
|
||||
DeclareTimer::processTimes();
|
||||
sLastFrameIndex = sCurFrameIndex++;
|
||||
}
|
||||
|
||||
// get ready for next frame
|
||||
NamedTimer::resetFrame();
|
||||
DeclareTimer::resetFrame();
|
||||
sLastFrameTime = frame_time;
|
||||
}
|
||||
|
||||
|
|
@ -588,17 +507,17 @@ void LLFastTimer::nextFrame()
|
|||
void LLFastTimer::dumpCurTimes()
|
||||
{
|
||||
// accumulate timings, etc.
|
||||
NamedTimer::processTimes();
|
||||
DeclareTimer::processTimes();
|
||||
|
||||
F64 clock_freq = (F64)countsPerSecond();
|
||||
F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds
|
||||
|
||||
// walk over timers in depth order and output timings
|
||||
for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
|
||||
for(timer_tree_dfs_iterator_t it = begin_timer_tree(DeclareTimer::getRootTimer());
|
||||
it != end_timer_tree();
|
||||
++it)
|
||||
{
|
||||
NamedTimer* timerp = (*it);
|
||||
DeclareTimer* timerp = (*it);
|
||||
F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq);
|
||||
// Don't bother with really brief times, keep output concise
|
||||
if (total_time_ms < 0.1) continue;
|
||||
|
|
@ -621,7 +540,7 @@ void LLFastTimer::dumpCurTimes()
|
|||
//static
|
||||
void LLFastTimer::reset()
|
||||
{
|
||||
NamedTimer::reset();
|
||||
DeclareTimer::reset();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -637,22 +556,3 @@ void LLFastTimer::writeLog(std::ostream& os)
|
|||
}
|
||||
}
|
||||
|
||||
//static
|
||||
const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name)
|
||||
{
|
||||
return NamedTimerFactory::instance().getTimerByName(name);
|
||||
}
|
||||
|
||||
//LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)
|
||||
//: mFrameState(state)
|
||||
//{
|
||||
// U32 start_time = getCPUClockCount32();
|
||||
// mStartTime = start_time;
|
||||
// mFrameState->mActiveCount++;
|
||||
// LLFastTimer::sCurTimerData.mCurTimer = this;
|
||||
// LLFastTimer::sCurTimerData.mFrameState = mFrameState;
|
||||
// LLFastTimer::sCurTimerData.mChildTime = 0;
|
||||
// mLastTimerData = LLFastTimer::sCurTimerData;
|
||||
//}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "llinstancetracker.h"
|
||||
|
||||
#define FAST_TIMER_ON 1
|
||||
#define DEBUG_FAST_TIMER_THREADS 1
|
||||
|
||||
class LLMutex;
|
||||
|
||||
|
|
@ -45,64 +44,53 @@ LL_COMMON_API void assert_main_thread();
|
|||
class LL_COMMON_API LLFastTimer
|
||||
{
|
||||
public:
|
||||
class NamedTimer;
|
||||
|
||||
class DeclareTimer;
|
||||
struct LL_COMMON_API FrameState
|
||||
{
|
||||
FrameState();
|
||||
void setNamedTimer(class NamedTimer* timerp) { mTimer = timerp; }
|
||||
|
||||
U32 mSelfTimeCounter;
|
||||
U32 mTotalTimeCounter;
|
||||
U32 mCalls;
|
||||
FrameState* mParent; // info for caller timer
|
||||
FrameState* mLastCaller; // used to bootstrap tree construction
|
||||
class NamedTimer* mTimer;
|
||||
DeclareTimer* mLastCaller; // used to bootstrap tree construction
|
||||
U16 mActiveCount; // number of timers with this ID active on stack
|
||||
bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
|
||||
};
|
||||
|
||||
// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
|
||||
class LL_COMMON_API NamedTimer
|
||||
: public LLInstanceTracker<NamedTimer>
|
||||
class LL_COMMON_API DeclareTimer
|
||||
: public LLInstanceTracker<DeclareTimer>
|
||||
{
|
||||
friend class DeclareTimer;
|
||||
public:
|
||||
~NamedTimer();
|
||||
DeclareTimer(const std::string& name, bool open = false, DeclareTimer* parent = &getRootTimer());
|
||||
~DeclareTimer();
|
||||
|
||||
enum { HISTORY_NUM = 300 };
|
||||
|
||||
const std::string& getName() const { return mName; }
|
||||
NamedTimer* getParent() const { return mParent; }
|
||||
void setParent(NamedTimer* parent);
|
||||
DeclareTimer* getParent() const { return mParent; }
|
||||
void setParent(DeclareTimer* parent);
|
||||
S32 getDepth();
|
||||
std::string getToolTip(S32 history_index = -1);
|
||||
|
||||
typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
|
||||
typedef std::vector<DeclareTimer*>::const_iterator child_const_iter;
|
||||
child_const_iter beginChildren();
|
||||
child_const_iter endChildren();
|
||||
std::vector<NamedTimer*>& getChildren();
|
||||
std::vector<DeclareTimer*>& getChildren();
|
||||
|
||||
void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
|
||||
bool getCollapsed() const { return mCollapsed; }
|
||||
void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
|
||||
bool getCollapsed() const { return mCollapsed; }
|
||||
|
||||
U32 getCountAverage() const { return mCountAverage; }
|
||||
U32 getCallAverage() const { return mCallAverage; }
|
||||
U32 getCallAverage() const { return mCallAverage; }
|
||||
|
||||
U32 getHistoricalCount(S32 history_index = 0) const;
|
||||
U32 getHistoricalCalls(S32 history_index = 0) const;
|
||||
|
||||
void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); }
|
||||
FrameState& getFrameState() const;
|
||||
static DeclareTimer& getRootTimer();
|
||||
|
||||
private:
|
||||
friend class LLFastTimer;
|
||||
friend class NamedTimerFactory;
|
||||
|
||||
//
|
||||
// methods
|
||||
//
|
||||
NamedTimer(const std::string& name);
|
||||
// recursive call to gather total time from children
|
||||
static void accumulateTimings();
|
||||
|
||||
|
|
@ -117,82 +105,62 @@ public:
|
|||
//
|
||||
// members
|
||||
//
|
||||
FrameState* mFrameState;
|
||||
U32 mSelfTimeCounter;
|
||||
U32 mTotalTimeCounter;
|
||||
U32 mCalls;
|
||||
DeclareTimer* mLastCaller; // used to bootstrap tree construction
|
||||
U16 mActiveCount; // number of timers with this ID active on stack
|
||||
bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
|
||||
|
||||
std::string mName;
|
||||
std::string mName;
|
||||
|
||||
// sum of recorded self time and tree time of all children timers (might not match actual recorded time of children if topology is incomplete
|
||||
U32 mTreeTimeCounter;
|
||||
// sum of recored self time and tree time of all children timers (might not match actual recorded time of children if topology is incomplete
|
||||
U32 mTreeTimeCounter;
|
||||
|
||||
U32 mCountAverage;
|
||||
U32 mCallAverage;
|
||||
U32 mCountAverage;
|
||||
U32 mCallAverage;
|
||||
|
||||
U32* mCountHistory;
|
||||
U32* mCallHistory;
|
||||
U32* mCountHistory;
|
||||
U32* mCallHistory;
|
||||
|
||||
// tree structure
|
||||
NamedTimer* mParent; // NamedTimer of caller(parent)
|
||||
std::vector<NamedTimer*> mChildren;
|
||||
DeclareTimer* mParent; // DeclareTimer of caller(parent)
|
||||
std::vector<DeclareTimer*> mChildren;
|
||||
bool mCollapsed; // don't show children
|
||||
bool mNeedsSorting; // sort children whenever child added
|
||||
};
|
||||
|
||||
// used to statically declare a new named timer
|
||||
class LL_COMMON_API DeclareTimer
|
||||
: public LLInstanceTracker<DeclareTimer>
|
||||
{
|
||||
friend class LLFastTimer;
|
||||
public:
|
||||
DeclareTimer(const std::string& name, bool open);
|
||||
DeclareTimer(const std::string& name);
|
||||
|
||||
NamedTimer& getNamedTimer() { return mTimer; }
|
||||
|
||||
private:
|
||||
FrameState mFrameState;
|
||||
NamedTimer& mTimer;
|
||||
};
|
||||
|
||||
public:
|
||||
//LLFastTimer(LLFastTimer::FrameState* state);
|
||||
|
||||
LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
|
||||
{
|
||||
#if FAST_TIMER_ON
|
||||
LLFastTimer::FrameState* frame_state = &timer.mFrameState;
|
||||
mStartTime = getCPUClockCount32();
|
||||
|
||||
frame_state->mActiveCount++;
|
||||
frame_state->mCalls++;
|
||||
timer.mActiveCount++;
|
||||
timer.mCalls++;
|
||||
// keep current parent as long as it is active when we are
|
||||
frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
|
||||
timer.mMoveUpTree |= (timer.mParent->mActiveCount == 0);
|
||||
|
||||
LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
|
||||
mLastTimerData = *cur_timer_data;
|
||||
cur_timer_data->mCurTimer = this;
|
||||
cur_timer_data->mFrameState = frame_state;
|
||||
cur_timer_data->mTimerData = &timer;
|
||||
cur_timer_data->mChildTime = 0;
|
||||
#endif
|
||||
#if DEBUG_FAST_TIMER_THREADS
|
||||
#if !LL_RELEASE
|
||||
assert_main_thread();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE ~LLFastTimer()
|
||||
{
|
||||
#if FAST_TIMER_ON
|
||||
LLFastTimer::FrameState* frame_state = LLFastTimer::sCurTimerData.mFrameState;
|
||||
U32 total_time = getCPUClockCount32() - mStartTime;
|
||||
|
||||
frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
|
||||
frame_state->mTotalTimeCounter += total_time;
|
||||
frame_state->mActiveCount--;
|
||||
DeclareTimer* timer_data = LLFastTimer::sCurTimerData.mTimerData;
|
||||
timer_data->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
|
||||
timer_data->mTotalTimeCounter += total_time;
|
||||
timer_data->mActiveCount--;
|
||||
|
||||
// store last caller to bootstrap tree creation
|
||||
// do this in the destructor in case of recursion to get topmost caller
|
||||
frame_state->mLastCaller = mLastTimerData.mFrameState;
|
||||
timer_data->mLastCaller = mLastTimerData.mTimerData;
|
||||
|
||||
// we are only tracking self time, so subtract our total time delta from parents
|
||||
mLastTimerData.mChildTime += total_time;
|
||||
|
|
@ -225,12 +193,11 @@ public:
|
|||
static S32 getCurFrameIndex() { return sCurFrameIndex; }
|
||||
|
||||
static void writeLog(std::ostream& os);
|
||||
static const NamedTimer* getTimerByName(const std::string& name);
|
||||
|
||||
struct CurTimerData
|
||||
{
|
||||
LLFastTimer* mCurTimer;
|
||||
FrameState* mFrameState;
|
||||
DeclareTimer* mTimerData;
|
||||
U32 mChildTime;
|
||||
};
|
||||
static CurTimerData sCurTimerData;
|
||||
|
|
@ -374,15 +341,13 @@ private:
|
|||
|
||||
#endif
|
||||
|
||||
static U64 sClockResolution;
|
||||
|
||||
static S32 sCurFrameIndex;
|
||||
static S32 sLastFrameIndex;
|
||||
static U64 sLastFrameTime;
|
||||
static U64 sClockResolution;
|
||||
static S32 sCurFrameIndex;
|
||||
static S32 sLastFrameIndex;
|
||||
static U64 sLastFrameTime;
|
||||
|
||||
U32 mStartTime;
|
||||
LLFastTimer::CurTimerData mLastTimerData;
|
||||
|
||||
};
|
||||
|
||||
typedef class LLFastTimer LLFastTimer;
|
||||
|
|
|
|||
|
|
@ -877,7 +877,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
|
|||
|
||||
|
||||
LLProcessorInfo::~LLProcessorInfo() {}
|
||||
F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
|
||||
LLUnit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
|
||||
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
|
||||
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
|
||||
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#ifndef LLPROCESSOR_H
|
||||
#define LLPROCESSOR_H
|
||||
#include "llunit.h"
|
||||
|
||||
class LLProcessorInfoImpl;
|
||||
|
||||
class LL_COMMON_API LLProcessorInfo
|
||||
|
|
@ -35,7 +37,7 @@ public:
|
|||
LLProcessorInfo();
|
||||
~LLProcessorInfo();
|
||||
|
||||
F64 getCPUFrequency() const;
|
||||
LLUnit<LLUnits::Megahertz, F64> getCPUFrequency() const;
|
||||
bool hasSSE() const;
|
||||
bool hasSSE2() const;
|
||||
bool hasAltivec() const;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ void init()
|
|||
void cleanup()
|
||||
{
|
||||
delete gMasterThreadRecorder;
|
||||
LLUnitStrict<LLUnits::Seconds, F32> seconds;
|
||||
gMasterThreadRecorder = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ namespace LLTrace
|
|||
typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
|
||||
typedef LLUnit<LLUnits::Minutes, F64> Minutes;
|
||||
typedef LLUnit<LLUnits::Hours, F64> Hours;
|
||||
typedef LLUnit<LLUnits::Days, F64> Days;
|
||||
typedef LLUnit<LLUnits::Weeks, F64> Weeks;
|
||||
typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
|
||||
typedef LLUnit<LLUnits::Microseconds, F64> Microseconds;
|
||||
typedef LLUnit<LLUnits::Nanoseconds, F64> Nanoseconds;
|
||||
|
|
@ -226,27 +224,6 @@ namespace LLTrace
|
|||
size_t mAccumulatorIndex;
|
||||
};
|
||||
|
||||
|
||||
template<typename T, typename IS_UNIT = void>
|
||||
struct StorageType
|
||||
{
|
||||
typedef T type_t;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct StorageType<T, typename T::is_unit_tag_t>
|
||||
{
|
||||
typedef typename StorageType<typename T::storage_t>::type_t type_t;
|
||||
};
|
||||
|
||||
template<> struct StorageType<F32> { typedef F64 type_t; };
|
||||
template<> struct StorageType<S32> { typedef S64 type_t; };
|
||||
template<> struct StorageType<U32> { typedef S64 type_t; };
|
||||
template<> struct StorageType<S16> { typedef S64 type_t; };
|
||||
template<> struct StorageType<U16> { typedef S64 type_t; };
|
||||
template<> struct StorageType<S8> { typedef S64 type_t; };
|
||||
template<> struct StorageType<U8> { typedef S64 type_t; };
|
||||
|
||||
template<typename T>
|
||||
class LL_COMMON_API MeasurementAccumulator
|
||||
{
|
||||
|
|
@ -406,10 +383,10 @@ namespace LLTrace
|
|||
|
||||
template <typename T = F64, typename IS_UNIT = void>
|
||||
class LL_COMMON_API Measurement
|
||||
: public TraceType<MeasurementAccumulator<typename StorageType<T>::type_t> >
|
||||
: public TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >
|
||||
{
|
||||
public:
|
||||
typedef typename StorageType<T>::type_t storage_t;
|
||||
typedef typename LLUnits::HighestPrecisionType<T>::type_t storage_t;
|
||||
|
||||
Measurement(const char* name, const char* description = NULL)
|
||||
: TraceType(name, description)
|
||||
|
|
@ -423,10 +400,10 @@ namespace LLTrace
|
|||
|
||||
template <typename T>
|
||||
class LL_COMMON_API Measurement <T, typename T::is_unit_tag_t>
|
||||
: public TraceType<MeasurementAccumulator<typename StorageType<typename T::storage_t>::type_t> >
|
||||
: public TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<typename T::storage_t>::type_t> >
|
||||
{
|
||||
public:
|
||||
typedef typename StorageType<typename T::storage_t>::type_t storage_t;
|
||||
typedef typename LLUnits::HighestPrecisionType<typename T::storage_t>::type_t storage_t;
|
||||
|
||||
Measurement(const char* name, const char* description = NULL)
|
||||
: TraceType(name, description)
|
||||
|
|
@ -446,10 +423,10 @@ namespace LLTrace
|
|||
|
||||
template <typename T = F64, typename IS_UNIT = void>
|
||||
class LL_COMMON_API Count
|
||||
: public TraceType<CountAccumulator<typename StorageType<T>::type_t> >
|
||||
: public TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >
|
||||
{
|
||||
public:
|
||||
typedef typename StorageType<T>::type_t storage_t;
|
||||
typedef typename LLUnits::HighestPrecisionType<T>::type_t storage_t;
|
||||
|
||||
Count(const char* name, const char* description = NULL)
|
||||
: TraceType(name)
|
||||
|
|
@ -463,10 +440,10 @@ namespace LLTrace
|
|||
|
||||
template <typename T>
|
||||
class LL_COMMON_API Count <T, typename T::is_unit_tag_t>
|
||||
: public TraceType<CountAccumulator<typename StorageType<typename T::storage_t>::type_t> >
|
||||
: public TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<typename T::storage_t>::type_t> >
|
||||
{
|
||||
public:
|
||||
typedef typename StorageType<typename T::storage_t>::type_t storage_t;
|
||||
typedef typename LLUnits::HighestPrecisionType<typename T::storage_t>::type_t storage_t;
|
||||
|
||||
Count(const char* name, const char* description = NULL)
|
||||
: TraceType(name)
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getSum(const Count<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getSum(static_cast<const TraceType<CountAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getSum(static_cast<const TraceType<CountAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getPerSec(const TraceType<CountAccumulator<F64> >& stat) const;
|
||||
|
|
@ -130,7 +130,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getPerSec(const Count<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getPerSec(static_cast<const TraceType<CountAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getPerSec(static_cast<const TraceType<CountAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
U32 getSampleCount(const TraceType<CountAccumulator<F64> >& stat) const;
|
||||
|
|
@ -143,7 +143,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getSum(const Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getSum(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getSum(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getPerSec(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
@ -151,7 +151,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getPerSec(const Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getPerSec(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getPerSec(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getMin(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
@ -159,7 +159,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getMin(const Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getMin(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getMin(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getMax(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
@ -167,7 +167,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getMax(const Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getMax(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getMax(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getMean(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
@ -175,7 +175,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getMean(Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getStandardDeviation(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
@ -183,7 +183,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getStandardDeviation(const Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
F64 getLastValue(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
@ -191,7 +191,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
T getLastValue(const Measurement<T, typename T::is_unit_tag_t>& stat) const
|
||||
{
|
||||
return (T)getLastValue(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
|
||||
return (T)getLastValue(static_cast<const TraceType<MeasurementAccumulator<LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
|
||||
}
|
||||
|
||||
U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const;
|
||||
|
|
|
|||
|
|
@ -32,19 +32,44 @@
|
|||
|
||||
namespace LLUnits
|
||||
{
|
||||
template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG>
|
||||
|
||||
template<typename T, typename IS_UNIT = void>
|
||||
struct HighestPrecisionType
|
||||
{
|
||||
typedef T type_t;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct HighestPrecisionType<T, typename T::is_unit_tag_t>
|
||||
{
|
||||
typedef typename HighestPrecisionType<typename T::storage_t>::type_t type_t;
|
||||
};
|
||||
|
||||
template<> struct HighestPrecisionType<F32> { typedef F64 type_t; };
|
||||
template<> struct HighestPrecisionType<S32> { typedef S64 type_t; };
|
||||
template<> struct HighestPrecisionType<U32> { typedef S64 type_t; };
|
||||
template<> struct HighestPrecisionType<S16> { typedef S64 type_t; };
|
||||
template<> struct HighestPrecisionType<U16> { typedef S64 type_t; };
|
||||
template<> struct HighestPrecisionType<S8> { typedef S64 type_t; };
|
||||
template<> struct HighestPrecisionType<U8> { typedef S64 type_t; };
|
||||
|
||||
template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG, typename VALUE_TYPE>
|
||||
struct ConversionFactor
|
||||
{
|
||||
static F64 get()
|
||||
static typename HighestPrecisionType<VALUE_TYPE>::type_t get()
|
||||
{
|
||||
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
|
||||
llstatic_assert(sizeof(DERIVED_UNITS_TAG) == 0, "Cannot convert between types.");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BASE_UNITS_TAG>
|
||||
struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG>
|
||||
template<typename BASE_UNITS_TAG, typename VALUE_TYPE>
|
||||
struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG, VALUE_TYPE>
|
||||
{
|
||||
static F64 get() { return 1.0; }
|
||||
static typename HighestPrecisionType<VALUE_TYPE>::type_t get()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -91,6 +116,11 @@ struct LLUnit
|
|||
return mValue;
|
||||
}
|
||||
|
||||
template<typename NEW_UNIT_TYPE> LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE> as()
|
||||
{
|
||||
return LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE>(*this);
|
||||
}
|
||||
|
||||
void operator += (storage_t value)
|
||||
{
|
||||
mValue += value;
|
||||
|
|
@ -121,7 +151,8 @@ struct LLUnit
|
|||
template<typename OTHER_UNIT, typename OTHER_STORAGE>
|
||||
void operator *= (LLUnit<OTHER_UNIT, OTHER_STORAGE> multiplicand)
|
||||
{
|
||||
llstatic_assert(sizeof(OTHER_UNIT) == false, "Multiplication of unit types not supported.");
|
||||
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
|
||||
llstatic_assert(sizeof(OTHER_UNIT) == 0, "Multiplication of unit types not supported.");
|
||||
}
|
||||
|
||||
void operator /= (storage_t divisor)
|
||||
|
|
@ -132,15 +163,16 @@ struct LLUnit
|
|||
template<typename OTHER_UNIT, typename OTHER_STORAGE>
|
||||
void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
|
||||
{
|
||||
llstatic_assert(sizeof(OTHER_UNIT) == false, "Division of unit types not supported.");
|
||||
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
|
||||
llstatic_assert(sizeof(OTHER_UNIT) == 0, "Division of unit types not supported.");
|
||||
}
|
||||
|
||||
template<typename SOURCE_UNITS, typename SOURCE_VALUE>
|
||||
static storage_t convert(LLUnit<SOURCE_UNITS, SOURCE_VALUE> v)
|
||||
template<typename SOURCE_UNITS, typename SOURCE_STORAGE>
|
||||
static storage_t convert(LLUnit<SOURCE_UNITS, SOURCE_STORAGE> v)
|
||||
{
|
||||
return (storage_t)(v.value()
|
||||
* LLUnits::ConversionFactor<SOURCE_UNITS, typename UNIT_TYPE::base_unit_t>::get()
|
||||
* LLUnits::ConversionFactor<typename UNIT_TYPE::base_unit_t, UNIT_TYPE>::get());
|
||||
* LLUnits::ConversionFactor<SOURCE_UNITS, typename UNIT_TYPE::base_unit_t, SOURCE_STORAGE>::get()
|
||||
* LLUnits::ConversionFactor<typename UNIT_TYPE::base_unit_t, UNIT_TYPE, STORAGE_TYPE>::get());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -148,6 +180,32 @@ protected:
|
|||
storage_t mValue;
|
||||
};
|
||||
|
||||
template<typename UNIT_TYPE, typename STORAGE_TYPE>
|
||||
struct LLUnitStrict : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
|
||||
{
|
||||
typedef LLUnitStrict<UNIT_TYPE, STORAGE_TYPE> self_t;
|
||||
|
||||
explicit LLUnitStrict(storage_t value = storage_t())
|
||||
: LLUnit(value)
|
||||
{}
|
||||
|
||||
template<typename OTHER_UNIT, typename OTHER_STORAGE>
|
||||
LLUnitStrict(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
|
||||
: LLUnit(convert(other))
|
||||
{}
|
||||
|
||||
LLUnitStrict(self_t& other)
|
||||
: LLUnit(other)
|
||||
{}
|
||||
|
||||
|
||||
private:
|
||||
operator storage_t() const
|
||||
{
|
||||
return value();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// operator +
|
||||
//
|
||||
|
|
@ -221,7 +279,8 @@ LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (LLUnit<STORAGE_TYPE, UNIT_TYPE> firs
|
|||
template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
|
||||
void operator * (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
|
||||
{
|
||||
llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported.");
|
||||
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
|
||||
llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported.");
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -242,7 +301,8 @@ LLUnit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnit<STORAGE_TYPE, UNIT_TYPE> firs
|
|||
template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
|
||||
void operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
|
||||
{
|
||||
llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported.");
|
||||
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
|
||||
llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported.");
|
||||
}
|
||||
|
||||
#define COMPARISON_OPERATORS(op) \
|
||||
|
|
@ -273,21 +333,21 @@ COMPARISON_OPERATORS(!=)
|
|||
|
||||
namespace LLUnits
|
||||
{
|
||||
#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor)\
|
||||
struct unit_name \
|
||||
{ \
|
||||
typedef base_unit_name base_unit_t; \
|
||||
}; \
|
||||
template<> \
|
||||
struct ConversionFactor<unit_name, base_unit_name> \
|
||||
{ \
|
||||
static F64 get() { return (conversion_factor); } \
|
||||
}; \
|
||||
\
|
||||
template<> \
|
||||
struct ConversionFactor<base_unit_name, unit_name> \
|
||||
{ \
|
||||
static F64 get() { return 1.0 / (conversion_factor); } \
|
||||
#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor) \
|
||||
struct unit_name \
|
||||
{ \
|
||||
typedef base_unit_name base_unit_t; \
|
||||
}; \
|
||||
template<typename STORAGE_TYPE> \
|
||||
struct ConversionFactor<unit_name, base_unit_name, STORAGE_TYPE> \
|
||||
{ \
|
||||
static typename HighestPrecisionType<STORAGE_TYPE>::type_t get() { return typename HighestPrecisionType<STORAGE_TYPE>::type_t(conversion_factor); } \
|
||||
}; \
|
||||
\
|
||||
template<typename STORAGE_TYPE> \
|
||||
struct ConversionFactor<base_unit_name, unit_name, STORAGE_TYPE> \
|
||||
{ \
|
||||
static typename HighestPrecisionType<STORAGE_TYPE>::type_t get() { return typename HighestPrecisionType<STORAGE_TYPE>::type_t(1.0 / (conversion_factor)); } \
|
||||
}
|
||||
|
||||
struct Bytes { typedef Bytes base_unit_t; };
|
||||
|
|
@ -302,16 +362,19 @@ LL_DECLARE_DERIVED_UNIT(Bytes, Gigabits, (1024 * 1024 * 1024 / 8));
|
|||
struct Seconds { typedef Seconds base_unit_t; };
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Minutes, 60);
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Hours, 60 * 60);
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Days, 60 * 60 * 24);
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Weeks, 60 * 60 * 24 * 7);
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Milliseconds, (1.0 / 1000.0));
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Microseconds, (1.0 / (1000000.0)));
|
||||
LL_DECLARE_DERIVED_UNIT(Seconds, Nanoseconds, (1.0 / (1000000000.0)));
|
||||
|
||||
struct Meters { typedef Meters base_unit_t; };
|
||||
LL_DECLARE_DERIVED_UNIT(Meters, Kilometers, 1000);
|
||||
LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, (1.0 / 100));
|
||||
LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, (1.0 / 1000));
|
||||
LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, (1.0 / 100.0));
|
||||
LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, (1.0 / 1000.0));
|
||||
|
||||
struct Hertz { typedef Hertz base_unit_t; };
|
||||
LL_DECLARE_DERIVED_UNIT(Hertz, Kilohertz, 1000);
|
||||
LL_DECLARE_DERIVED_UNIT(Hertz, Megahertz, 1000 * 1000);
|
||||
LL_DECLARE_DERIVED_UNIT(Hertz, Gigahertz, 1000 * 1000 * 1000);
|
||||
}
|
||||
|
||||
#endif // LL_LLUNIT_H
|
||||
|
|
|
|||
|
|
@ -61,17 +61,17 @@ static const S32 LINE_GRAPH_HEIGHT = 240;
|
|||
static S32 FTV_NUM_TIMERS;
|
||||
const S32 FTV_MAX_DEPTH = 8;
|
||||
|
||||
std::vector<LLFastTimer::NamedTimer*> ft_display_idx; // line of table entry for display purposes (for collapse)
|
||||
std::vector<LLFastTimer::DeclareTimer*> ft_display_idx; // line of table entry for display purposes (for collapse)
|
||||
|
||||
typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_iterator_t;
|
||||
typedef LLTreeDFSIter<LLFastTimer::DeclareTimer, LLFastTimer::DeclareTimer::child_const_iter> timer_tree_iterator_t;
|
||||
|
||||
BOOL LLFastTimerView::sAnalyzePerformance = FALSE;
|
||||
|
||||
static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
|
||||
static timer_tree_iterator_t begin_timer_tree(LLFastTimer::DeclareTimer& id)
|
||||
{
|
||||
return timer_tree_iterator_t(&id,
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::beginChildren), _1),
|
||||
boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::endChildren), _1));
|
||||
}
|
||||
|
||||
static timer_tree_iterator_t end_timer_tree()
|
||||
|
|
@ -92,7 +92,7 @@ LLFastTimerView::LLFastTimerView(const LLSD& key)
|
|||
mScrollIndex = 0;
|
||||
mHoverID = NULL;
|
||||
mHoverBarIndex = -1;
|
||||
FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
|
||||
FTV_NUM_TIMERS = LLFastTimer::DeclareTimer::instanceCount();
|
||||
mPrintStats = -1;
|
||||
}
|
||||
|
||||
|
|
@ -139,13 +139,13 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
|
||||
bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
|
||||
mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx;
|
||||
mPrintStats = LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex - bar_idx;
|
||||
return TRUE;
|
||||
}
|
||||
return LLFloater::handleRightMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
|
||||
LLFastTimer::DeclareTimer* LLFastTimerView::getLegendID(S32 y)
|
||||
{
|
||||
S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5;
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if (x < mBarRect.mLeft)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = getLegendID(y);
|
||||
LLFastTimer::DeclareTimer* idp = getLegendID(y);
|
||||
if (idp)
|
||||
{
|
||||
idp->setCollapsed(!idp->getCollapsed());
|
||||
|
|
@ -235,7 +235,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
|
|||
if (hasMouseCapture())
|
||||
{
|
||||
F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f);
|
||||
mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
|
||||
mScrollIndex = llround( lerp * (F32)(LLFastTimer::DeclareTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
|
||||
mScrollIndex = llclamp( mScrollIndex, 0, LLFastTimer::getLastFrameIndex());
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -288,7 +288,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
else if (x < mBarRect.mLeft)
|
||||
{
|
||||
LLFastTimer::NamedTimer* timer_id = getLegendID(y);
|
||||
LLFastTimer::DeclareTimer* timer_id = getLegendID(y);
|
||||
if (timer_id)
|
||||
{
|
||||
mHoverID = timer_id;
|
||||
|
|
@ -299,6 +299,23 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
|
||||
|
||||
static std::string get_tooltip(LLFastTimer::DeclareTimer& timer, S32 history_index = -1)
|
||||
{
|
||||
F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
|
||||
|
||||
std::string tooltip;
|
||||
if (history_index < 0)
|
||||
{
|
||||
// by default, show average number of call
|
||||
tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(timer.getCountAverage() * ms_multiplier), (S32)timer.getCallAverage());
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(timer.getHistoricalCount(history_index) * ms_multiplier), (S32)timer.getHistoricalCalls(history_index));
|
||||
}
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
|
||||
|
|
@ -309,8 +326,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
LLRect screen_rect;
|
||||
localRectToScreen(mToolTipRect, &screen_rect);
|
||||
|
||||
std::string tooltip = get_tooltip(*mHoverTimer, LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex);
|
||||
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params()
|
||||
.message(mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex))
|
||||
.message(tooltip)
|
||||
.sticky_rect(screen_rect)
|
||||
.delay_time(0.f));
|
||||
|
||||
|
|
@ -322,10 +341,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
// tooltips for timer legend
|
||||
if (x < mBarRect.mLeft)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = getLegendID(y);
|
||||
LLFastTimer::DeclareTimer* idp = getLegendID(y);
|
||||
if (idp)
|
||||
{
|
||||
LLToolTipMgr::instance().show(idp->getToolTip());
|
||||
LLToolTipMgr::instance().show(get_tooltip(*idp));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -340,13 +359,13 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
|||
LLFastTimer::sPauseHistory = TRUE;
|
||||
mScrollIndex = llclamp( mScrollIndex + clicks,
|
||||
0,
|
||||
llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
|
||||
llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::DeclareTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true);
|
||||
|
||||
static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors;
|
||||
static std::map<LLFastTimer::DeclareTimer*, LLColor4> sTimerColors;
|
||||
|
||||
void LLFastTimerView::draw()
|
||||
{
|
||||
|
|
@ -426,7 +445,7 @@ void LLFastTimerView::draw()
|
|||
it != timer_tree_iterator_t();
|
||||
++it)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = (*it);
|
||||
LLFastTimer::DeclareTimer* idp = (*it);
|
||||
|
||||
const F32 HUE_INCREMENT = 0.23f;
|
||||
hue = fmodf(hue + HUE_INCREMENT, 1.f);
|
||||
|
|
@ -446,12 +465,12 @@ void LLFastTimerView::draw()
|
|||
LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin));
|
||||
S32 cur_line = 0;
|
||||
ft_display_idx.clear();
|
||||
std::map<LLFastTimer::NamedTimer*, S32> display_line;
|
||||
std::map<LLFastTimer::DeclareTimer*, S32> display_line;
|
||||
for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
|
||||
it != timer_tree_iterator_t();
|
||||
++it)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = (*it);
|
||||
LLFastTimer::DeclareTimer* idp = (*it);
|
||||
display_line[idp] = cur_line;
|
||||
ft_display_idx.push_back(idp);
|
||||
cur_line++;
|
||||
|
|
@ -471,7 +490,7 @@ void LLFastTimerView::draw()
|
|||
S32 calls = 0;
|
||||
if (mHoverBarIndex > 0 && mHoverID)
|
||||
{
|
||||
S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex;
|
||||
S32 hidx = LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex;
|
||||
U64 ticks = idp->getHistoricalCount(hidx);
|
||||
ms = (F32)((F64)ticks * iclock_freq);
|
||||
calls = (S32)idp->getHistoricalCalls(hidx);
|
||||
|
|
@ -509,7 +528,7 @@ void LLFastTimerView::draw()
|
|||
|
||||
x += dx;
|
||||
BOOL is_child_of_hover_item = (idp == mHoverID);
|
||||
LLFastTimer::NamedTimer* next_parent = idp->getParent();
|
||||
LLFastTimer::DeclareTimer* next_parent = idp->getParent();
|
||||
while(!is_child_of_hover_item && next_parent)
|
||||
{
|
||||
is_child_of_hover_item = (mHoverID == next_parent);
|
||||
|
|
@ -687,7 +706,7 @@ void LLFastTimerView::draw()
|
|||
S32 tidx;
|
||||
if (j >= 0)
|
||||
{
|
||||
tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex;
|
||||
tidx = LLFastTimer::DeclareTimer::HISTORY_NUM - j - 1 - mScrollIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -701,14 +720,14 @@ void LLFastTimerView::draw()
|
|||
std::vector<S32> deltax;
|
||||
xpos.push_back(xleft);
|
||||
|
||||
LLFastTimer::NamedTimer* prev_id = NULL;
|
||||
LLFastTimer::DeclareTimer* prev_id = NULL;
|
||||
|
||||
S32 i = 0;
|
||||
for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
|
||||
it != end_timer_tree();
|
||||
++it, ++i)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = (*it);
|
||||
LLFastTimer::DeclareTimer* idp = (*it);
|
||||
F32 frac = tidx == -1
|
||||
? (F32)idp->getCountAverage() / (F32)totalticks
|
||||
: (F32)idp->getHistoricalCount(tidx) / (F32)totalticks;
|
||||
|
|
@ -735,7 +754,7 @@ void LLFastTimerView::draw()
|
|||
{
|
||||
U64 sublevelticks = 0;
|
||||
|
||||
for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren();
|
||||
for (LLFastTimer::DeclareTimer::child_const_iter it = prev_id->beginChildren();
|
||||
it != prev_id->endChildren();
|
||||
++it)
|
||||
{
|
||||
|
|
@ -777,7 +796,7 @@ void LLFastTimerView::draw()
|
|||
S32 scale_offset = 0;
|
||||
|
||||
BOOL is_child_of_hover_item = (idp == mHoverID);
|
||||
LLFastTimer::NamedTimer* next_parent = idp->getParent();
|
||||
LLFastTimer::DeclareTimer* next_parent = idp->getParent();
|
||||
while(!is_child_of_hover_item && next_parent)
|
||||
{
|
||||
is_child_of_hover_item = (mHoverID == next_parent);
|
||||
|
|
@ -842,10 +861,10 @@ void LLFastTimerView::draw()
|
|||
|
||||
//highlight visible range
|
||||
{
|
||||
S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
|
||||
S32 first_frame = LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex;
|
||||
S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
|
||||
|
||||
F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
|
||||
F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::DeclareTimer::HISTORY_NUM-1);
|
||||
|
||||
F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;
|
||||
F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame;
|
||||
|
|
@ -872,7 +891,7 @@ void LLFastTimerView::draw()
|
|||
it != end_timer_tree();
|
||||
++it)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = (*it);
|
||||
LLFastTimer::DeclareTimer* idp = (*it);
|
||||
|
||||
//fatten highlighted timer
|
||||
if (mHoverID == idp)
|
||||
|
|
@ -896,8 +915,8 @@ void LLFastTimerView::draw()
|
|||
|
||||
gGL.color4f(col[0], col[1], col[2], alpha);
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex());
|
||||
j < LLFastTimer::NamedTimer::HISTORY_NUM;
|
||||
for (U32 j = llmax(0, LLFastTimer::DeclareTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex());
|
||||
j < LLFastTimer::DeclareTimer::HISTORY_NUM;
|
||||
j++)
|
||||
{
|
||||
U64 ticks = idp->getHistoricalCount(j);
|
||||
|
|
@ -918,7 +937,7 @@ void LLFastTimerView::draw()
|
|||
//normalize to highlighted timer
|
||||
cur_max = llmax(cur_max, ticks);
|
||||
}
|
||||
F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
|
||||
F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::DeclareTimer::HISTORY_NUM-1)*j;
|
||||
F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks;
|
||||
gGL.vertex2f(x,y);
|
||||
gGL.vertex2f(x,mGraphRect.mBottom);
|
||||
|
|
@ -973,7 +992,7 @@ void LLFastTimerView::draw()
|
|||
it != end_timer_tree();
|
||||
++it)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = (*it);
|
||||
LLFastTimer::DeclareTimer* idp = (*it);
|
||||
|
||||
if (!first)
|
||||
{
|
||||
|
|
@ -995,7 +1014,7 @@ void LLFastTimerView::draw()
|
|||
it != end_timer_tree();
|
||||
++it)
|
||||
{
|
||||
LLFastTimer::NamedTimer* idp = (*it);
|
||||
LLFastTimer::DeclareTimer* idp = (*it);
|
||||
|
||||
if (!first)
|
||||
{
|
||||
|
|
@ -1033,11 +1052,8 @@ void LLFastTimerView::draw()
|
|||
|
||||
F64 LLFastTimerView::getTime(const std::string& name)
|
||||
{
|
||||
const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name);
|
||||
if (timerp)
|
||||
{
|
||||
return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond();
|
||||
}
|
||||
//TODO: replace calls to this with use of timer object directly
|
||||
//llstatic_assert(false, "TODO: implement");
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
|
@ -1552,9 +1568,9 @@ void LLFastTimerView::onClickCloseBtn()
|
|||
setVisible(false);
|
||||
}
|
||||
|
||||
LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer()
|
||||
LLFastTimer::DeclareTimer& LLFastTimerView::getFrameTimer()
|
||||
{
|
||||
return FTM_FRAME.getNamedTimer();
|
||||
return FTM_FRAME;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ private:
|
|||
static LLSD analyzePerformanceLogDefault(std::istream& is) ;
|
||||
static void exportCharts(const std::string& base, const std::string& target);
|
||||
void onPause();
|
||||
LLFastTimer::NamedTimer& getFrameTimer();
|
||||
LLFastTimer::DeclareTimer& getFrameTimer();
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ public:
|
|||
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
virtual void draw();
|
||||
|
||||
LLFastTimer::NamedTimer* getLegendID(S32 y);
|
||||
LLFastTimer::DeclareTimer* getLegendID(S32 y);
|
||||
F64 getTime(const std::string& name);
|
||||
|
||||
protected:
|
||||
|
|
@ -85,8 +85,8 @@ private:
|
|||
U64 mMaxCountTotal;
|
||||
LLRect mBarRect;
|
||||
S32 mScrollIndex;
|
||||
LLFastTimer::NamedTimer* mHoverID;
|
||||
LLFastTimer::NamedTimer* mHoverTimer;
|
||||
LLFastTimer::DeclareTimer* mHoverID;
|
||||
LLFastTimer::DeclareTimer* mHoverTimer;
|
||||
LLRect mToolTipRect;
|
||||
S32 mHoverBarIndex;
|
||||
LLFrameTimer mHighlightTimer;
|
||||
|
|
|
|||
|
|
@ -2715,7 +2715,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
|
|||
|
||||
S32 count = 0;
|
||||
|
||||
max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime);
|
||||
max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnit<LLUnits::Seconds, F32>(max_dtime));
|
||||
LLSpatialGroup* last_group = NULL;
|
||||
LLSpatialBridge* last_bridge = NULL;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue