aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterlagmeter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llfloaterlagmeter.cpp')
-rw-r--r--linden/indra/newview/llfloaterlagmeter.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterlagmeter.cpp b/linden/indra/newview/llfloaterlagmeter.cpp
new file mode 100644
index 0000000..399d0b6
--- /dev/null
+++ b/linden/indra/newview/llfloaterlagmeter.cpp
@@ -0,0 +1,365 @@
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=viewergpl$
6 *
7 * Copyright (c) 2007, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlife.com/developers/opensource/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlife.com/developers/opensource/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llfloaterlagmeter.h"
35
36#include "llvieweruictrlfactory.h"
37#include "llviewerstats.h"
38#include "llviewerimage.h"
39#include "llviewercontrol.h"
40#include "viewer.h"
41#include "lltexturefetch.h"
42
43#include "llbutton.h"
44#include "llfocusmgr.h"
45#include "lltextbox.h"
46
47const LLString LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga";
48const LLString LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga";
49const LLString LAG_GOOD_IMAGE_NAME = "lag_status_good.tga";
50
51LLFloaterLagMeter * LLFloaterLagMeter::sInstance = NULL;
52
53LLFloaterLagMeter::LLFloaterLagMeter()
54 : LLFloater("floater_lagmeter")
55{
56 gUICtrlFactory->buildFloater(this, "floater_lagmeter.xml");
57
58 // Don't let this window take keyboard focus -- it's confusing to
59 // lose arrow-key driving when testing lag.
60 setIsChrome(TRUE);
61
62 mClientButton = LLUICtrlFactory::getButtonByName(this, "client_lagmeter");
63 mClientText = LLUICtrlFactory::getTextBoxByName(this, "client_text");
64 mClientCause = LLUICtrlFactory::getTextBoxByName(this, "client_lag_cause");
65
66 mNetworkButton = LLUICtrlFactory::getButtonByName(this, "network_lagmeter");
67 mNetworkText = LLUICtrlFactory::getTextBoxByName(this, "network_text");
68 mNetworkCause = LLUICtrlFactory::getTextBoxByName(this, "network_lag_cause");
69
70 mServerButton = LLUICtrlFactory::getButtonByName(this, "server_lagmeter");
71 mServerText = LLUICtrlFactory::getTextBoxByName(this, "server_text");
72 mServerCause = LLUICtrlFactory::getTextBoxByName(this, "server_lag_cause");
73
74 LLString config_string = childGetText("client_frame_rate_critical_fps");
75 mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() );
76 config_string = childGetText("client_frame_rate_warning_fps");
77 mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() );
78
79 config_string = childGetText("network_packet_loss_critical_pct");
80 mNetworkPacketLossCritical = (float)atof( config_string.c_str() );
81 config_string = childGetText("network_packet_loss_warning_pct");
82 mNetworkPacketLossWarning = (float)atof( config_string.c_str() );
83
84 config_string = childGetText("network_ping_critical_ms");
85 mNetworkPingCritical = (float)atof( config_string.c_str() );
86 config_string = childGetText("network_ping_warning_ms");
87 mNetworkPingWarning = (float)atof( config_string.c_str() );
88 config_string = childGetText("server_frame_rate_critical_fps");
89
90 mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() );
91 config_string = childGetText("server_frame_rate_warning_fps");
92 mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() );
93 config_string = childGetText("server_single_process_max_time_ms");
94 mServerSingleProcessMaxTime = (float)atof( config_string.c_str() );
95
96 mShrunk = false;
97 config_string = childGetText("max_width_px");
98 mMaxWidth = atoi( config_string.c_str() );
99 config_string = childGetText("min_width_px");
100 mMinWidth = atoi( config_string.c_str() );
101
102 childSetTextArg("client_frame_time_critical_msg", "[CLIENT_FRAME_RATE_CRITICAL]", childGetText("client_frame_rate_critical_fps"));
103 childSetTextArg("client_frame_time_warning_msg", "[CLIENT_FRAME_RATE_CRITICAL]", childGetText("client_frame_rate_critical_fps"));
104 childSetTextArg("client_frame_time_warning_msg", "[CLIENT_FRAME_RATE_WARNING]", childGetText("client_frame_rate_warning_fps"));
105
106 childSetTextArg("network_packet_loss_critical_msg", "[NETWORK_PACKET_LOSS_CRITICAL]", childGetText("network_packet_loss_critical_pct"));
107 childSetTextArg("network_packet_loss_warning_msg", "[NETWORK_PACKET_LOSS_CRITICAL]", childGetText("network_packet_loss_critical_pct"));
108 childSetTextArg("network_packet_loss_warning_msg", "[NETWORK_PACKET_LOSS_WARNING]", childGetText("network_packet_loss_warning_pct"));
109
110 childSetTextArg("network_ping_critical_msg", "[NETWORK_PING_CRITICAL]", childGetText("network_ping_critical_ms"));
111 childSetTextArg("network_ping_warning_msg", "[NETWORK_PING_CRITICAL]", childGetText("network_ping_critical_ms"));
112 childSetTextArg("network_ping_warning_msg", "[NETWORK_PING_WARNING]", childGetText("network_ping_warning_ms"));
113
114 childSetTextArg("server_frame_time_critical_msg", "[SERVER_FRAME_RATE_CRITICAL]", childGetText("server_frame_rate_critical_fps"));
115 childSetTextArg("server_frame_time_warning_msg", "[SERVER_FRAME_RATE_CRITICAL]", childGetText("server_frame_rate_critical_fps"));
116 childSetTextArg("server_frame_time_warning_msg", "[SERVER_FRAME_RATE_WARNING]", childGetText("server_frame_rate_warning_fps"));
117
118 childSetAction("minimize", onClickShrink, this);
119
120 // were we shrunk last time?
121 if (gSavedSettings.getBOOL("LagMeterShrunk"))
122 {
123 onClickShrink(this);
124 }
125}
126
127LLFloaterLagMeter::~LLFloaterLagMeter()
128{
129 sInstance = NULL;
130
131 // save shrunk status for next time
132 gSavedSettings.setBOOL("LagMeterShrunk", mShrunk);
133 // expand so we save the large window rectangle
134 if (mShrunk)
135 {
136 onClickShrink(this);
137 }
138}
139
140void LLFloaterLagMeter::draw()
141{
142 determineClient();
143 determineNetwork();
144 determineServer();
145
146 LLFloater::draw();
147}
148
149//static
150void LLFloaterLagMeter::show(void *data)
151{
152 if(!sInstance) sInstance = new LLFloaterLagMeter();
153 sInstance->open();
154}
155
156void LLFloaterLagMeter::determineClient()
157{
158 F32 client_frame_time = gViewerStats->mFPSStat.getMeanDuration();
159 bool find_cause = false;
160
161 if (!gFocusMgr.getAppHasFocus())
162 {
163 mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
164 mClientText->setText( childGetText("client_frame_time_window_bg_msg") );
165 mClientCause->setText( LLString::null );
166 }
167 else if(client_frame_time >= mClientFrameTimeCritical)
168 {
169 mClientButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
170 mClientText->setText( childGetText("client_frame_time_critical_msg") );
171 find_cause = true;
172 }
173 else if(client_frame_time >= mClientFrameTimeWarning)
174 {
175 mClientButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
176 mClientText->setText( childGetText("client_frame_time_warning_msg") );
177 find_cause = true;
178 }
179 else
180 {
181 mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
182 mClientText->setText( childGetText("client_frame_time_normal_msg") );
183 mClientCause->setText( LLString::null );
184 }
185
186 if(find_cause)
187 {
188 if(gSavedSettings.getF32("RenderFarClip") > 128)
189 {
190 mClientCause->setText( childGetText("client_draw_distance_cause_msg") );
191 }
192 else if(gTextureFetch->getNumRequests() > 2)
193 {
194 mClientCause->setText( childGetText("client_texture_loading_cause_msg") );
195 }
196 else if(LLViewerImage::sBoundTextureMemory > LLViewerImage::sMaxBoundTextureMem)
197 {
198 mClientCause->setText( childGetText("client_texture_memory_cause_msg") );
199 }
200 else
201 {
202 mClientCause->setText( childGetText("client_complex_objects_cause_msg") );
203 }
204 }
205}
206
207void LLFloaterLagMeter::determineNetwork()
208{
209 F32 packet_loss = gViewerStats->mPacketsLostPercentStat.getMean();
210 F32 ping_time = gViewerStats->mSimPingStat.getMean();
211 bool find_cause_loss = false;
212 bool find_cause_ping = false;
213
214 if(packet_loss >= mNetworkPacketLossCritical)
215 {
216 mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
217 mNetworkText->setText( childGetText("network_packet_loss_critical_msg") );
218 find_cause_loss = true;
219 }
220 else if(ping_time >= mNetworkPingCritical)
221 {
222 mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
223 mNetworkText->setText( childGetText("network_ping_critical_msg") );
224 find_cause_ping = true;
225 }
226 else if(packet_loss >= mNetworkPacketLossWarning)
227 {
228 mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
229 mNetworkText->setText( childGetText("network_packet_loss_warning_msg") );
230 find_cause_loss = true;
231 }
232 else if(ping_time >= mNetworkPingWarning)
233 {
234 mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
235 mNetworkText->setText( childGetText("network_ping_warning_msg") );
236 find_cause_ping = true;
237 }
238 else
239 {
240 mNetworkButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
241 mNetworkText->setText( childGetText("network_performance_normal_msg") );
242 }
243
244 if(find_cause_loss)
245 {
246 mNetworkCause->setText( childGetText("network_packet_loss_cause_msg") );
247 }
248 else if(find_cause_ping)
249 {
250 mNetworkCause->setText( childGetText("network_ping_cause_msg") );
251 }
252 else
253 {
254 mNetworkCause->setText( LLString::null );
255 }
256}
257
258void LLFloaterLagMeter::determineServer()
259{
260 F32 sim_frame_time = gViewerStats->mSimFrameMsec.getCurrent();
261 bool find_cause = false;
262
263 if(sim_frame_time >= mServerFrameTimeCritical)
264 {
265 mServerButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
266 mServerText->setText( childGetText("server_frame_time_critical_msg") );
267 find_cause = true;
268 }
269 else if(sim_frame_time >= mServerFrameTimeWarning)
270 {
271 mServerButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
272 mServerText->setText( childGetText("server_frame_time_warning_msg") );
273 find_cause = true;
274 }
275 else
276 {
277 mServerButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
278 mServerText->setText( childGetText("server_frame_time_normal_msg") );
279 mServerCause->setText( LLString::null );
280 }
281
282 if(find_cause)
283 {
284 if(gViewerStats->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime)
285 {
286 mServerCause->setText( childGetText("server_physics_cause_msg") );
287 }
288 else if(gViewerStats->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime)
289 {
290 mServerCause->setText( childGetText("server_scripts_cause_msg") );
291 }
292 else if(gViewerStats->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime)
293 {
294 mServerCause->setText( childGetText("server_net_cause_msg") );
295 }
296 else if(gViewerStats->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime)
297 {
298 mServerCause->setText( childGetText("server_agent_cause_msg") );
299 }
300 else if(gViewerStats->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime)
301 {
302 mServerCause->setText( childGetText("server_images_cause_msg") );
303 }
304 else
305 {
306 mServerCause->setText( childGetText("server_generic_cause_msg") );
307 }
308 }
309}
310
311//static
312void LLFloaterLagMeter::onClickShrink(void * data)
313{
314 LLFloaterLagMeter * self = (LLFloaterLagMeter*)data;
315
316 LLButton * button = (LLButton*)self->getChildByName("minimize");
317 S32 delta_width = self->mMaxWidth - self->mMinWidth;
318 LLRect r = self->getRect();
319 if(self->mShrunk)
320 {
321 self->setTitle( self->childGetText("max_title_msg") );
322 // make left edge appear to expand
323 r.translate(-delta_width, 0);
324 self->setRect(r);
325 self->reshape(self->mMaxWidth, self->getRect().getHeight());
326
327 self->childSetText("client", self->childGetText("client_text_msg") + ":");
328 self->childSetText("network", self->childGetText("network_text_msg") + ":");
329 self->childSetText("server", self->childGetText("server_text_msg") + ":");
330
331 // usually "<<"
332 button->setLabel( self->childGetText("smaller_label") );
333 }
334 else
335 {
336 self->setTitle( self->childGetText("min_title_msg") );
337 // make left edge appear to collapse
338 r.translate(delta_width, 0);
339 self->setRect(r);
340 self->reshape(self->mMinWidth, self->getRect().getHeight());
341
342 self->childSetText("client", self->childGetText("client_text_msg") );
343 self->childSetText("network", self->childGetText("network_text_msg") );
344 self->childSetText("server", self->childGetText("server_text_msg") );
345
346 // usually ">>"
347 button->setLabel( self->childGetText("bigger_label") );
348 }
349 // Don't put keyboard focus on the button
350 button->setFocus(FALSE);
351
352 self->mClientText->setVisible(self->mShrunk);
353 self->mClientCause->setVisible(self->mShrunk);
354 self->childSetVisible("client_help", self->mShrunk);
355
356 self->mNetworkText->setVisible(self->mShrunk);
357 self->mNetworkCause->setVisible(self->mShrunk);
358 self->childSetVisible("network_help", self->mShrunk);
359
360 self->mServerText->setVisible(self->mShrunk);
361 self->mServerCause->setVisible(self->mShrunk);
362 self->childSetVisible("server_help", self->mShrunk);
363
364 self->mShrunk = !self->mShrunk;
365}