Commits

richard_linden committed e50f553

improved fast timers display
can move and resize
better visualization of timer history
can click drag to browse history
increased frame history to 300

Comments (0)

Files changed (8)

indra/llcommon/llfasttimer_class.cpp

 
 std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
 {
+	F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
 	if (history_idx < 0)
 	{
-		// by default, show average number of calls
-		return llformat("%s (%d calls)", getName().c_str(), (S32)getCallAverage());
+		// by default, show average number of call
+		return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
 	}
 	else
 	{
-		return llformat("%s (%d calls)", getName().c_str(), (S32)getHistoricalCalls(history_idx));
+		return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
 	}
 }
 
 		llinfos << "Slow frame, fast timers inaccurate" << llendl;
 	}
 
-	if (sPauseHistory)
-	{
-		sResetHistory = true;
-	}
-	else if (sResetHistory)
-	{
-		sLastFrameIndex = 0;
-		sCurFrameIndex = 0;
-		sResetHistory = false;
-	}
-	else // not paused
+	if (!sPauseHistory)
 	{
 		NamedTimer::processTimes();
 		sLastFrameIndex = sCurFrameIndex++;

indra/llcommon/llfasttimer_class.h

 	public:
 		~NamedTimer();
 
-		enum { HISTORY_NUM = 60 };
+		enum { HISTORY_NUM = 300 };
 
 		const std::string& getName() const { return mName; }
 		NamedTimer* getParent() const { return mParent; }

indra/newview/lldebugview.cpp

 #include "llmemoryview.h"
 #include "llsceneview.h"
 #include "llviewertexture.h"
+#include "llfloaterreg.h"
 
 //
 // Globals
 	r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), 
   									 (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
 	
-	mFastTimerView = new LLFastTimerView(r);
-	mFastTimerView->setFollowsTop();
-	mFastTimerView->setFollowsLeft();
-	mFastTimerView->setVisible(FALSE);			// start invisible
-	addChild(mFastTimerView);
-	mFastTimerView->setRect(rect);
+	mFastTimerView = dynamic_cast<LLFastTimerView*>(LLFloaterReg::getInstance("fast_timers"));
 
 	gSceneView = new LLSceneView(r);
 	gSceneView->setFollowsTop();

indra/newview/llfasttimerview.cpp

 	return timer_tree_iterator_t(); 
 }
 
-LLFastTimerView::LLFastTimerView(const LLRect& rect)
-:	LLFloater(LLSD()),
+LLFastTimerView::LLFastTimerView(const LLSD& key)
+:	LLFloater(key),
 	mHoverTimer(NULL)
 {
-	setRect(rect);
-	setVisible(FALSE);
 	mDisplayMode = 0;
 	mAvgCountTotal = 0;
 	mMaxCountTotal = 0;
 	FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
 	mPrintStats = -1;	
 	mAverageCyclesPerTimer = 0;
-	setCanMinimize(false);
-	setCanClose(true);
 }
 
+void LLFastTimerView::onPause()
+{
+	LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+	// reset scroll to bottom when unpausing
+	if (!LLFastTimer::sPauseHistory)
+	{
+		mScrollIndex = 0;
+		getChild<LLButton>("pause_btn")->setLabel(getString("pause"));
+	}
+	else
+	{
+		getChild<LLButton>("pause_btn")->setLabel(getString("run"));
+	}
+}
+
+BOOL LLFastTimerView::postBuild()
+{
+	LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
+	
+	pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
+	return TRUE;
+}
 
 BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 		{
 			mHoverTimer->getParent()->setCollapsed(true);
 		}
+		return TRUE;
 	}
 	else if (mBarRect.pointInRect(x, y))
 	{
 		S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
 		bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
 		mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx;
+		return TRUE;
 	}
-	return FALSE;
+	return LLFloater::handleRightMouseDown(x, y, mask);
 }
 
 LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
 
 BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
-
-	{
-		S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
-		S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
-		if(mButtons[BUTTON_CLOSE]->getVisible()
-			&&  mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y)  )
-		{
-			return LLFloater::handleMouseDown(x, y, mask);;
-		}
-	}
-	
-
 	if (x < mBarRect.mLeft) 
 	{
 		LLFastTimer::NamedTimer* idp = getLegendID(y);
 	{
 		mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
 	}
-	else
+	else if (mGraphRect.pointInRect(x, y))
 	{
-		// pause/unpause
-		LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
-		// reset scroll to bottom when unpausing
-		if (!LLFastTimer::sPauseHistory)
-		{
-			mScrollIndex = 0;
-		}
+		gFocusMgr.setMouseCapture(this);
+		return TRUE;
 	}
-	// SJB: Don't pass mouse clicks through the display
-	return TRUE;
+	//else
+	//{
+	//	// pause/unpause
+	//	LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+	//	// reset scroll to bottom when unpausing
+	//	if (!LLFastTimer::sPauseHistory)
+	//	{
+	//		mScrollIndex = 0;
+	//	}
+	//}
+	return LLFloater::handleMouseDown(x, y, mask);
 }
 
 BOOL LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask)
 {
+	if (hasMouseCapture())
 	{
-		S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
-		S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
-		if(mButtons[BUTTON_CLOSE]->getVisible()
-			&&  mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y)  )
-		{
-			return LLFloater::handleMouseUp(x, y, mask);;
-		}
+		gFocusMgr.setMouseCapture(NULL);
 	}
-	return FALSE;
+	return LLFloater::handleMouseUp(x, y, mask);;
 }
 
 BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
 {
+	if (hasMouseCapture())
+	{
+		F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f);
+		mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
+		mScrollIndex = llclamp(	mScrollIndex, 0, LLFastTimer::getLastFrameIndex());
+		return TRUE;
+	}
 	mHoverTimer = NULL;
 	mHoverID = NULL;
 
 		}
 	}
 	
-	return FALSE;
+	return LLFloater::handleHover(x, y, mask);
 }
 
 
 			}
 		}
 	}
-	
-	return FALSE;
+
+	return LLFloater::handleToolTip(x, y, mask);
 }
 
 BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
 	LLFastTimer::sPauseHistory = TRUE;
-	mScrollIndex = llclamp(mScrollIndex - clicks, 
-							0, 
+	mScrollIndex = llclamp(	mScrollIndex + clicks,
+							0,
 							llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
 	return TRUE;
 }
 	F64 iclock_freq = 1000.0 / clock_freq;
 	
 	S32 margin = 10;
-	S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f);
-	S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f);
+	S32 height = getRect().getHeight();
+	S32 width = getRect().getWidth();
 	
 	LLRect new_rect;
 	new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
 										 LLFontGL::LEFT, LLFontGL::TOP);
 		}
 
-		LLRect graph_rect;
 		// Draw borders
 		{
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			by = LINE_GRAPH_HEIGHT-barh-dy-7;
 			
 			//line graph
-			graph_rect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
+			mGraphRect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
 			
-			gl_rect_2d(graph_rect, FALSE);
+			gl_rect_2d(mGraphRect, FALSE);
 		}
 		
 		mBarStart.clear();
 		//draw line graph history
 		{
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			LLLocalClipRect clip(graph_rect);
+			LLLocalClipRect clip(mGraphRect);
 			
 			//normalize based on last frame's maximum
 			static U64 last_max = 0;
 			else
 				tdesc = llformat("%4.2f ms", ms);
 							
-			x = graph_rect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
-			y = graph_rect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight());
+			x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
+			y = mGraphRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight());
  
 			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
 										 LLFontGL::LEFT, LLFontGL::TOP);
 				S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
 				S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
 				
-				F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
+				F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
 				
-				F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame;
-				F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame;
+				F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;
+				F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame;
 				
 				gGL.color4f(0.5f,0.5f,0.5f,0.3f);
-				gl_rect_2d((S32) left, graph_rect.mTop, (S32) right, graph_rect.mBottom);
+				gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom);
 				
 				if (mHoverBarIndex >= 0)
 				{
 					S32 bar_frame = first_frame - mHoverBarIndex;
-					F32 bar = (F32) graph_rect.mLeft + frame_delta*bar_frame;
+					F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;
 
 					gGL.color4f(0.5f,0.5f,0.5f,1);
 				
 					gGL.begin(LLRender::LINES);
-					gGL.vertex2i((S32)bar, graph_rect.mBottom);
-					gGL.vertex2i((S32)bar, graph_rect.mTop);
+					gGL.vertex2i((S32)bar, mGraphRect.mBottom);
+					gGL.vertex2i((S32)bar, mGraphRect.mTop);
 					gGL.end();
 				}
 			}
 				
 				if (mHoverID != NULL &&
 					idp != mHoverID)
-				{	//fade out non-hihglighted timers
+				{	//fade out non-highlighted timers
 					if (idp->getParent() != mHoverID)
 					{
 						alpha = alpha_interp;
 				}
 
 				gGL.color4f(col[0], col[1], col[2], alpha);				
-				gGL.begin(LLRender::LINE_STRIP);
-				for (U32 j = 0; j < LLFastTimer::NamedTimer::HISTORY_NUM; j++)
+				gGL.begin(LLRender::TRIANGLE_STRIP);
+				for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex());
+					j < LLFastTimer::NamedTimer::HISTORY_NUM;
+					j++)
 				{
 					U64 ticks = idp->getHistoricalCount(j);
 
 						//normalize to highlighted timer
 						cur_max = llmax(cur_max, ticks);
 					}
-					F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
-					F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks;
+					F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
+					F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks;
 					gGL.vertex2f(x,y);
+					gGL.vertex2f(x,mGraphRect.mBottom);
 				}
 				gGL.end();
 				
 			}
 			
 			//interpolate towards new maximum
-			F32 dt = gFrameIntervalSeconds*3.f;
-			last_max = (U64) ((F32) last_max + ((F32) cur_max- (F32) last_max) * dt);
+			last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f));
+			if (last_max - cur_max <= 1 ||  cur_max - last_max  <= 1)
+			{
+				last_max = cur_max;
+			}
 			F32 alpha_target = last_max > cur_max ?
 								llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) :
 								llmin((F32) cur_max/ (F32) last_max - 1.f,1.f);
-			
-			alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt;
+			alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f));
 
 			if (mHoverID != NULL)
 			{
-				x = (graph_rect.mRight + graph_rect.mLeft)/2;
-				y = graph_rect.mBottom + 8;
+				x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
+				y = mGraphRect.mBottom + 8;
 
 				LLFontGL::getFontMonospace()->renderUTF8(
 					mHoverID->getName(), 

indra/newview/llfasttimerview.h

 class LLFastTimerView : public LLFloater
 {
 public:
-	LLFastTimerView(const LLRect& rect);
-	
+	LLFastTimerView(const LLSD&);
+	BOOL postBuild();
+
 	static BOOL sAnalyzePerformance;
 
 	static void outputAllMetrics();
 	static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ;
 	static LLSD analyzePerformanceLogDefault(std::istream& is) ;
 	static void exportCharts(const std::string& base, const std::string& target);
+	void onPause();
 
 public:
 
 	LLFrameTimer mHighlightTimer;
 	S32 mPrintStats;
 	S32 mAverageCyclesPerTimer;
+	LLRect mGraphRect;
 };
 
 #endif

indra/newview/llviewerfloaterreg.cpp

 
 #include "llcompilequeue.h"
 #include "llcallfloater.h"
+#include "llfasttimerview.h"
 #include "llfloaterabout.h"
 #include "llfloateranimpreview.h"
 #include "llfloaterauction.h"
 	// *NOTE: Please keep these alphabetized for easier merges
 
 	LLFloaterAboutUtil::registerFloater();
+	LLFloaterReg::add("fast_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>);
 	LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
 	LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
 	LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);

indra/newview/llviewermenu.cpp

 		}
 		else if ("fast timers" == console_type)
 		{
-			toggle_visibility( (void*)gDebugView->mFastTimerView );
+			LLFloaterReg::toggleInstance("fast_timers");
 		}
 		else if ("scene view" == console_type)
 		{
 		}
 		else if ("fast timers" == console_type)
 		{
-			new_value = get_visibility( (void*)gDebugView->mFastTimerView );
+			new_value = LLFloaterReg::instanceVisible("fast_timers");
 		}
 		else if ("scene view" == console_type)
 		{

indra/newview/skins/default/xui/en/floater_fast_timers.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ can_tear_off="false"
+ can_resize="true"
+ can_drag_on_left="false"
+ can_close="true"
+ height="500"
+ layout="topleft"
+ name="fast_timers"
+ save_rect="true"
+ save_visibility="false"
+ single_instance="true" 
+ min_width="400"
+ width="700">
+  <string name="pause" >Pause</string>
+  <string name="run">Run</string>
+  <button follows="top|right" 
+          name="pause_btn"
+          left="-200"
+          top="5"
+          width="180"
+          height="40"
+          pad_bottom="-5"
+          label="Pause"
+          font="SansSerifHuge"/>
+</floater>