diff options
Diffstat (limited to 'linden/indra/newview/llfloaterlagmeter.cpp')
-rw-r--r-- | linden/indra/newview/llfloaterlagmeter.cpp | 365 |
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 | |||
47 | const LLString LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga"; | ||
48 | const LLString LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga"; | ||
49 | const LLString LAG_GOOD_IMAGE_NAME = "lag_status_good.tga"; | ||
50 | |||
51 | LLFloaterLagMeter * LLFloaterLagMeter::sInstance = NULL; | ||
52 | |||
53 | LLFloaterLagMeter::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 | |||
127 | LLFloaterLagMeter::~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 | |||
140 | void LLFloaterLagMeter::draw() | ||
141 | { | ||
142 | determineClient(); | ||
143 | determineNetwork(); | ||
144 | determineServer(); | ||
145 | |||
146 | LLFloater::draw(); | ||
147 | } | ||
148 | |||
149 | //static | ||
150 | void LLFloaterLagMeter::show(void *data) | ||
151 | { | ||
152 | if(!sInstance) sInstance = new LLFloaterLagMeter(); | ||
153 | sInstance->open(); | ||
154 | } | ||
155 | |||
156 | void 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 | |||
207 | void 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 | |||
258 | void 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 | ||
312 | void 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 | } | ||