diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llfasttimer.cpp | 45 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer.h | 13 | ||||
| -rw-r--r-- | indra/llcommon/lltrace.h | 24 | ||||
| -rw-r--r-- | indra/llcommon/lltracerecording.cpp | 29 | ||||
| -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/llui/llui.cpp | 26 | ||||
| -rw-r--r-- | indra/llui/llui.h | 2 | ||||
| -rw-r--r-- | indra/newview/llfasttimerview.cpp | 424 | ||||
| -rw-r--r-- | indra/newview/llfasttimerview.h | 35 | 
11 files changed, 398 insertions, 256 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index a144a8c94e..0ea91d7e51 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -256,12 +256,16 @@ void TimeBlock::processTimes()  	while(cur_timer && cur_timer->mParentTimerData.mActiveTimer != cur_timer)  	{  		U64 cumulative_time_delta = cur_time - cur_timer->mStartTime; -	 -		accumulator->mTotalTimeCounter += cumulative_time_delta; -		accumulator->mChildTimeCounter += stack_record->mChildTime; +		U64 child_time = stack_record->mChildTime  +			- (accumulator->mSelfTimeCounter - cur_timer->mStartSelfTimeCounter) +			- (accumulator->mChildTimeCounter - cur_timer->mStartChildTimeCounter); +		accumulator->mChildTimeCounter += child_time; +		accumulator->mSelfTimeCounter += cumulative_time_delta - child_time;  		stack_record->mChildTime = 0;  		cur_timer->mStartTime = cur_time; +		cur_timer->mStartSelfTimeCounter = accumulator->mSelfTimeCounter; +		cur_timer->mStartChildTimeCounter = accumulator->mChildTimeCounter;  		stack_record = &cur_timer->mParentTimerData;  		accumulator = stack_record->mTimeBlock->getPrimaryAccumulator(); @@ -401,7 +405,9 @@ void TimeBlock::writeLog(std::ostream& os)  TimeBlockAccumulator::TimeBlockAccumulator()   :	mChildTimeCounter(0), -	mTotalTimeCounter(0), +	mSelfTimeCounter(0), +	mStartChildTimeCounter(0), +	mStartSelfTimeCounter(0),  	mCalls(0),  	mLastCaller(NULL),  	mActiveCount(0), @@ -411,8 +417,8 @@ TimeBlockAccumulator::TimeBlockAccumulator()  void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other )  { -	mChildTimeCounter += other.mChildTimeCounter; -	mTotalTimeCounter += other.mTotalTimeCounter; +	mChildTimeCounter += other.mChildTimeCounter - other.mStartChildTimeCounter; +	mSelfTimeCounter += other.mSelfTimeCounter - other.mStartSelfTimeCounter;  	mCalls += other.mCalls;  	mLastCaller = other.mLastCaller;  	mActiveCount = other.mActiveCount; @@ -422,9 +428,32 @@ void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other )  void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other )  { -	mTotalTimeCounter = 0; -	mChildTimeCounter = 0;  	mCalls = 0; +	if (other) +	{ +		mStartSelfTimeCounter = other->mSelfTimeCounter; +		mSelfTimeCounter = mStartSelfTimeCounter; +		mStartChildTimeCounter = other->mChildTimeCounter; +		mChildTimeCounter = mStartChildTimeCounter; + +		mLastCaller = other->mLastCaller; +		mActiveCount = other->mActiveCount; +		mMoveUpTree = other->mMoveUpTree; +		mParent = other->mParent; +	} +	else +	{ +		mStartSelfTimeCounter = mSelfTimeCounter; +		mStartChildTimeCounter = mChildTimeCounter; +	}  } +LLUnit<LLUnits::Seconds, F64> BlockTimer::getElapsedTime() +{ +	U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime; + +	return (F64)total_time / (F64)TimeBlock::countsPerSecond(); +} + +  } // namespace LLTrace diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 726db70fbe..28e54a37de 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -71,9 +71,13 @@ public:  	BlockTimer(TimeBlock& timer);  	~BlockTimer(); +	LLUnit<LLUnits::Seconds, F64> getElapsedTime(); +  private:  	U64						mStartTime; +	U64						mStartSelfTimeCounter; +	U64						mStartChildTimeCounter;  	BlockTimerStackRecord	mParentTimerData;  }; @@ -279,6 +283,8 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)  	BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists();  	TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();  	accumulator->mActiveCount++; +	mStartSelfTimeCounter = accumulator->mSelfTimeCounter; +	mStartChildTimeCounter = accumulator->mChildTimeCounter;  	// keep current parent as long as it is active when we are  	accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0); @@ -298,9 +304,12 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer()  	BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists();  	TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator(); +	U64 child_time = cur_timer_data->mChildTime  +					- (accumulator->mSelfTimeCounter - mStartSelfTimeCounter) +					- (accumulator->mChildTimeCounter - mStartChildTimeCounter);  	accumulator->mCalls++; -	accumulator->mChildTimeCounter += cur_timer_data->mChildTime; -	accumulator->mTotalTimeCounter += total_time; +	accumulator->mChildTimeCounter += child_time; +	accumulator->mSelfTimeCounter += total_time - cur_timer_data->mChildTime;  	accumulator->mActiveCount--;  	// store last caller to bootstrap tree creation diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 0f927bad53..8c3259eea9 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), @@ -446,8 +444,10 @@ namespace LLTrace  		//  		// members  		// -		U64							mChildTimeCounter, -									mTotalTimeCounter; +		U64							mStartChildTimeCounter, +									mStartSelfTimeCounter, +									mChildTimeCounter, +									mSelfTimeCounter;  		U32							mCalls;  		class TimeBlock*			mParent;		// last acknowledged parent of this time block  		class TimeBlock*			mLastCaller;	// used to bootstrap tree construction @@ -468,7 +468,6 @@ namespace LLTrace  	:	public TraceType<TimeBlockAccumulator>  	{  	public: -		typedef F32 mean_t;  		TraceType(const char* name, const char* description = "")  		:	TraceType<TimeBlockAccumulator>(name, description) @@ -476,17 +475,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..2af9041863 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -109,9 +109,17 @@ 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); -	//TODO: figure out how to get seamless handoff of timing stats +	other.mStackTimers.write()->reset(mStackTimers); +	other.mMemStats.write()->reset(mMemStats);  }  void Recording::makePrimary() @@ -174,12 +182,15 @@ void Recording::mergeRecording( const Recording& other)  LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat) const  { -	return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / (F64)LLTrace::TimeBlock::countsPerSecond(); +	const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; +	return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter + accumulator.mChildTimeCounter - accumulator.mStartChildTimeCounter)  +				/ (F64)LLTrace::TimeBlock::countsPerSecond();  }  LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const  { -	return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond(); +	const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; +	return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond();  } @@ -190,12 +201,18 @@ U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountAspect>& st  LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat) const  { -	return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); +	const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; + +	return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter + accumulator.mChildTimeCounter - accumulator.mStartChildTimeCounter)  +				/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);  }  LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const  { -	return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); +	const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()]; + +	return (F64)(accumulator.mSelfTimeCounter - accumulator.mStartSelfTimeCounter)  +			/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);  }  F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat) const @@ -520,7 +537,7 @@ void ExtendableRecording::splitFrom(ExtendableRecording& other)  PeriodicRecording& get_frame_recording()  { -	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(64, PeriodicRecording::STARTED)); +	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));  	return *sRecording;  } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 05e1577a5a..16fee04979 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/llui/llui.cpp b/indra/llui/llui.cpp index 6a87977718..b9d935847b 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1147,6 +1147,8 @@ void gl_rect_2d_simple( S32 width, S32 height )  	gGL.end();  } +static LLFastTimer::DeclareTimer FTM_RENDER_SEGMENTED_RECT ("Render segmented rectangle"); +  void gl_segmented_rect_2d_tex(const S32 left,   							  const S32 top,   							  const S32 right,  @@ -1156,6 +1158,7 @@ void gl_segmented_rect_2d_tex(const S32 left,  							  const S32 border_size,   							  const U32 edges)  { +	LLFastTimer _(FTM_RENDER_SEGMENTED_RECT);  	S32 width = llabs(right - left);  	S32 height = llabs(top - bottom); @@ -1306,10 +1309,7 @@ void gl_segmented_rect_2d_tex(const S32 left,  }  //FIXME: rewrite to use scissor? -void gl_segmented_rect_2d_fragment_tex(const S32 left,  -									   const S32 top,  -									   const S32 right,  -									   const S32 bottom,  +void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,   									   const S32 texture_width,   									   const S32 texture_height,   									   const S32 border_size,  @@ -1317,6 +1317,11 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  									   const F32 end_fragment,   									   const U32 edges)  { +	LLFastTimer _(FTM_RENDER_SEGMENTED_RECT); +	const S32 left = rect.mLeft; +	const S32 right = rect.mRight; +	const S32 top = rect.mTop; +	const S32 bottom = rect.mBottom;  	S32 width = llabs(right - left);  	S32 height = llabs(top - bottom); @@ -1354,9 +1359,9 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  	{  		if (start_fragment < middle_start)  		{ -			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; +			u_min = (start_fragment / middle_start)			* border_uv_scale.mV[VX];  			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; -			x_min = (start_fragment / middle_start) * border_width_left; +			x_min = (start_fragment / middle_start)			* border_width_left;  			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;  			// draw bottom left @@ -1446,10 +1451,10 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  		if (end_fragment > middle_end)  		{ -			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX]; -			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]; -			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right); -			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); +			u_min = 1.f			- ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]); +			u_max = 1.f			- ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]); +			x_min = width_vec	- ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right); +			x_max = width_vec	- ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);  			// draw bottom right  			gGL.texCoord2f(u_min, 0.f); @@ -1500,6 +1505,7 @@ void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& bo  							  const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,  							  const U32 edges)  { +	LLFastTimer _(FTM_RENDER_SEGMENTED_RECT);  	LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;  	LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero; diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 90a4617c4e..dfb9fa60c9 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -128,7 +128,7 @@ typedef enum e_rounded_edge  void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL); +void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);  void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);  void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 7858378f00..1a1a4a8b44 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -58,9 +58,7 @@ using namespace LLTrace;  static const S32 MAX_VISIBLE_HISTORY = 10;  static const S32 LINE_GRAPH_HEIGHT = 240; - -const S32 FTV_MAX_DEPTH = 8; -const S32 HISTORY_NUM = 300; +static const S32 MIN_BAR_HEIGHT = 3;  std::vector<TimeBlock*> ft_display_idx; // line of table entry for display purposes (for collapse) @@ -107,7 +105,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,29 +115,37 @@ LLFastTimerView::~LLFastTimerView()  		delete mRecording;  	}  	mRecording = NULL; -	delete [] mBarRects; +	delete [] mTimerBars;  }  void LLFastTimerView::onPause()  { -	mPauseHistory = !mPauseHistory; +	setPauseState(!mPauseHistory); +} + +void LLFastTimerView::setPauseState(bool pause_state) +{ +	if (pause_state == mPauseHistory) return; +  	// reset scroll to bottom when unpausing -	if (!mPauseHistory) -	{ -		mRecording = new PeriodicRecording(get_frame_recording()); -		mScrollIndex = 0; -		getChild<LLButton>("pause_btn")->setLabel(getString("pause")); -	} -	else +	if (!pause_state)  	{  		if (mRecording != &get_frame_recording())  		{  			delete mRecording;  		}  		mRecording = &get_frame_recording(); +		getChild<LLButton>("pause_btn")->setLabel(getString("pause")); +	} +	else +	{ +		mRecording = new PeriodicRecording(get_frame_recording()); +		mScrollIndex = 0;  		getChild<LLButton>("pause_btn")->setLabel(getString("run"));  	} + +	mPauseHistory = pause_state;  }  BOOL LLFastTimerView::postBuild() @@ -177,7 +183,7 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)  TimeBlock* LLFastTimerView::getLegendID(S32 y)  { -	S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5; +	S32 idx = (mBarRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 1;  	if (idx >= 0 && idx < (S32)ft_display_idx.size())  	{ @@ -256,7 +262,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)(HISTORY_NUM - MAX_VISIBLE_HISTORY)); +		mScrollIndex = llround( lerp * (F32)(mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY));  		mScrollIndex = llclamp(	mScrollIndex, 0, mRecording->getNumPeriods());  		return TRUE;  	} @@ -265,8 +271,9 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  	if(mPauseHistory && mBarRect.pointInRect(x, y))  	{ -		mHoverBarIndex = llmin(mRecording->getNumPeriods() - 1,  -								MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight())); +		mHoverBarIndex = llmin((mBarRect.mTop - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1, +								mRecording->getNumPeriods() - 1, +								MAX_VISIBLE_HISTORY);  		if (mHoverBarIndex == 0)  		{  			return TRUE; @@ -282,7 +289,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].mVisibleRect.pointInRect(x, y))  			{  				mHoverID = (*it);  				if (mHoverTimer != *it) @@ -294,7 +301,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  					mHoverTimer = (*it);  				} -				mToolTipRect = mBarRects[mHoverBarIndex][i]; +				mToolTipRect = mTimerBars[mHoverBarIndex][i].mVisibleRect;  			}  			if ((*it)->getCollapsed()) @@ -318,17 +325,15 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicRecording& frame_recording)  { -	F64 ms_multiplier = 1000.0 / (F64)TimeBlock::countsPerSecond(); -  	std::string tooltip; -	if (history_index < 0) +	if (history_index == 0)  	{  		// by default, show average number of call -		tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPeriodMean(timer) * ms_multiplier).value(), (S32)frame_recording.getPeriodMean(timer.callCount())); +		tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<LLUnits::Milliseconds, F64>(frame_recording.getPeriodMean(timer)).value(), (S32)frame_recording.getPeriodMean(timer.callCount()));  	}  	else  	{ -		tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer) * ms_multiplier).value(), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount())); +		tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<LLUnits::Milliseconds, F64>(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount()));  	}  	return tooltip;  } @@ -343,7 +348,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  			LLRect screen_rect;  			localRectToScreen(mToolTipRect, &screen_rect); -			std::string tooltip = get_tooltip(*mHoverTimer, mScrollIndex + mHoverBarIndex, *mRecording); +			std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, *mRecording);  			LLToolTipMgr::instance().show(LLToolTip::Params()  				.message(tooltip) @@ -361,7 +366,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  			TimeBlock* idp = getLegendID(y);  			if (idp)  			{ -				LLToolTipMgr::instance().show(get_tooltip(*idp, -1,  *mRecording)); +				LLToolTipMgr::instance().show(get_tooltip(*idp, 0, *mRecording));  				return TRUE;  			} @@ -373,10 +378,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)  { -	mPauseHistory = true; +	setPauseState(true);  	mScrollIndex = llclamp(	mScrollIndex + clicks,  							0, -							llmin(mRecording->getNumPeriods(), (S32)HISTORY_NUM - MAX_VISIBLE_HISTORY)); +							llmin(mRecording->getNumPeriods(), (S32)mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY));  	return TRUE;  } @@ -397,7 +402,7 @@ void LLFastTimerView::draw()  	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)); +	drawLegend(y - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 2));  	// update rectangle that includes timer bars  	const S32 LEGEND_WIDTH = 220; @@ -999,8 +1004,11 @@ void LLFastTimerView::printLineStats()  	}  } +static LLFastTimer::DeclareTimer FTM_DRAW_LINE_GRAPH("Draw line graph"); +  void LLFastTimerView::drawLineGraph()  { +	LLFastTimer _(FTM_DRAW_LINE_GRAPH);  	//draw line graph history  	S32 x = mBarRect.mLeft;  	S32 y = LINE_GRAPH_HEIGHT; @@ -1019,7 +1027,7 @@ void LLFastTimerView::drawLineGraph()  	else if (mDisplayHz)  		axis_label = llformat("%d Hz", (int)(1.f / max_time.value()));  	else -		axis_label = llformat("%4.2f ms", max_time.value()); +		axis_label = llformat("%4.2f ms", LLUnit<LLUnits::Milliseconds, F32>(max_time).value());  	x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(axis_label)-5;  	y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); @@ -1029,10 +1037,10 @@ void LLFastTimerView::drawLineGraph()  	//highlight visible range  	{ -		S32 first_frame = HISTORY_NUM - mScrollIndex; +		S32 first_frame = mRecording->getNumPeriods() - mScrollIndex;  		S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; -		F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(HISTORY_NUM-1); +		F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording->getNumPeriods()-1);  		F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;  		F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; @@ -1040,9 +1048,9 @@ void LLFastTimerView::drawLineGraph()  		gGL.color4f(0.5f,0.5f,0.5f,0.3f);  		gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom); -		if (mHoverBarIndex >= 0) +		if (mHoverBarIndex > 0)  		{ -			S32 bar_frame = first_frame - mHoverBarIndex; +			S32 bar_frame = first_frame - mHoverBarIndex - 1;  			F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;  			gGL.color4f(0.5f,0.5f,0.5f,1); @@ -1074,7 +1082,7 @@ void LLFastTimerView::drawLineGraph()  		F32 alpha = 1.f;  		if (mHoverID != NULL && -			idp != mHoverID) +			mHoverID != idp)  		{	//fade out non-highlighted timers  			if (idp->getParent() != mHoverID)  			{ @@ -1097,7 +1105,7 @@ void LLFastTimerView::drawLineGraph()  				cur_max = llmax(cur_max, time);  				cur_max_calls = llmax(cur_max_calls, calls);  			} -			F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(HISTORY_NUM-1); +			F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording->getNumPeriods()-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(); @@ -1118,7 +1126,7 @@ void LLFastTimerView::drawLineGraph()  			it.skipDescendants();  		}  	} - +	  	//interpolate towards new maximum  	max_time = lerp(max_time.value(), cur_max.value(), LLCriticalDamp::getInterpolant(0.1f));  	if (max_time - cur_max <= 1 ||  cur_max - max_time  <= 1) @@ -1281,41 +1289,40 @@ void LLFastTimerView::generateUniqueColors()  S32 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]"), -			0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -		y -= (texth + 2); -	}	return y; +	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]"), +		0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); +	y -= (texth + 2); +	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 +1384,216 @@ 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; + +	mTotalTimeDisplay = LLUnit<LLUnits::Milliseconds, F32>(llceil(mTotalTimeDisplay.as<LLUnits::Milliseconds, F32>().value() / (20.f)) * 20.f);  }  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 bar_height = mBarRect.getHeight() / (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()); -	const S32 histmax = llmin(mRecording->getNumPeriods()+1, MAX_VISIBLE_HISTORY); +	LLPointer<LLUIImage> bar_image = LLUI::getUIImage("Rounded_Square"); +	gGL.getTexUnit(0)->bind(bar_image->getImage()); +	const S32 histmax = llmin(mRecording->getNumPeriods(), MAX_VISIBLE_HISTORY) + 1; -	for (S32 j = -1; j < histmax && y > LINE_GRAPH_HEIGHT; j++) +	for (S32 bar_index = 0; bar_index < histmax && y > LINE_GRAPH_HEIGHT; bar_index++)  	{ -		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) -			? j + 1 + mScrollIndex +		S32 history_index = (bar_index > 0) +			? bar_index + mScrollIndex  			: -1; +		mTimerBars[bar_index].clear(); +		mTimerBars[bar_index].reserve(LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()); + +		updateTimerBarWidths(&FTM_FRAME, mTimerBars[bar_index], history_index, true); +		LLRect frame_bar_rect(mBarRect.mLeft, y, mBarRect.mLeft + mTimerBars[bar_index][0].mWidth, y-bar_height); +		mTimerBars[bar_index][0].mVisibleRect = frame_bar_rect; +		updateTimerBarFractions(&FTM_FRAME, 0, mTimerBars[bar_index]); +		drawBar(&FTM_FRAME, frame_bar_rect, mTimerBars[bar_index], 0, bar_image); +				 +		y -= (bar_height + vpad); +		if (bar_index == 0) +			y -= bar_height; +	} +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +} -		// draw the bars for each stat -		std::vector<S32> xpos; -		S32 deltax = 0; -		xpos.push_back(mBarRect.mLeft); +static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths"); -		TimeBlock* prev_id = NULL; +S32 LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector<TimerBar>& bars, S32 history_index, bool visible) +{ +	LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS); +	F32 self_time_frame_fraction = history_index == -1 +		? (mRecording->getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay)  +		: (mRecording->getPrevRecordingPeriod(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); -		S32 i = 0; -		for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); -			it != end_timer_tree(); -			++it, ++i) -		{ -			TimeBlock* idp = (*it); -			F32 frac = tidx == -1 -				? (mRecording->getPeriodMean(*idp) / total_time)  -				: (mRecording->getPrevRecordingPeriod(tidx).getSum(*idp).value() / total_time.value()); +	S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); +	S32 full_width = self_time_width; -			S32 dx = llround(frac * (F32)mBarRect.getWidth()); -			S32 prev_delta_x = deltax; -			deltax = dx; +	bool children_visible = visible; -			const int level = get_depth(idp) - 1; -			while ((S32)xpos.size() > level + 1) -			{ -				xpos.pop_back(); -			} +	// reserve a spot for this bar to be rendered before its children +	// even though we don't know its size yet +	S32 bar_rect_index = bars.size(); +	if (visible) +	{ +		bars.push_back(TimerBar()); +	} -			LLRect bar_rect; -			bar_rect.setLeftTopAndSize(xpos.back(), y, dx, bar_height); -			mBarRects[llmax(j, 0)].push_back(bar_rect); +	if (time_block->getCollapsed()) +	{ +		children_visible = false; +	} +	for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) +	{ +		full_width += updateTimerBarWidths(*it, bars, history_index, children_visible); +	} -			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; +	if (visible) +	{ +		TimerBar& timer_bar = bars[bar_rect_index]; -				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(); -				} +		timer_bar.mWidth = full_width; +		timer_bar.mSelfWidth = self_time_width; +		timer_bar.mColor = sTimerColors[time_block]; + +		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(); +		} -				F32 subfrac = (F32)sublevelticks / (F32)total_time.value(); -				sublevel_dx[level] = (int)(subfrac * (F32)mBarRect.getWidth() + .5f); +		if (mHoverID != NULL  +			&& time_block != mHoverID  +			&& !is_child_of_hover_item) +		{ +			timer_bar.mColor = lerp(timer_bar.mColor, LLColor4::grey, 0.8f); +		} +	} +	return full_width; +} -				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]); -				} +static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions"); -				sublevel_left[level] = bar_rect.mLeft; -				sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; -			}				 +S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector<TimerBar>& bars) +{ +	LLFastTimer _(FTM_UPDATE_TIMER_BAR_FRACTIONS); +	TimerBar& timer_bar = bars[timer_bar_index]; +	S32 child_time_width = timer_bar.mWidth - timer_bar.mSelfWidth; +	LLRect children_rect = timer_bar.mVisibleRect; -			xpos.back() = bar_rect.mRight; -			xpos.push_back(bar_rect.mLeft); +	if (mDisplayCenter == ALIGN_CENTER) +	{ +		children_rect.mLeft += timer_bar.mSelfWidth / 2; +	} +	else if (mDisplayCenter == ALIGN_RIGHT) +	{ +		children_rect.mLeft += timer_bar.mSelfWidth; +	} +	children_rect.mRight = children_rect.mLeft + timer_bar.mWidth - timer_bar.mSelfWidth; -			if (bar_rect.getWidth() > 0) -			{ -				LLColor4 color = sTimerColors[idp]; -				S32 scale_offset = 0; +	if (children_rect.getHeight() > MIN_BAR_HEIGHT) +	{ +		children_rect.mTop -= 1; +		children_rect.mBottom += 1; +	} +	timer_bar.mChildrenRect = children_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(); -				} +	//now loop through children and figure out portion of bar image covered by each bar, now that we know the +	//sum of all children +	if (!time_block->getCollapsed()) +	{ +		F32 bar_fraction_start = 0.f; +		for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren();  +			it != end_it;  +			++it) +		{ +			timer_bar_index++; -				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); -				} +			TimerBar& child_timer_bar = bars[timer_bar_index]; +			TimeBlock* child_time_block = *it; -				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); -			} +			child_timer_bar.mStartFraction = bar_fraction_start; +			child_timer_bar.mEndFraction = child_time_width > 0 +				? bar_fraction_start + (F32)child_timer_bar.mWidth / child_time_width +				: 1.f; +			child_timer_bar.mVisibleRect.set(children_rect.mLeft + llround(child_timer_bar.mStartFraction * children_rect.getWidth()),  +				children_rect.mTop,  +				children_rect.mLeft + llround(child_timer_bar.mEndFraction * children_rect.getWidth()),  +				children_rect.mBottom); -			if ((*it)->getCollapsed()) -			{ -				it.skipDescendants(); -			} +			timer_bar_index = updateTimerBarFractions(child_time_block, timer_bar_index, bars); -			prev_id = idp; +			bar_fraction_start = child_timer_bar.mEndFraction;  		} -		y -= (bar_height + vpad); -		if (j < 0) -			y -= bar_height;  	} -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	return timer_bar_index;  } +S32 LLFastTimerView::drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 bar_index, LLPointer<LLUIImage>& bar_image) +{ +	TimerBar& timer_bar = bars[bar_index]; +	// animate scale of bar when hovering over that particular timer +	if (bar_rect.getWidth() > 0) +	{ +		LLRect render_rect(bar_rect); +		S32 scale_offset = 0; +		if (time_block == mHoverID) +		{ +			scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); +			render_rect.mTop += scale_offset; +			render_rect.mBottom -= scale_offset; +		} +		gGL.color4fv(timer_bar.mColor.mV); +		gl_segmented_rect_2d_fragment_tex(render_rect, +			bar_image->getTextureWidth(), bar_image->getTextureHeight(),  +			16,  +			timer_bar.mStartFraction, timer_bar.mEndFraction); +	} +	if (!time_block->getCollapsed()) +	{ +		for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) +		{ +			++bar_index; +			bar_index = drawBar(*it, timer_bar.mChildrenRect, bars, bar_index, bar_image); +		} +	} - - - - - - - +	return bar_index; +} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 7eee3c1cb5..f9ceb4423b 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -61,8 +61,6 @@ public:  	virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);  	virtual void draw(); - -  	LLTrace::TimeBlock* getLegendID(S32 y);  	F64 getTime(const std::string& name); @@ -70,7 +68,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 +77,32 @@ private:  	void printLineStats();  	void generateUniqueColors(); -	LLUnit<LLUnits::Seconds, F64> getTotalTime(); +	void updateTotalTime(); - -	std::vector<LLRect>* mBarRects; +	struct TimerBar +	{ +		TimerBar() +		:	mWidth(0), +			mSelfWidth(0), +			mVisible(true), +			mStartFraction(0.f), +			mEndFraction(1.f) +		{} +		S32			mWidth; +		S32			mSelfWidth; +		LLRect		mVisibleRect, +					mChildrenRect; +		LLColor4	mColor; +		bool		mVisible; +		F32			mStartFraction, +					mEndFraction; +	}; +	S32 updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector<TimerBar>& bars, S32 history_index, bool visible); +	S32 updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector<TimerBar>& bars); +	S32 drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 bar_index, LLPointer<LLUIImage>& bar_image); +	void setPauseState(bool pause_state); + +	std::vector<TimerBar>* mTimerBars;  	S32 mDisplayMode;  	typedef enum child_alignment @@ -96,7 +116,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;  | 
