diff options
-rw-r--r-- | indra/llcommon/llfasttimer.cpp | 7 | ||||
-rw-r--r-- | indra/llcommon/lltrace.h | 18 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 10 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.h | 11 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.cpp | 33 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.h | 12 | ||||
-rw-r--r-- | indra/newview/llfasttimerview.cpp | 245 | ||||
-rw-r--r-- | indra/newview/llfasttimerview.h | 19 |
8 files changed, 193 insertions, 162 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index a144a8c94e..e58c5c0f98 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -425,6 +425,13 @@ void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other ) mTotalTimeCounter = 0; mChildTimeCounter = 0; mCalls = 0; + if (other) + { + mLastCaller = other->mLastCaller; + mActiveCount = other->mActiveCount; + mMoveUpTree = other->mMoveUpTree; + mParent = other->mParent; + } } } // namespace LLTrace diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0f927bad53..c38e92962b 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -243,8 +243,6 @@ namespace LLTrace : public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string> { public: - typedef typename MeanValueType<TraceType<ACCUMULATOR> >::type mean_t; - TraceType(const char* name, const char* description = NULL) : LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name), mName(name), @@ -468,7 +466,6 @@ namespace LLTrace : public TraceType<TimeBlockAccumulator> { public: - typedef F32 mean_t; TraceType(const char* name, const char* description = "") : TraceType<TimeBlockAccumulator>(name, description) @@ -476,17 +473,30 @@ namespace LLTrace }; template<> + struct MeanValueType<TraceType<TimeBlockAccumulator::CallCountAspect> > + { + typedef F64 type; + }; + + + template<> class TraceType<TimeBlockAccumulator::SelfTimeAspect> : public TraceType<TimeBlockAccumulator> { public: - typedef F32 mean_t; TraceType(const char* name, const char* description = "") : TraceType<TimeBlockAccumulator>(name, description) {} }; + template<> + struct MeanValueType<TraceType<TimeBlockAccumulator::SelfTimeAspect> > + { + typedef LLUnit<LLUnits::Seconds, F64> type; + }; + + class TimeBlock; class TimeBlockTreeNode { diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 913c4cbdad..737b95cdd5 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -109,8 +109,18 @@ void Recording::handleSplitTo(Recording& other) { stop(); other.restart(); + syncTo(other); +} + +void Recording::syncTo(Recording& other) +{ + other.mCountsFloat.write()->reset(mCountsFloat); other.mMeasurementsFloat.write()->reset(mMeasurementsFloat); + other.mCounts.write()->reset(mCounts); other.mMeasurements.write()->reset(mMeasurements); + other.mStackTimers.write()->reset(mStackTimers); + other.mMemStats.write()->reset(mMemStats); + //TODO: figure out how to get seamless handoff of timing stats } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index f575fbd8b2..af9ba02b29 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -119,6 +119,7 @@ namespace LLTrace // gather data from recording, ignoring time relationship (for example, pulling data from slave threads) void mergeRecording(const Recording& other); + // grab latest recorded data void update(); // Timer accessors @@ -217,6 +218,8 @@ namespace LLTrace LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); } + void syncTo(Recording& other); + private: friend class ThreadRecorder; @@ -337,9 +340,9 @@ namespace LLTrace } template <typename T> - typename TraceType<T>::mean_t getPeriodMean(const TraceType<T>& stat) const + typename MeanValueType<TraceType<T> >::type getPeriodMean(const TraceType<T>& stat) const { - typename TraceType<T>::mean_t mean = 0.0; + typename MeanValueType<TraceType<T> >::type mean = 0.0; for (S32 i = 0; i < mNumPeriods; i++) { if (mRecordingPeriods[i].getDuration() > 0.f) @@ -352,9 +355,9 @@ namespace LLTrace } template <typename T> - typename TraceType<T>::mean_t getPeriodMeanPerSec(const TraceType<T>& stat) const + typename MeanValueType<TraceType<T> >::type getPeriodMeanPerSec(const TraceType<T>& stat) const { - typename TraceType<T>::mean_t mean = 0.0; + typename MeanValueType<TraceType<T> >::type mean = 0.0; for (S32 i = 0; i < mNumPeriods; i++) { if (mRecordingPeriods[i].getDuration() > 0.f) diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7b493a651e..113febcca8 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -76,7 +76,7 @@ ThreadRecorder::~ThreadRecorder() while(mActiveRecordings.size()) { - mActiveRecordings.front().mTargetRecording->stop(); + mActiveRecordings.front()->mTargetRecording->stop(); } set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; @@ -94,31 +94,37 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) void ThreadRecorder::activate( Recording* recording ) { - mActiveRecordings.push_front(ActiveRecording(recording)); - mActiveRecordings.front().mBaseline.makePrimary(); + ActiveRecording* active_recording = new ActiveRecording(recording); + if (!mActiveRecordings.empty()) + { + mActiveRecordings.front()->mBaseline.syncTo(active_recording->mBaseline); + } + mActiveRecordings.push_front(active_recording); + + mActiveRecordings.front()->mBaseline.makePrimary(); } -std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Recording* recording ) +ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording ) { - std::list<ActiveRecording>::iterator it, end_it; + active_recording_list_t::iterator it, end_it; for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); it != end_it; ++it) { - std::list<ActiveRecording>::iterator next_it = it; + active_recording_list_t::iterator next_it = it; ++next_it; // if we have another recording further down in the stack... if (next_it != mActiveRecordings.end()) { // ...push our gathered data down to it - next_it->mBaseline.appendRecording(it->mBaseline); + (*next_it)->mBaseline.appendRecording((*it)->mBaseline); } // copy accumulated measurements into result buffer and clear accumulator (mBaseline) - it->moveBaselineToTarget(); + (*it)->moveBaselineToTarget(); - if (it->mTargetRecording == recording) + if ((*it)->mTargetRecording == recording) { // found the recording, so return it break; @@ -142,17 +148,18 @@ AccumulatorBuffer<MemStatAccumulator> gMemStats; void ThreadRecorder::deactivate( Recording* recording ) { - std::list<ActiveRecording>::iterator it = update(recording); + active_recording_list_t::iterator it = update(recording); if (it != mActiveRecordings.end()) { // and if we've found the recording we wanted to update - std::list<ActiveRecording>::iterator next_it = it; + active_recording_list_t::iterator next_it = it; ++next_it; if (next_it != mActiveRecordings.end()) { - next_it->mTargetRecording->makePrimary(); + (*next_it)->mTargetRecording->makePrimary(); } + delete *it; mActiveRecordings.erase(it); } } @@ -244,7 +251,7 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLMutexLock lock(&mSlaveListMutex); - Recording& target_recording = mActiveRecordings.front().mBaseline; + Recording& target_recording = mActiveRecordings.front()->mBaseline; for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index 337035974c..0e6c091900 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -39,13 +39,14 @@ namespace LLTrace { protected: struct ActiveRecording; + typedef std::list<ActiveRecording*> active_recording_list_t; public: ThreadRecorder(); virtual ~ThreadRecorder(); void activate(Recording* recording); - std::list<struct ActiveRecording>::iterator update(Recording* recording); + active_recording_list_t::iterator update(Recording* recording); void deactivate(Recording* recording); virtual void pushToMaster() = 0; @@ -63,11 +64,12 @@ namespace LLTrace void moveBaselineToTarget(); }; Recording mThreadRecording; - std::list<ActiveRecording> mActiveRecordings; - class BlockTimer* mRootTimer; - TimeBlockTreeNode* mTimeBlockTreeNodes; - size_t mNumTimeBlockTreeNodes; + active_recording_list_t mActiveRecordings; + + class BlockTimer* mRootTimer; + TimeBlockTreeNode* mTimeBlockTreeNodes; + size_t mNumTimeBlockTreeNodes; }; class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 7858378f00..948b6f8e89 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -107,7 +107,7 @@ LLFastTimerView::LLFastTimerView(const LLSD& key) mRecording(&get_frame_recording()), mPauseHistory(false) { - mBarRects = new std::vector<LLRect>[MAX_VISIBLE_HISTORY + 1]; + mTimerBars = new std::vector<TimerBar>[MAX_VISIBLE_HISTORY + 1]; } LLFastTimerView::~LLFastTimerView() @@ -117,7 +117,7 @@ LLFastTimerView::~LLFastTimerView() delete mRecording; } mRecording = NULL; - delete [] mBarRects; + delete [] mTimerBars; } void LLFastTimerView::onPause() @@ -282,7 +282,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) ++it, ++i) { // is mouse over bar for this timer? - if (mBarRects[mHoverBarIndex][i].pointInRect(x, y)) + if (mTimerBars[mHoverBarIndex][i].mRect.pointInRect(x, y)) { mHoverID = (*it); if (mHoverTimer != *it) @@ -294,7 +294,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) mHoverTimer = (*it); } - mToolTipRect = mBarRects[mHoverBarIndex][i]; + mToolTipRect = mTimerBars[mHoverBarIndex][i].mRect; } if ((*it)->getCollapsed()) @@ -1311,11 +1311,11 @@ S32 LLFastTimerView::drawHelp( S32 y ) } return y; } -void LLFastTimerView::drawTicks( LLUnit<LLUnits::Seconds, F64> total_time ) +void LLFastTimerView::drawTicks() { // Draw MS ticks { - LLUnit<LLUnits::Milliseconds, U32> ms = total_time; + LLUnit<LLUnits::Milliseconds, U32> ms = mTotalTimeDisplay; std::string tick_label; S32 x; S32 barw = mBarRect.getWidth(); @@ -1377,187 +1377,170 @@ void LLFastTimerView::drawBorders( S32 y, const S32 x_start, S32 bar_height, S32 } } -LLUnit<LLUnits::Seconds, F64> LLFastTimerView::getTotalTime() +void LLFastTimerView::updateTotalTime() { - LLUnit<LLUnits::Seconds, F64> total_time; switch(mDisplayMode) { case 0: - total_time = mRecording->getPeriodMean(FTM_FRAME)*2; + mTotalTimeDisplay = mRecording->getPeriodMean(FTM_FRAME)*2; break; case 1: - total_time = mAllTimeMax; + mTotalTimeDisplay = mAllTimeMax; break; case 2: // Calculate the max total ticks for the current history - total_time = mRecording->getPeriodMax(FTM_FRAME); + mTotalTimeDisplay = mRecording->getPeriodMax(FTM_FRAME); break; default: - total_time = LLUnit<LLUnits::Milliseconds, F32>(100); + mTotalTimeDisplay = LLUnit<LLUnits::Milliseconds, F32>(100); break; } - return total_time; } void LLFastTimerView::drawBars() { - LLUnit<LLUnits::Seconds, F64> total_time = getTotalTime(); - if (total_time <= 0.0) return; + updateTotalTime(); + if (mTotalTimeDisplay <= 0.0) return; - LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square"); LLLocalClipRect clip(mBarRect); S32 bar_height = (mBarRect.mTop - MARGIN - LINE_GRAPH_HEIGHT) / (MAX_VISIBLE_HISTORY + 2); S32 vpad = llmax(1, bar_height / 4); // spacing between bars bar_height -= vpad; - drawTicks(total_time); + drawTicks(); S32 y = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); drawBorders(y, mBarRect.mLeft, bar_height, vpad); // Draw bars for each history entry // Special: -1 = show running average - gGL.getTexUnit(0)->bind(box_imagep->getImage()); + LLPointer<LLUIImage> bar_image = LLUI::getUIImage("Rounded_Square"); + gGL.getTexUnit(0)->bind(bar_image->getImage()); const S32 histmax = llmin(mRecording->getNumPeriods()+1, MAX_VISIBLE_HISTORY); for (S32 j = -1; j < histmax && y > LINE_GRAPH_HEIGHT; j++) { - mBarRects[llmax(j, 0)].clear(); - int sublevel_dx[FTV_MAX_DEPTH]; - int sublevel_left[FTV_MAX_DEPTH]; - int sublevel_right[FTV_MAX_DEPTH]; - S32 tidx = (j >= 0) + S32 history_index = (j >= 0) ? j + 1 + mScrollIndex : -1; + S32 rect_index = llmax(j, 0); + mTimerBars[rect_index].clear(); - // draw the bars for each stat - std::vector<S32> xpos; - S32 deltax = 0; - xpos.push_back(mBarRect.mLeft); + updateTimerBars(&FTM_FRAME, LLRect(mBarRect.mLeft, 0, mBarRect.mRight, -bar_height), mTimerBars[rect_index], history_index); - TimeBlock* prev_id = NULL; - - S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); - it != end_timer_tree(); - ++it, ++i) + for (std::vector<TimerBar>::iterator it = mTimerBars[rect_index].begin(), end_it = mTimerBars[rect_index].end(); + it != end_it; + ++it) { - TimeBlock* idp = (*it); - F32 frac = tidx == -1 - ? (mRecording->getPeriodMean(*idp) / total_time) - : (mRecording->getPrevRecordingPeriod(tidx).getSum(*idp).value() / total_time.value()); - - S32 dx = llround(frac * (F32)mBarRect.getWidth()); - S32 prev_delta_x = deltax; - deltax = dx; - - const int level = get_depth(idp) - 1; - while ((S32)xpos.size() > level + 1) - { - xpos.pop_back(); - } - - LLRect bar_rect; - bar_rect.setLeftTopAndSize(xpos.back(), y, dx, bar_height); - mBarRects[llmax(j, 0)].push_back(bar_rect); - - if (level == 0) - { - sublevel_left[level] = mBarRect.mLeft; - sublevel_dx[level] = dx; - sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; - } - else if (prev_id && get_depth(prev_id) < get_depth(idp)) - { - F64 sublevelticks = 0; - - for (TimeBlock::child_const_iter it = prev_id->beginChildren(); - it != prev_id->endChildren(); - ++it) - { - sublevelticks += (tidx == -1) - ? mRecording->getPeriodMean(**it).value() - : mRecording->getPrevRecordingPeriod(tidx).getSum(**it).value(); - } - - F32 subfrac = (F32)sublevelticks / (F32)total_time.value(); - sublevel_dx[level] = (int)(subfrac * (F32)mBarRect.getWidth() + .5f); + TimerBar& timer_bar = *it; + gGL.color4fv(timer_bar.mColor.mV); + gl_segmented_rect_2d_fragment_tex(timer_bar.mRect.mLeft, timer_bar.mRect.mTop, timer_bar.mRect.mRight, timer_bar.mRect.mBottom, + bar_image->getTextureWidth(), bar_image->getTextureHeight(), + 16, + timer_bar.mStartFraction, timer_bar.mEndFraction); - if (mDisplayCenter == ALIGN_CENTER) - { - bar_rect.mLeft += (prev_delta_x - sublevel_dx[level])/2; - } - else if (mDisplayCenter == ALIGN_RIGHT) - { - bar_rect.mLeft += (prev_delta_x - sublevel_dx[level]); - } - - sublevel_left[level] = bar_rect.mLeft; - sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; - } + } + + y -= (bar_height + vpad); + if (j < 0) + y -= bar_height; + } + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +} - xpos.back() = bar_rect.mRight; - xpos.push_back(bar_rect.mLeft); +LLRect LLFastTimerView::updateTimerBars(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 history_index) +{ + F32 self_time_frame_fraction = history_index == -1 + ? (mRecording->getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay) + : (mRecording->getPrevRecordingPeriod(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); - if (bar_rect.getWidth() > 0) - { - LLColor4 color = sTimerColors[idp]; - S32 scale_offset = 0; + S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); + LLRect child_rect = bar_rect; - BOOL is_child_of_hover_item = (idp == mHoverID); - TimeBlock* next_parent = idp->getParent(); - while(!is_child_of_hover_item && next_parent) - { - is_child_of_hover_item = (mHoverID == next_parent); - if (next_parent->getParent() == next_parent) break; - next_parent = next_parent->getParent(); - } + if (mDisplayCenter == ALIGN_CENTER) + { + child_rect.mLeft += self_time_width / 2; + self_time_width -= self_time_width / 2; + } + else if (mDisplayCenter == ALIGN_RIGHT) + { + child_rect.mLeft += self_time_width; + self_time_width = 0; + } - if (idp == mHoverID) - { - scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); - //color = lerp(color, LLColor4::black, -0.4f); - } - else if (mHoverID != NULL && !is_child_of_hover_item) - { - color = lerp(color, LLColor4::grey, 0.8f); - } + if (child_rect.getHeight() > 3) + { + child_rect.mTop -= 1; + child_rect.mBottom += 1; + } + child_rect.mRight = child_rect.mLeft; - gGL.color4fv(color.mV); - F32 start_fragment = llclamp((F32)(bar_rect.mLeft - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); - F32 end_fragment = llclamp((F32)(bar_rect.mRight - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); - gl_segmented_rect_2d_fragment_tex( - sublevel_left[level], - bar_rect.mTop - level + scale_offset, - sublevel_right[level], - bar_rect.mBottom + level - scale_offset, - box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), - 16, - start_fragment, end_fragment); - } + // reserve a spot for this bar to be rendered before its children + // even though we don't know its size yet + S32 first_child_left = child_rect.mLeft; + S32 bar_rect_index = bars.size(); + bars.push_back(TimerBar()); - if ((*it)->getCollapsed()) - { - it.skipDescendants(); - } + for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) + { + child_rect = updateTimerBars(*it, child_rect, bars, history_index); - prev_id = idp; - } - y -= (bar_height + vpad); - if (j < 0) - y -= bar_height; + // advance for next child + child_rect.mLeft = child_rect.mRight; } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -} + // now loop through children and figure out portion of bar image covered by each bar, now that we know the + // sum of all children + //S32 total_width_children = child_rect.mRight - first_child_left; + //S32 child_bar_index = bar_rect_index + 1; + //F32 bar_fraction_start = 0.f; + //for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); + // it != end_it; + // ++it) + //{ + // TimerBar& child_timer_bar = bars[child_bar_index]; + // child_timer_bar.mStartFraction = bar_fraction_start; + // child_timer_bar.mEndFraction = (F32)child_timer_bar.mRect.getWidth() / (F32)total_width_children; + // bar_fraction_start = child_timer_bar.mEndFraction; + // // advance for next child + // child_bar_index++; + //} + bar_rect.mRight = child_rect.mRight + self_time_width; + if (bar_rect.getWidth() > 0) + { + LLColor4 color = sTimerColors[time_block]; + S32 scale_offset = 0; + BOOL is_child_of_hover_item = (time_block == mHoverID); + TimeBlock* next_parent = time_block->getParent(); + while(!is_child_of_hover_item && next_parent) + { + is_child_of_hover_item = (mHoverID == next_parent); + if (next_parent->getParent() == next_parent) break; + next_parent = next_parent->getParent(); + } + if (time_block == mHoverID) + { + scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); + } + else if (mHoverID != NULL && !is_child_of_hover_item) + { + color = lerp(color, LLColor4::grey, 0.8f); + } + bar_rect.mTop += scale_offset; + bar_rect.mBottom -= scale_offset; + bars[bar_rect_index].mRect = bar_rect; + bars[bar_rect_index].mColor = color; + } + return bar_rect; +} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 7eee3c1cb5..86781b626c 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -70,7 +70,7 @@ protected: virtual void onClickCloseBtn(); private: - void drawTicks(LLUnit<LLUnits::Seconds, F64> total_time); + void drawTicks(); void drawLineGraph(); void drawLegend(S32 y); S32 drawHelp(S32 y); @@ -79,10 +79,18 @@ private: void printLineStats(); void generateUniqueColors(); - LLUnit<LLUnits::Seconds, F64> getTotalTime(); + void updateTotalTime(); - - std::vector<LLRect>* mBarRects; + struct TimerBar + { + LLRect mRect; + LLColor4 mColor; + F32 mStartFraction, + mEndFraction; + }; + LLRect updateTimerBars(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 history_index); + + std::vector<TimerBar>* mTimerBars; S32 mDisplayMode; typedef enum child_alignment @@ -96,7 +104,8 @@ private: ChildAlignment mDisplayCenter; bool mDisplayCalls, mDisplayHz; - LLUnit<LLUnits::Seconds, F64> mAllTimeMax; + LLUnit<LLUnits::Seconds, F64> mAllTimeMax, + mTotalTimeDisplay; LLRect mBarRect; S32 mScrollIndex; LLTrace::TimeBlock* mHoverID; |