PageRenderTime 367ms CodeModel.GetById 121ms app.highlight 162ms RepoModel.GetById 79ms app.codeStats 0ms

/indra/newview/llfloaterlagmeter.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 375 lines | 274 code | 48 blank | 53 comment | 40 complexity | 75ef8c616849f607302fc5543d11f9e2 MD5 | raw file
  1/** 
  2 * @file llfloaterlagmeter.cpp
  3 * @brief The "Lag-o-Meter" floater used to tell users what is causing lag.
  4 *
  5 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llfloaterlagmeter.h"
 30
 31#include "lluictrlfactory.h"
 32#include "llviewerstats.h"
 33#include "llviewertexture.h"
 34#include "llviewercontrol.h"
 35#include "llappviewer.h"
 36
 37#include "lltexturefetch.h"
 38
 39#include "llbutton.h"
 40#include "llfocusmgr.h"
 41#include "lltextbox.h"
 42
 43const std::string LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga";
 44const std::string LAG_WARNING_IMAGE_NAME  = "lag_status_warning.tga";
 45const std::string LAG_GOOD_IMAGE_NAME     = "lag_status_good.tga";
 46
 47LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key)
 48	:	LLFloater(key)
 49{
 50	mCommitCallbackRegistrar.add("LagMeter.ClickShrink",  boost::bind(&LLFloaterLagMeter::onClickShrink, this));	
 51}
 52
 53BOOL LLFloaterLagMeter::postBuild()
 54{
 55	// Don't let this window take keyboard focus -- it's confusing to
 56	// lose arrow-key driving when testing lag.
 57	setIsChrome(TRUE);
 58	
 59	// were we shrunk last time?
 60	if (isShrunk())
 61	{
 62		onClickShrink();
 63	}
 64	
 65	mClientButton = getChild<LLButton>("client_lagmeter");
 66	mClientText = getChild<LLTextBox>("client_text");
 67	mClientCause = getChild<LLTextBox>("client_lag_cause");
 68
 69	mNetworkButton = getChild<LLButton>("network_lagmeter");
 70	mNetworkText = getChild<LLTextBox>("network_text");
 71	mNetworkCause = getChild<LLTextBox>("network_lag_cause");
 72
 73	mServerButton = getChild<LLButton>("server_lagmeter");
 74	mServerText = getChild<LLTextBox>("server_text");
 75	mServerCause = getChild<LLTextBox>("server_lag_cause");
 76
 77	std::string config_string = getString("client_frame_rate_critical_fps", mStringArgs);
 78	mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() );
 79	config_string = getString("client_frame_rate_warning_fps", mStringArgs);
 80	mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() );
 81
 82	config_string = getString("network_packet_loss_critical_pct", mStringArgs);
 83	mNetworkPacketLossCritical = (float)atof( config_string.c_str() );
 84	config_string = getString("network_packet_loss_warning_pct", mStringArgs);
 85	mNetworkPacketLossWarning = (float)atof( config_string.c_str() );
 86
 87	config_string = getString("network_ping_critical_ms", mStringArgs);
 88	mNetworkPingCritical = (float)atof( config_string.c_str() );
 89	config_string = getString("network_ping_warning_ms", mStringArgs);
 90	mNetworkPingWarning = (float)atof( config_string.c_str() );
 91	config_string = getString("server_frame_rate_critical_fps", mStringArgs);
 92
 93	mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() );
 94	config_string = getString("server_frame_rate_warning_fps", mStringArgs);
 95	mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() );
 96	config_string = getString("server_single_process_max_time_ms", mStringArgs);
 97	mServerSingleProcessMaxTime = (float)atof( config_string.c_str() );
 98
 99//	mShrunk = false;
100	config_string = getString("max_width_px", mStringArgs);
101	mMaxWidth = atoi( config_string.c_str() );
102	config_string = getString("min_width_px", mStringArgs);
103	mMinWidth = atoi( config_string.c_str() );
104
105	mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps");
106	mStringArgs["[CLIENT_FRAME_RATE_WARNING]"] = getString("client_frame_rate_warning_fps");
107
108	mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct");
109	mStringArgs["[NETWORK_PACKET_LOSS_WARNING]"] = getString("network_packet_loss_warning_pct");
110
111	mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms");
112	mStringArgs["[NETWORK_PING_WARNING]"] = getString("network_ping_warning_ms");
113
114	mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps");
115	mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps");
116
117//	childSetAction("minimize", onClickShrink, this);
118	updateControls(isShrunk()); // if expanded append colon to the labels (EXT-4079)
119
120	return TRUE;
121}
122LLFloaterLagMeter::~LLFloaterLagMeter()
123{
124	// save shrunk status for next time
125//	gSavedSettings.setBOOL("LagMeterShrunk", mShrunk);
126	// expand so we save the large window rectangle
127	if (isShrunk())
128	{
129		onClickShrink();
130	}
131}
132
133void LLFloaterLagMeter::draw()
134{
135	determineClient();
136	determineNetwork();
137	determineServer();
138
139	LLFloater::draw();
140}
141
142void LLFloaterLagMeter::determineClient()
143{
144	F32 client_frame_time = LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
145	bool find_cause = false;
146
147	if (!gFocusMgr.getAppHasFocus())
148	{
149		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
150		mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) );
151		mClientCause->setText( LLStringUtil::null );
152	}
153	else if(client_frame_time >= mClientFrameTimeCritical)
154	{
155		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
156		mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) );
157		find_cause = true;
158	}
159	else if(client_frame_time >= mClientFrameTimeWarning)
160	{
161		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
162		mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) );
163		find_cause = true;
164	}
165	else
166	{
167		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
168		mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) );
169		mClientCause->setText( LLStringUtil::null );
170	}	
171
172	if(find_cause)
173	{
174		if(gSavedSettings.getF32("RenderFarClip") > 128)
175		{
176			mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) );
177		}
178		else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2)
179		{
180			mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
181		}
182		else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes)
183		{
184			mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
185		}
186		else 
187		{
188			mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) );
189		}
190	}
191}
192
193void LLFloaterLagMeter::determineNetwork()
194{
195	F32 packet_loss = LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean();
196	F32 ping_time = LLViewerStats::getInstance()->mSimPingStat.getMean();
197	bool find_cause_loss = false;
198	bool find_cause_ping = false;
199
200	// *FIXME: We can't blame a large ping time on anything in
201	// particular if the frame rate is low, because a low frame
202	// rate is a sure recipe for bad ping times right now until
203	// the network handlers are de-synched from the rendering.
204	F32 client_frame_time_ms = 1000.0f * LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
205	
206	if(packet_loss >= mNetworkPacketLossCritical)
207	{
208		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
209		mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) );
210		find_cause_loss = true;
211	}
212	else if(ping_time >= mNetworkPingCritical)
213	{
214		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
215		if (client_frame_time_ms < mNetworkPingCritical)
216		{
217			mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) );
218			find_cause_ping = true;
219		}
220	}
221	else if(packet_loss >= mNetworkPacketLossWarning)
222	{
223		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
224		mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) );
225		find_cause_loss = true;
226	}
227	else if(ping_time >= mNetworkPingWarning)
228	{
229		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
230		if (client_frame_time_ms < mNetworkPingWarning)
231		{
232			mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) );
233			find_cause_ping = true;
234		}
235	}
236	else
237	{
238		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
239		mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) );
240	}
241
242	if(find_cause_loss)
243 	{
244		mNetworkCause->setText( getString("network_packet_loss_cause_msg", mStringArgs) );
245 	}
246	else if(find_cause_ping)
247	{
248		mNetworkCause->setText( getString("network_ping_cause_msg", mStringArgs) );
249	}
250	else
251	{
252		mNetworkCause->setText( LLStringUtil::null );
253	}
254}
255
256void LLFloaterLagMeter::determineServer()
257{
258	F32 sim_frame_time = LLViewerStats::getInstance()->mSimFrameMsec.getCurrent();
259	bool find_cause = false;
260
261	if(sim_frame_time >= mServerFrameTimeCritical)
262	{
263		mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
264		mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) );
265		find_cause = true;
266	}
267	else if(sim_frame_time >= mServerFrameTimeWarning)
268	{
269		mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
270		mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) );
271		find_cause = true;
272	}
273	else
274	{
275		mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
276		mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) );
277		mServerCause->setText( LLStringUtil::null );
278	}	
279
280	if(find_cause)
281	{
282		if(LLViewerStats::getInstance()->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime)
283		{
284			mServerCause->setText( getString("server_physics_cause_msg", mStringArgs) );
285		}
286		else if(LLViewerStats::getInstance()->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime)
287		{
288			mServerCause->setText( getString("server_scripts_cause_msg", mStringArgs) );
289		}
290		else if(LLViewerStats::getInstance()->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime)
291		{
292			mServerCause->setText( getString("server_net_cause_msg", mStringArgs) );
293		}
294		else if(LLViewerStats::getInstance()->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime)
295		{
296			mServerCause->setText( getString("server_agent_cause_msg", mStringArgs) );
297		}
298		else if(LLViewerStats::getInstance()->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime)
299		{
300			mServerCause->setText( getString("server_images_cause_msg", mStringArgs) );
301		}
302		else
303		{
304			mServerCause->setText( getString("server_generic_cause_msg", mStringArgs) );
305		}
306	}
307}
308
309void LLFloaterLagMeter::updateControls(bool shrink)
310{
311//	LLFloaterLagMeter * self = (LLFloaterLagMeter*)data;
312
313	LLButton * button = getChild<LLButton>("minimize");
314	S32 delta_width = mMaxWidth -mMinWidth;
315	LLRect r = getRect();
316
317	if(!shrink)
318	{
319		setTitle(getString("max_title_msg", mStringArgs) );
320		// make left edge appear to expand
321		r.translate(-delta_width, 0);
322		setRect(r);
323		reshape(mMaxWidth, getRect().getHeight());
324		
325		getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) + ":");
326		getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) + ":");
327		getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) + ":");
328
329		// usually "<<"
330		button->setLabel( getString("smaller_label", mStringArgs) );
331	}
332	else
333	{
334		setTitle( getString("min_title_msg", mStringArgs) );
335		// make left edge appear to collapse
336		r.translate(delta_width, 0);
337		setRect(r);
338		reshape(mMinWidth, getRect().getHeight());
339		
340		getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) );
341		getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) );
342		getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) );
343
344		// usually ">>"
345		button->setLabel( getString("bigger_label", mStringArgs) );
346	}
347	// Don't put keyboard focus on the button
348	button->setFocus(FALSE);
349
350//	self->mClientText->setVisible(self->mShrunk);
351//	self->mClientCause->setVisible(self->mShrunk);
352//	self->getChildView("client_help")->setVisible( self->mShrunk);
353
354//	self->mNetworkText->setVisible(self->mShrunk);
355//	self->mNetworkCause->setVisible(self->mShrunk);
356//	self->getChildView("network_help")->setVisible( self->mShrunk);
357
358//	self->mServerText->setVisible(self->mShrunk);
359//	self->mServerCause->setVisible(self->mShrunk);
360//	self->getChildView("server_help")->setVisible( self->mShrunk);
361
362//	self->mShrunk = !self->mShrunk;
363}
364
365BOOL LLFloaterLagMeter::isShrunk()
366{
367	return gSavedSettings.getBOOL("LagMeterShrunk");
368}
369
370void LLFloaterLagMeter::onClickShrink()  // toggle "LagMeterShrunk"
371{
372	bool shrunk = isShrunk();
373	updateControls(!shrunk);
374	gSavedSettings.setBOOL("LagMeterShrunk", !shrunk);
375}