summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/llcommon/llfasttimer.cpp77
-rwxr-xr-xindra/llcommon/llfasttimer.h4
-rw-r--r--indra/llcommon/lltrace.h19
-rw-r--r--indra/llcommon/lltracerecording.cpp38
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp1
-rw-r--r--indra/llcommon/tests/llunits_test.cpp3
-rwxr-xr-xindra/newview/llfasttimerview.cpp316
-rwxr-xr-xindra/newview/llfasttimerview.h33
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_fast_timers.xml69
9 files changed, 315 insertions, 245 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index d9670891f8..4da9c3fd6c 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -178,43 +178,38 @@ TimeBlockTreeNode& TimeBlock::getTreeNode() const
return *nodep;
}
-static LLFastTimer::DeclareTimer FTM_PROCESS_TIMES("Process FastTimer Times");
-// not thread safe, so only call on main thread
-//static
-void TimeBlock::processTimes()
+void TimeBlock::bootstrapTimerTree()
{
- LLFastTimer _(FTM_PROCESS_TIMES);
- get_clock_count(); // good place to calculate clock frequency
- U64 cur_time = getCPUClockCount64();
-
- // set up initial tree
for (LLInstanceTracker<TimeBlock>::instance_iter begin_it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances(), it = begin_it;
it != end_it;
++it)
{
TimeBlock& timer = *it;
if (&timer == &TimeBlock::getRootTimeBlock()) continue;
-
+
// bootstrap tree construction by attaching to last timer to be on stack
// when this timer was called
if (timer.getParent() == &TimeBlock::getRootTimeBlock())
{
TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();
-
+
if (accumulator->mLastCaller)
{
timer.setParent(accumulator->mLastCaller);
accumulator->mParent = accumulator->mLastCaller;
}
- // no need to push up tree on first use, flag can be set spuriously
+ // no need to push up tree on first use, flag can be set spuriously
accumulator->mMoveUpTree = false;
}
}
+}
- // bump timers up tree if they have 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
+// bump timers up tree if they have 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
+void TimeBlock::incrementalUpdateTimerTree()
+{
for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(TimeBlock::getRootTimeBlock());
it != end_timer_tree_bottom_up();
++it)
@@ -240,27 +235,35 @@ void TimeBlock::processTimes()
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());
- accumulator->mParent = timerp->getParent();
- accumulator->mMoveUpTree = false;
+ accumulator->mParent = timerp->getParent();
+ accumulator->mMoveUpTree = false;
// don't bubble up any ancestors until descendants are done bubbling up
- // as ancestors may call this timer only on certain paths, so we want to resolve
- // child-most block locations before their parents
+ // as ancestors may call this timer only on certain paths, so we want to resolve
+ // child-most block locations before their parents
it.skipAncestors();
}
}
}
+}
+
+
+void TimeBlock::updateTimes()
+{
+ U64 cur_time = getCPUClockCount64();
// walk up stack of active timers and accumulate current time while leaving timing structures active
- BlockTimerStackRecord* stack_record = ThreadTimerStack::getInstance();
- BlockTimer* cur_timer = stack_record->mActiveTimer;
- TimeBlockAccumulator* accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
+ BlockTimerStackRecord* stack_record = ThreadTimerStack::getInstance();
+ BlockTimer* cur_timer = stack_record->mActiveTimer;
+ TimeBlockAccumulator* accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
while(cur_timer
&& cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self
{
U64 cumulative_time_delta = cur_time - cur_timer->mStartTime;
- accumulator->mTotalTimeCounter += cumulative_time_delta - (accumulator->mTotalTimeCounter - cur_timer->mBlockStartTotalTimeCounter);
+ accumulator->mTotalTimeCounter += cumulative_time_delta
+ - (accumulator->mTotalTimeCounter
+ - cur_timer->mBlockStartTotalTimeCounter);
accumulator->mSelfTimeCounter += cumulative_time_delta - stack_record->mChildTime;
stack_record->mChildTime = 0;
@@ -268,11 +271,28 @@ void TimeBlock::processTimes()
cur_timer->mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
stack_record = &cur_timer->mParentTimerData;
- accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
- cur_timer = stack_record->mActiveTimer;
+ accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
+ cur_timer = stack_record->mActiveTimer;
stack_record->mChildTime += cumulative_time_delta;
}
+}
+
+static LLFastTimer::DeclareTimer FTM_PROCESS_TIMES("Process FastTimer Times");
+
+// not thread safe, so only call on main thread
+//static
+void TimeBlock::processTimes()
+{
+ LLFastTimer _(FTM_PROCESS_TIMES);
+ get_clock_count(); // good place to calculate clock frequency
+
+ // set up initial tree
+ bootstrapTimerTree();
+
+ incrementalUpdateTimerTree();
+
+ updateTimes();
// reset for next frame
for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(),
@@ -288,14 +308,13 @@ void TimeBlock::processTimes()
}
}
-
std::vector<TimeBlock*>::iterator TimeBlock::beginChildren()
- {
+{
return getTreeNode().mChildren.begin();
- }
+}
std::vector<TimeBlock*>::iterator TimeBlock::endChildren()
- {
+{
return getTreeNode().mChildren.end();
}
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index fdc6997d45..e800befd9f 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -115,6 +115,7 @@ public:
static void pushLog(LLSD sd);
static void setLogLock(LLMutex* mutex);
static void writeLog(std::ostream& os);
+ static void updateTimes();
// dumps current cumulative frame stats to log
// call nextFrame() to reset timers
@@ -262,6 +263,9 @@ public:
// can be called multiple times in a frame, at any point
static void processTimes();
+ static void bootstrapTimerTree();
+ static void incrementalUpdateTimerTree();
+
// call this once a frame to periodically log timers
static void logStats();
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index cd377531e8..6292534a03 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -157,12 +157,12 @@ public:
}
}
- void flush()
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
{
llassert(mStorageSize >= sNextStorageSlot);
for (size_t i = 0; i < sNextStorageSlot; i++)
{
- mStorage[i].flush();
+ mStorage[i].flush(time_stamp);
}
}
@@ -380,7 +380,7 @@ public:
mLastValue = other ? other->mLastValue : 0;
}
- void flush() {}
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds>) {}
F64 getSum() const { return mSum; }
F64 getMin() const { return mMin; }
@@ -512,9 +512,8 @@ public:
mHasValue = other ? other->mHasValue : false;
}
- void flush()
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
{
- LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
LLUnitImplicit<F64, LLUnits::Seconds> delta_time = time_stamp - mLastSampleTimeStamp;
if (mHasValue)
@@ -579,7 +578,7 @@ public:
mSum = 0;
}
- void flush() {}
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds>) {}
F64 getSum() const { return mSum; }
@@ -614,7 +613,7 @@ public:
TimeBlockAccumulator();
void addSamples(const self_t& other, bool /*append*/);
void reset(const self_t* other);
- void flush() {}
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds>) {}
//
// members
@@ -780,10 +779,10 @@ struct MemStatAccumulator
mDeallocatedCount = 0;
}
- void flush()
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
{
- mSize.flush();
- mChildSize.flush();
+ mSize.flush(time_stamp);
+ mChildSize.flush(time_stamp);
}
SampleAccumulator mSize,
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index f2c5941011..33002929ea 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -107,7 +107,9 @@ void RecordingBuffers::reset(RecordingBuffers* other)
void RecordingBuffers::flush()
{
- mSamples.flush();
+ LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+
+ mSamples.flush(time_stamp);
}
///////////////////////////////////////////////////////////////////////
@@ -205,7 +207,6 @@ void Recording::mergeRecording( const Recording& other)
LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat)
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
- update();
return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
/ (F64)LLTrace::TimeBlock::countsPerSecond();
}
@@ -213,14 +214,12 @@ LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumul
LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
- update();
return (F64)(accumulator.mSelfTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond();
}
U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
{
- update();
return mBuffers->mStackTimers[stat.getIndex()].mCalls;
}
@@ -228,7 +227,6 @@ LLUnit<F64, LLUnits::Seconds> Recording::getPerSec(const TraceType<TimeBlockAccu
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
- update();
return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value());
}
@@ -237,105 +235,88 @@ LLUnit<F64, LLUnits::Seconds> Recording::getPerSec(const TraceType<TimeBlockAccu
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
- update();
return (F64)(accumulator.mSelfTimeCounter)
/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value());
}
F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
{
- update();
return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds.value();
}
LLUnit<F64, LLUnits::Bytes> Recording::getMin(const TraceType<MemStatAccumulator>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getMin();
}
LLUnit<F64, LLUnits::Bytes> Recording::getMean(const TraceType<MemStatAccumulator>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getMean();
}
LLUnit<F64, LLUnits::Bytes> Recording::getMax(const TraceType<MemStatAccumulator>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getMax();
}
LLUnit<F64, LLUnits::Bytes> Recording::getStandardDeviation(const TraceType<MemStatAccumulator>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getStandardDeviation();
}
LLUnit<F64, LLUnits::Bytes> Recording::getLastValue(const TraceType<MemStatAccumulator>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getLastValue();
}
LLUnit<F64, LLUnits::Bytes> Recording::getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMin();
}
LLUnit<F64, LLUnits::Bytes> Recording::getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMean();
}
LLUnit<F64, LLUnits::Bytes> Recording::getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMax();
}
LLUnit<F64, LLUnits::Bytes> Recording::getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getStandardDeviation();
}
LLUnit<F64, LLUnits::Bytes> Recording::getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getLastValue();
}
U32 Recording::getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount;
}
U32 Recording::getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat)
{
- update();
return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount;
}
F64 Recording::getSum( const TraceType<CountAccumulator>& stat )
{
- update();
return mBuffers->mCounts[stat.getIndex()].getSum();
}
F64 Recording::getSum( const TraceType<EventAccumulator>& stat )
{
- update();
return (F64)mBuffers->mEvents[stat.getIndex()].getSum();
}
F64 Recording::getPerSec( const TraceType<CountAccumulator>& stat )
{
- update();
F64 sum = mBuffers->mCounts[stat.getIndex()].getSum();
return (sum != 0.0)
? (sum / mElapsedSeconds.value())
@@ -344,79 +325,66 @@ F64 Recording::getPerSec( const TraceType<CountAccumulator>& stat )
U32 Recording::getSampleCount( const TraceType<CountAccumulator>& stat )
{
- update();
return mBuffers->mCounts[stat.getIndex()].getSampleCount();
}
F64 Recording::getMin( const TraceType<SampleAccumulator>& stat )
{
- update();
return mBuffers->mSamples[stat.getIndex()].getMin();
}
F64 Recording::getMax( const TraceType<SampleAccumulator>& stat )
{
- update();
return mBuffers->mSamples[stat.getIndex()].getMax();
}
F64 Recording::getMean( const TraceType<SampleAccumulator>& stat )
{
- update();
return mBuffers->mSamples[stat.getIndex()].getMean();
}
F64 Recording::getStandardDeviation( const TraceType<SampleAccumulator>& stat )
{
- update();
return mBuffers->mSamples[stat.getIndex()].getStandardDeviation();
}
F64 Recording::getLastValue( const TraceType<SampleAccumulator>& stat )
{
- update();
return mBuffers->mSamples[stat.getIndex()].getLastValue();
}
U32 Recording::getSampleCount( const TraceType<SampleAccumulator>& stat )
{
- update();
return mBuffers->mSamples[stat.getIndex()].getSampleCount();
}
F64 Recording::getMin( const TraceType<EventAccumulator>& stat )
{
- update();
return mBuffers->mEvents[stat.getIndex()].getMin();
}
F64 Recording::getMax( const TraceType<EventAccumulator>& stat )
{
- update();
return mBuffers->mEvents[stat.getIndex()].getMax();
}
F64 Recording::getMean( const TraceType<EventAccumulator>& stat )
{
- update();
return mBuffers->mEvents[stat.getIndex()].getMean();
}
F64 Recording::getStandardDeviation( const TraceType<EventAccumulator>& stat )
{
- update();
return mBuffers->mEvents[stat.getIndex()].getStandardDeviation();
}
F64 Recording::getLastValue( const TraceType<EventAccumulator>& stat )
{
- update();
return mBuffers->mEvents[stat.getIndex()].getLastValue();
}
U32 Recording::getSampleCount( const TraceType<EventAccumulator>& stat )
{
- update();
return mBuffers->mEvents[stat.getIndex()].getSampleCount();
}
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index c1a0700eff..54006f4e5b 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -111,6 +111,7 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU
if (mActiveRecordings.empty()) return mActiveRecordings.rend();
mActiveRecordings.back()->mPartialRecording.flush();
+ TimeBlock::updateTimes();
active_recording_list_t::reverse_iterator it, end_it;
for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend();
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 04764f6c2f..a5df51f6de 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -56,6 +56,9 @@ namespace tut
LLUnit<F32, Quatloos> float_quatloos;
ensure(float_quatloos == 0.f);
+ LLUnit<F32, Quatloos> float_initialize_quatloos(1);
+ ensure(float_initialize_quatloos == 1.f);
+
LLUnit<S32, Quatloos> int_quatloos;
ensure(int_quatloos == 0);
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 231ece4bbd..1355b58f8b 100755
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -30,12 +30,14 @@
#include "llviewerwindow.h"
#include "llrect.h"
+#include "llcombobox.h"
#include "llerror.h"
#include "llgl.h"
#include "llimagepng.h"
#include "llrender.h"
#include "llrendertarget.h"
#include "lllocalcliprect.h"
+#include "lllayoutstack.h"
#include "llmath.h"
#include "llfontgl.h"
#include "llsdserialize.h"
@@ -59,6 +61,8 @@ using namespace LLTrace;
static const S32 MAX_VISIBLE_HISTORY = 12;
static const S32 LINE_GRAPH_HEIGHT = 240;
static const S32 MIN_BAR_HEIGHT = 3;
+static const S32 RUNNING_AVERAGE_WIDTH = 100;
+static const S32 NUM_FRAMES_HISTORY = 256;
std::vector<TimeBlock*> ft_display_idx; // line of table entry for display purposes (for collapse)
@@ -95,17 +99,15 @@ LLFastTimerView::LLFastTimerView(const LLSD& key)
: LLFloater(key),
mHoverTimer(NULL),
mDisplayMode(0),
- mDisplayCenter(ALIGN_CENTER),
- mDisplayCalls(false),
- mDisplayHz(false),
+ mDisplayType(TIME),
mScrollIndex(0),
mHoverID(NULL),
mHoverBarIndex(-1),
mStatsIndex(-1),
mPauseHistory(false),
- mRecording(512)
+ mRecording(NUM_FRAMES_HISTORY)
{
- mTimerBarRows.resize(512);
+ mTimerBarRows.resize(NUM_FRAMES_HISTORY);
}
LLFastTimerView::~LLFastTimerView()
@@ -172,7 +174,7 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
TimeBlock* LLFastTimerView::getLegendID(S32 y)
{
- S32 idx = (mBarRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 1;
+ S32 idx = (mLegendRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight() + 2);
if (idx >= 0 && idx < (S32)ft_display_idx.size())
{
@@ -208,26 +210,6 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
//left click drills down by expanding timers
mHoverTimer->setCollapsed(false);
}
- else if (mask & MASK_ALT)
- {
- if (mask & MASK_CONTROL)
- {
- mDisplayHz = !mDisplayHz;
- }
- else
- {
- mDisplayCalls = !mDisplayCalls;
- }
- }
- else if (mask & MASK_SHIFT)
- {
- if (++mDisplayMode > 3)
- mDisplayMode = 0;
- }
- else if (mask & MASK_CONTROL)
- {
- mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
- }
else if (mGraphRect.pointInRect(x, y))
{
gFocusMgr.setMouseCapture(this);
@@ -260,7 +242,10 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
if(mPauseHistory && mBarRect.pointInRect(x, y))
{
- mHoverBarIndex = llmin((mBarRect.mTop - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1,
+ //const S32 bars_top = mBarRect.mTop;
+ const S32 bars_top = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4);
+
+ mHoverBarIndex = llmin((bars_top - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1,
(S32)mRecording.getNumRecordedPeriods() - 1,
MAX_VISIBLE_HISTORY);
if (mHoverBarIndex == 0)
@@ -272,25 +257,33 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
mHoverBarIndex = 0;
}
- TimerBarRow& row = mHoverBarIndex == 0 ? mAverageTimerRow : mTimerBarRows[mHoverBarIndex - 1];
+ TimerBarRow& row = mHoverBarIndex == 0 ? mAverageTimerRow : mTimerBarRows[mScrollIndex + mHoverBarIndex - 1];
TimerBar* hover_bar = NULL;
LLUnit<F32, LLUnits::Seconds> mouse_time_offset = ((F32)(x - mBarRect.mLeft) / (F32)mBarRect.getWidth()) * mTotalTimeDisplay;
- for (std::vector<TimerBar>::iterator it = row.mBars.begin(), end_it = row.mBars.end();
- it != end_it;
- ++it)
+ for (int bar_index = 0, end_index = LLInstanceTracker<LLTrace::TimeBlock>::instanceCount();
+ bar_index < end_index;
+ ++bar_index)
{
- if (it->mSelfStart > mouse_time_offset)
+ TimerBar& bar = row.mBars[bar_index];
+ if (bar.mSelfStart > mouse_time_offset)
{
break;
}
- hover_bar = &(*it);
+ if (bar.mSelfEnd > mouse_time_offset)
+ {
+ hover_bar = &bar;
+ if (bar.mTimeBlock->getCollapsed())
+ {
+ // stop on first collapsed timeblock, since we can't select any children
+ break;
+ }
+ }
}
if (hover_bar)
{
mHoverID = hover_bar->mTimeBlock;
- mHoverTimer = mHoverID;
if (mHoverTimer != mHoverID)
{
// could be that existing tooltip is for a parent and is thus
@@ -300,7 +293,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
mHoverTimer = mHoverID;
mToolTipRect.set(mBarRect.mLeft + (hover_bar->mSelfStart / mTotalTimeDisplay) * mBarRect.getWidth(),
row.mTop,
- mBarRect.mLeft + (hover_bar->mSelfStart / mTotalTimeDisplay) * mBarRect.getWidth(),
+ mBarRect.mLeft + (hover_bar->mSelfEnd / mTotalTimeDisplay) * mBarRect.getWidth(),
row.mBottom);
}
}
@@ -324,7 +317,7 @@ static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicReco
if (history_index == 0)
{
// by default, show average number of call
- tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<F64, LLUnits::Milliseconds>(frame_recording.getPeriodMean(timer)).value(), (S32)frame_recording.getPeriodMean(timer.callCount()));
+ tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<F64, LLUnits::Milliseconds>(frame_recording.getPeriodMean (timer, RUNNING_AVERAGE_WIDTH)).value(), (S32)frame_recording.getPeriodMean(timer.callCount(), RUNNING_AVERAGE_WIDTH));
}
else
{
@@ -397,22 +390,34 @@ void LLFastTimerView::draw()
mTimerBarRows.push_front(TimerBarRow());
}
+ mDisplayMode = llclamp(getChild<LLComboBox>("time_scale_combo")->getCurrentIndex(), 0, 3);
+ mDisplayType = (EDisplayType)llclamp(getChild<LLComboBox>("metric_combo")->getCurrentIndex(), 0, 2);
+
generateUniqueColors();
+ LLView::drawChildren();
+ //getChild<LLLayoutStack>("timer_bars_stack")->updateLayout();
+ //getChild<LLLayoutStack>("legend_stack")->updateLayout();
+ LLView* bars_panel = getChildView("bars_panel");
+ bars_panel->localRectToOtherView(bars_panel->getLocalRect(), &mBarRect, this);
+
+ LLView* lines_panel = getChildView("lines_panel");
+ lines_panel->localRectToOtherView(lines_panel->getLocalRect(), &mGraphRect, this);
+
+ LLView* legend_panel = getChildView("legend");
+ legend_panel->localRectToOtherView(legend_panel->getLocalRect(), &mLegendRect, this);
+
// Draw the window background
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gl_rect_2d(getLocalRect(), LLColor4(0.f, 0.f, 0.f, 0.25f));
- S32 y = drawHelp(getRect().getHeight() - MARGIN);
- drawLegend(y - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 2));
-
- // update rectangle that includes timer bars
- const S32 LEGEND_WIDTH = 220;
+ drawHelp(getRect().getHeight() - MARGIN);
+ drawLegend();
- mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8;
- mBarRect.mTop = y;
- mBarRect.mRight = getRect().getWidth() - MARGIN;
- mBarRect.mBottom = MARGIN + LINE_GRAPH_HEIGHT;
+ //mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8;
+ //mBarRect.mTop = y;
+ //mBarRect.mRight = getRect().getWidth() - MARGIN;
+ //mBarRect.mBottom = MARGIN + LINE_GRAPH_HEIGHT;
drawBars();
drawLineGraph();
@@ -433,7 +438,8 @@ void LLFastTimerView::onOpen(const LLSD& key)
it != end_it;
++it)
{
- it->mBars.clear();
+ delete []it->mBars;
+ it->mBars = NULL;
}
}
@@ -993,7 +999,7 @@ void LLFastTimerView::printLineStats()
LLUnit<F32, LLUnits::Seconds> ticks;
if (mStatsIndex == 0)
{
- ticks = mRecording.getPeriodMean(*idp);
+ ticks = mRecording.getPeriodMean(*idp, RUNNING_AVERAGE_WIDTH);
}
else
{
@@ -1019,8 +1025,6 @@ void LLFastTimerView::drawLineGraph()
{
LLFastTimer _(FTM_DRAW_LINE_GRAPH);
//draw line graph history
- S32 x = mBarRect.mLeft;
- S32 y = LINE_GRAPH_HEIGHT;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLLocalClipRect clip(mGraphRect);
@@ -1029,21 +1033,6 @@ void LLFastTimerView::drawLineGraph()
static U32 max_calls = 0;
static F32 alpha_interp = 0.f;
- //display y-axis range
- std::string axis_label;
- if (mDisplayCalls)
- axis_label = llformat("%d calls", (int)max_calls);
- else if (mDisplayHz)
- axis_label = llformat("%d Hz", (int)(1.f / max_time.value()));
- else
- axis_label = llformat("%4.2f ms", LLUnit<F32, LLUnits::Milliseconds>(max_time).value());
-
- x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(axis_label)-5;
- y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight();
-
- LLFontGL::getFontMonospace()->renderUTF8(axis_label, 0, x, y, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::TOP);
-
//highlight visible range
{
S32 first_frame = mRecording.getNumRecordedPeriods() - mScrollIndex;
@@ -1059,7 +1048,7 @@ void LLFastTimerView::drawLineGraph()
if (mHoverBarIndex > 0)
{
- S32 bar_frame = first_frame - mHoverBarIndex - 1;
+ S32 bar_frame = first_frame - (mScrollIndex + mHoverBarIndex) - 1;
F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;
gGL.color4f(0.5f,0.5f,0.5f,1);
@@ -1090,6 +1079,7 @@ void LLFastTimerView::drawLineGraph()
const F32 * col = sTimerColors[idp->getIndex()].mV;// ft_display_table[idx].color->mV;
F32 alpha = 1.f;
+ bool is_hover_timer = true;
if (mHoverID != NULL &&
mHoverID != idp)
@@ -1097,11 +1087,15 @@ void LLFastTimerView::drawLineGraph()
if (idp->getParent() != mHoverID)
{
alpha = alpha_interp;
+ is_hover_timer = false;
}
}
gGL.color4f(col[0], col[1], col[2], alpha);
gGL.begin(LLRender::TRIANGLE_STRIP);
+ F32 call_scale_factor = (F32)mGraphRect.getHeight() / (F32)max_calls;
+ F32 time_scale_factor = (F32)mGraphRect.getHeight() / max_time.value();
+ F32 hz_scale_factor = (F32) mGraphRect.getHeight() / (1.f / max_time.value());
for (U32 j = mRecording.getNumRecordedPeriods();
j > 0;
j--)
@@ -1110,16 +1104,26 @@ void LLFastTimerView::drawLineGraph()
LLUnit<F32, LLUnits::Seconds> time = llmax(recording.getSum(*idp), LLUnit<F64, LLUnits::Seconds>(0.000001));
U32 calls = recording.getSum(idp->callCount());
- if (alpha == 1.f)
+ if (is_hover_timer)
{
//normalize to highlighted timer
cur_max = llmax(cur_max, time);
cur_max_calls = llmax(cur_max_calls, calls);
}
F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording.getNumRecordedPeriods()-1);
- F32 y = mDisplayHz
- ? mGraphRect.mBottom + (1.f / time.value()) * ((F32) mGraphRect.getHeight() / (1.f / max_time.value()))
- : mGraphRect.mBottom + time / max_time * (F32)mGraphRect.getHeight();
+ F32 y;
+ switch(mDisplayType)
+ {
+ case TIME:
+ y = mGraphRect.mBottom + time.value() * time_scale_factor;
+ break;
+ case CALLS:
+ y = mGraphRect.mBottom + (F32)calls * call_scale_factor;
+ break;
+ case HZ:
+ y = mGraphRect.mBottom + (1.f / time.value()) * hz_scale_factor;
+ break;
+ }
gGL.vertex2f(x,y);
gGL.vertex2f(x,mGraphRect.mBottom);
}
@@ -1140,7 +1144,7 @@ void LLFastTimerView::drawLineGraph()
//interpolate towards new maximum
max_time = lerp(max_time.value(), cur_max.value(), LLSmoothInterpolation::getInterpolant(0.1f));
- if (max_time - cur_max <= 1 || cur_max - max_time <= 1)
+ if (llabs((max_time - cur_max).value()) <= 1)
{
max_time = llmax(LLUnit<F32, LLUnits::Microseconds>(1), LLUnit<F32, LLUnits::Microseconds>(cur_max));
}
@@ -1159,8 +1163,8 @@ void LLFastTimerView::drawLineGraph()
if (mHoverID != NULL)
{
- x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
- y = mGraphRect.mBottom + 8;
+ S32 x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
+ S32 y = mGraphRect.mBottom + 8;
LLFontGL::getFontMonospace()->renderUTF8(
mHoverID->getName(),
@@ -1168,18 +1172,40 @@ void LLFastTimerView::drawLineGraph()
x, y,
LLColor4::white,
LLFontGL::LEFT, LLFontGL::BOTTOM);
- }
+ }
+
+ //display y-axis range
+ std::string axis_label;
+ switch(mDisplayType)
+ {
+ case TIME:
+ axis_label = llformat("%4.2f ms", LLUnit<F32, LLUnits::Milliseconds>(max_time).value());
+ break;
+ case CALLS:
+ axis_label = llformat("%d calls", (int)max_calls);
+ break;
+ case HZ:
+ axis_label = llformat("%4.2f Hz", max_time.value() ? 1.f / max_time.value() : 0.f);
+ break;
+ }
+
+ LLFontGL* font = LLFontGL::getFontMonospace();
+ S32 x = mGraphRect.mRight - font->getWidth(axis_label)-5;
+ S32 y = mGraphRect.mTop - font->getLineHeight();;
+
+ font->renderUTF8(axis_label, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
}
-void LLFastTimerView::drawLegend( S32 y )
+void LLFastTimerView::drawLegend()
{
// draw legend
S32 dx;
- S32 x = MARGIN;
+ S32 x = mLegendRect.mLeft;
+ S32 y = mLegendRect.mTop;
const S32 TEXT_HEIGHT = (S32)LLFontGL::getFontMonospace()->getLineHeight();
{
- LLLocalClipRect clip(LLRect(MARGIN, y, LEGEND_WIDTH, MARGIN));
+ LLLocalClipRect clip(mLegendRect);
S32 cur_line = 0;
ft_display_idx.clear();
std::map<TimeBlock*, S32> display_line;
@@ -1214,18 +1240,22 @@ void LLFastTimerView::drawLegend( S32 y )
}
else
{
- ms = LLUnit<F64, LLUnits::Seconds>(mRecording.getPeriodMean(*idp));
- calls = (S32)mRecording.getPeriodMean(idp->callCount());
+ ms = LLUnit<F64, LLUnits::Seconds>(mRecording.getPeriodMean(*idp, RUNNING_AVERAGE_WIDTH));
+ calls = (S32)mRecording.getPeriodMean(idp->callCount(), RUNNING_AVERAGE_WIDTH);
}
std::string timer_label;
- if (mDisplayCalls)
- {
- timer_label = llformat("%s (%d)",idp->getName().c_str(),calls);
- }
- else
+ switch(mDisplayType)
{
+ case TIME:
timer_label = llformat("%s [%.1f]",idp->getName().c_str(),ms.value());
+ break;
+ case CALLS:
+ timer_label = llformat("%s (%d)",idp->getName().c_str(),calls);
+ break;
+ case HZ:
+ timer_label = llformat("%.1f", ms.value() ? (1.f / ms.value()) : 0.f);
+ break;
}
dx = (TEXT_HEIGHT+4) + get_depth(idp)*8;
@@ -1300,36 +1330,16 @@ void LLFastTimerView::generateUniqueColors()
}
}
-S32 LLFastTimerView::drawHelp( S32 y )
+void LLFastTimerView::drawHelp( S32 y )
{
// Draw some help
const S32 texth = (S32)LLFontGL::getFontMonospace()->getLineHeight();
- char modedesc[][32] = {
- "2 x Average ",
- "Max ",
- "Recent Max ",
- "100 ms "
- };
- char centerdesc[][32] = {
- "Left ",
- "Centered ",
- "Ordered "
- };
-
- std::string text;
- text = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-
y -= (texth + 2);
- text = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
y -= (texth + 2);
- LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"),
+ LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts]"),
0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
- y -= (texth + 2);
- return y;
}
void LLFastTimerView::drawTicks()
@@ -1392,7 +1402,7 @@ void LLFastTimerView::drawBorders( S32 y, const S32 x_start, S32 bar_height, S32
by = LINE_GRAPH_HEIGHT-dy;
//line graph
- mGraphRect = LLRect(x_start-5, by, getRect().getWidth()-5, 5);
+ //mGraphRect = LLRect(x_start-5, by, getRect().getWidth()-5, 5);
gl_rect_2d(mGraphRect, FALSE);
}
@@ -1403,7 +1413,7 @@ void LLFastTimerView::updateTotalTime()
switch(mDisplayMode)
{
case 0:
- mTotalTimeDisplay = mRecording.getPeriodMean(FTM_FRAME, 100)*2;
+ mTotalTimeDisplay = mRecording.getPeriodMean(FTM_FRAME, RUNNING_AVERAGE_WIDTH)*2;
break;
case 1:
mTotalTimeDisplay = mRecording.getPeriodMax(FTM_FRAME);
@@ -1447,18 +1457,27 @@ void LLFastTimerView::drawBars()
const S32 histmax = (S32)mRecording.getNumRecordedPeriods();
// update widths
- updateTimerBarWidths(&FTM_FRAME, mAverageTimerRow, -1);
- updateTimerBarOffsets(&FTM_FRAME, mAverageTimerRow);
-
- for (S32 history_index = 1; history_index <= histmax; history_index++)
+ if (!mPauseHistory)
{
- llassert(history_index <= mTimerBarRows.size());
- TimerBarRow& row = mTimerBarRows[history_index - 1];
- if (row.mBars.empty())
+ U32 bar_index = 0;
+ if (!mAverageTimerRow.mBars)
{
- row.mBars.reserve(LLInstanceTracker<LLTrace::TimeBlock>::instanceCount());
- updateTimerBarWidths(&FTM_FRAME, row, history_index);
- updateTimerBarOffsets(&FTM_FRAME, row);
+ mAverageTimerRow.mBars = new TimerBar[LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()];
+ }
+ updateTimerBarWidths(&FTM_FRAME, mAverageTimerRow, -1, bar_index);
+ updateTimerBarOffsets(&FTM_FRAME, mAverageTimerRow);
+
+ for (S32 history_index = 1; history_index <= histmax; history_index++)
+ {
+ llassert(history_index <= mTimerBarRows.size());
+ TimerBarRow& row = mTimerBarRows[history_index - 1];
+ bar_index = 0;
+ if (!row.mBars)
+ {
+ row.mBars = new TimerBar[LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()];
+ updateTimerBarWidths(&FTM_FRAME, row, history_index, bar_index);
+ updateTimerBarOffsets(&FTM_FRAME, row);
+ }
}
}
@@ -1492,32 +1511,28 @@ void LLFastTimerView::drawBars()
static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths");
-LLUnit<F32, LLUnits::Seconds> LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, bool visible)
+LLUnit<F32, LLUnits::Seconds> LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, U32& bar_index)
{
LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS);
const LLUnit<F32, LLUnits::Seconds> self_time = history_index == -1
- ? mRecording.getPeriodMean(time_block->selfTime())
+ ? mRecording.getPeriodMean(time_block->selfTime(), RUNNING_AVERAGE_WIDTH)
: mRecording.getPrevRecording(history_index).getSum(time_block->selfTime());
LLUnit<F32, LLUnits::Seconds> full_time = self_time;
// reserve a spot for this bar to be rendered before its children
// even though we don't know its size yet
- std::vector<TimerBar>& bars = row.mBars;
- S32 bar_index = bars.size();
- bars.push_back(TimerBar());
+ TimerBar& timer_bar = row.mBars[bar_index];
+ bar_index++;
- const bool children_visible = visible && !time_block->getCollapsed();
for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it)
{
- full_time += updateTimerBarWidths(*it, row, history_index, children_visible);
+ full_time += updateTimerBarWidths(*it, row, history_index, bar_index);
}
- TimerBar& timer_bar = bars[bar_index];
timer_bar.mTotalTime = full_time;
timer_bar.mSelfTime = self_time;
timer_bar.mTimeBlock = time_block;
- timer_bar.mVisible = visible;
return full_time;
}
@@ -1528,21 +1543,16 @@ S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::TimeBlock* time_block, Timer
{
LLFastTimer _(FTM_UPDATE_TIMER_BAR_FRACTIONS);
- std::vector<TimerBar>& bars = row.mBars;
- llassert(timer_bar_index < bars.size());
- TimerBar& timer_bar = bars[timer_bar_index];
- const LLUnit<F32, LLUnits::Seconds> child_time_width = timer_bar.mTotalTime - timer_bar.mSelfTime;
- timer_bar.mChildrenStart = timer_bar.mSelfStart;
+ TimerBar& timer_bar = row.mBars[timer_bar_index];
+ const LLUnit<F32, LLUnits::Seconds> bar_time = timer_bar.mTotalTime - timer_bar.mSelfTime;
+ timer_bar.mChildrenStart = timer_bar.mSelfStart + timer_bar.mSelfTime / 2;
+ timer_bar.mChildrenEnd = timer_bar.mChildrenStart + timer_bar.mTotalTime - timer_bar.mSelfTime;
- if (mDisplayCenter == ALIGN_CENTER)
+ if (timer_bar_index == 0)
{
- timer_bar.mChildrenStart += timer_bar.mSelfTime / 2;
+ timer_bar.mSelfStart = 0.f;
+ timer_bar.mSelfEnd = bar_time;
}
- else if (mDisplayCenter == ALIGN_RIGHT)
- {
- timer_bar.mChildrenStart += timer_bar.mSelfTime;
- }
- timer_bar.mChildrenEnd = timer_bar.mChildrenStart + timer_bar.mTotalTime - timer_bar.mSelfTime;
//now loop through children and figure out portion of bar image covered by each bar, now that we know the
//sum of all children
@@ -1556,8 +1566,7 @@ S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::TimeBlock* time_block, Timer
{
timer_bar_index++;
- llassert(timer_bar_index < bars.size());
- TimerBar& child_timer_bar = bars[timer_bar_index];
+ TimerBar& child_timer_bar = row.mBars[timer_bar_index];
TimeBlock* child_time_block = *it;
if (last_child_timer_bar)
@@ -1574,15 +1583,15 @@ S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::TimeBlock* time_block, Timer
}
child_timer_bar.mStartFraction = bar_fraction_start;
- child_timer_bar.mEndFraction = child_time_width > 0
- ? bar_fraction_start + child_timer_bar.mTotalTime / child_time_width
+ child_timer_bar.mEndFraction = bar_time > 0
+ ? bar_fraction_start + child_timer_bar.mTotalTime / bar_time
: 1.f;
- child_timer_bar.mSelfStart = timer_bar.mChildrenStart
- + child_timer_bar.mStartFraction
- * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart);
- child_timer_bar.mSelfEnd = timer_bar.mChildrenStart
- + child_timer_bar.mEndFraction
- * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart);
+ child_timer_bar.mSelfStart = timer_bar.mChildrenStart
+ + child_timer_bar.mStartFraction
+ * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart);
+ child_timer_bar.mSelfEnd = timer_bar.mChildrenStart
+ + child_timer_bar.mEndFraction
+ * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart);
timer_bar_index = updateTimerBarOffsets(child_time_block, row, timer_bar_index);
@@ -1591,16 +1600,15 @@ S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::TimeBlock* time_block, Timer
return timer_bar_index;
}
-S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, S32 bar_index)
+S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, bool visible, S32 bar_index)
{
- llassert(bar_index < row.mBars.size());
TimerBar& timer_bar = row.mBars[bar_index];
LLTrace::TimeBlock* time_block = timer_bar.mTimeBlock;
hovered |= mHoverID == time_block;
// animate scale of bar when hovering over that particular timer
- if ((F32)bar_rect.getWidth() * (timer_bar.mEndFraction - timer_bar.mStartFraction) > 2.f)
+ if (visible && (F32)bar_rect.getWidth() * (timer_bar.mEndFraction - timer_bar.mStartFraction) > 2.f)
{
LLRect render_rect(bar_rect);
S32 scale_offset = 0;
@@ -1637,15 +1645,17 @@ S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width,
children_rect.mBottom = bar_rect.mBottom;
}
+ bool children_visible = visible && !time_block->getCollapsed();
+
bar_index++;
- const U32 num_bars = row.mBars.size();
+ const U32 num_bars = LLInstanceTracker<LLTrace::TimeBlock>::instanceCount();
if (bar_index < num_bars && row.mBars[bar_index].mFirstChild)
{
bool is_last = false;
do
{
is_last = row.mBars[bar_index].mLastChild;
- bar_index = drawBar(children_rect, row, image_width, image_height, hovered, bar_index);
+ bar_index = drawBar(children_rect, row, image_width, image_height, hovered, children_visible, bar_index);
}
while(!is_last && bar_index < num_bars);
}
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index d9ae6348da..d931f25a7e 100755
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -68,8 +68,8 @@ private:
virtual void onClickCloseBtn();
void drawTicks();
void drawLineGraph();
- void drawLegend(S32 y);
- S32 drawHelp(S32 y);
+ void drawLegend();
+ void drawHelp(S32 y);
void drawBorders( S32 y, const S32 x_start, S32 barh, S32 dy);
void drawBars();
@@ -82,7 +82,6 @@ private:
TimerBar()
: mTotalTime(0),
mSelfTime(0),
- mVisible(true),
mStartFraction(0.f),
mEndFraction(1.f),
mFirstChild(false),
@@ -104,29 +103,26 @@ private:
struct TimerBarRow
{
- S32 mBottom,
- mTop;
- std::vector<TimerBar> mBars;
+ S32 mBottom,
+ mTop;
+ TimerBar* mBars;
};
- LLUnit<F32, LLUnits::Seconds> updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, bool visible = true);
+ LLUnit<F32, LLUnits::Seconds> updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, U32& bar_index);
S32 updateTimerBarOffsets(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 timer_bar_index = 0);
- S32 drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered = false, S32 bar_index = 0);
+ S32 drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered = false, bool visible = true, S32 bar_index = 0);
void setPauseState(bool pause_state);
std::deque<TimerBarRow> mTimerBarRows;
TimerBarRow mAverageTimerRow;
- enum ChildAlignment
+ enum EDisplayType
{
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_COUNT
- } mDisplayCenter;
- bool mDisplayCalls,
- mDisplayHz,
- mPauseHistory;
+ TIME,
+ CALLS,
+ HZ
+ } mDisplayType;
+ bool mPauseHistory;
LLUnit<F64, LLUnits::Seconds> mAllTimeMax,
mTotalTimeDisplay;
S32 mScrollIndex,
@@ -137,7 +133,8 @@ private:
LLTrace::TimeBlock* mHoverTimer;
LLRect mToolTipRect,
mGraphRect,
- mBarRect;
+ mBarRect,
+ mLegendRect;
LLFrameTimer mHighlightTimer;
LLTrace::PeriodicRecording mRecording;
};
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index 77adb5524e..671f116df3 100755
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -16,6 +16,27 @@
width="700">
<string name="pause" >Pause</string>
<string name="run">Run</string>
+ <combo_box name="time_scale_combo"
+ follows="left|top"
+ left="10"
+ top="5"
+ width="150"
+ height="20">
+ <item label="2x Average"/>
+ <item label="Max"/>
+ <item label="Recent Max"/>
+ <item label="100ms"/>
+ </combo_box>
+ <combo_box name="metric_combo"
+ follows="left|top"
+ left_pad="10"
+ top="5"
+ width="150"
+ height="20">
+ <item label="Time"/>
+ <item label="Number of Calls"/>
+ <item label="Hz"/>
+ </combo_box>
<button follows="top|right"
name="pause_btn"
left="-200"
@@ -24,4 +45,52 @@
height="40"
label="Pause"
font="SansSerifHuge"/>
+ <layout_stack name="legend_stack"
+ orientation="horizontal"
+ left="0"
+ top="50"
+ right="695"
+ bottom="500"
+ follows="all">
+ <layout_panel name="legend_panel"
+ auto_resize="false"
+ user_resize="true"
+ width="220"
+ height="450"
+ min_width="100">
+ <panel top="0"
+ left="0"
+ width="220"
+ height="440"
+ name="legend"
+ follows="all"/>
+ </layout_panel>
+ <layout_panel name="timers_panel"
+ auto_resize="true"
+ user_resize="true"
+ height="450"
+ width="475"
+ min_width="100">
+ <layout_stack name="timer_bars_stack"
+ orientation="vertical"
+ left="0"
+ top="0"
+ width="475"
+ height="445"
+ follows="all">
+ <layout_panel name="bars_panel"
+ auto_resize="true"
+ user_resize="true"
+ top="0"
+ width="475"
+ height="210"/>
+ <layout_panel name="lines_panel"
+ auto_resize="false"
+ user_resize="true"
+ width="475"
+ min_height="50"
+ height="240"/>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</floater>