PageRenderTime 37ms CodeModel.GetById 15ms RepoModel.GetById 0ms 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
Possible License(s): LGPL-2.1
  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. #include "llviewerprecompiledheaders.h"
  27. #include "llfloaterlagmeter.h"
  28. #include "lluictrlfactory.h"
  29. #include "llviewerstats.h"
  30. #include "llviewertexture.h"
  31. #include "llviewercontrol.h"
  32. #include "llappviewer.h"
  33. #include "lltexturefetch.h"
  34. #include "llbutton.h"
  35. #include "llfocusmgr.h"
  36. #include "lltextbox.h"
  37. const std::string LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga";
  38. const std::string LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga";
  39. const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga";
  40. LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key)
  41. : LLFloater(key)
  42. {
  43. mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this));
  44. }
  45. BOOL LLFloaterLagMeter::postBuild()
  46. {
  47. // Don't let this window take keyboard focus -- it's confusing to
  48. // lose arrow-key driving when testing lag.
  49. setIsChrome(TRUE);
  50. // were we shrunk last time?
  51. if (isShrunk())
  52. {
  53. onClickShrink();
  54. }
  55. mClientButton = getChild<LLButton>("client_lagmeter");
  56. mClientText = getChild<LLTextBox>("client_text");
  57. mClientCause = getChild<LLTextBox>("client_lag_cause");
  58. mNetworkButton = getChild<LLButton>("network_lagmeter");
  59. mNetworkText = getChild<LLTextBox>("network_text");
  60. mNetworkCause = getChild<LLTextBox>("network_lag_cause");
  61. mServerButton = getChild<LLButton>("server_lagmeter");
  62. mServerText = getChild<LLTextBox>("server_text");
  63. mServerCause = getChild<LLTextBox>("server_lag_cause");
  64. std::string config_string = getString("client_frame_rate_critical_fps", mStringArgs);
  65. mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() );
  66. config_string = getString("client_frame_rate_warning_fps", mStringArgs);
  67. mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() );
  68. config_string = getString("network_packet_loss_critical_pct", mStringArgs);
  69. mNetworkPacketLossCritical = (float)atof( config_string.c_str() );
  70. config_string = getString("network_packet_loss_warning_pct", mStringArgs);
  71. mNetworkPacketLossWarning = (float)atof( config_string.c_str() );
  72. config_string = getString("network_ping_critical_ms", mStringArgs);
  73. mNetworkPingCritical = (float)atof( config_string.c_str() );
  74. config_string = getString("network_ping_warning_ms", mStringArgs);
  75. mNetworkPingWarning = (float)atof( config_string.c_str() );
  76. config_string = getString("server_frame_rate_critical_fps", mStringArgs);
  77. mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() );
  78. config_string = getString("server_frame_rate_warning_fps", mStringArgs);
  79. mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() );
  80. config_string = getString("server_single_process_max_time_ms", mStringArgs);
  81. mServerSingleProcessMaxTime = (float)atof( config_string.c_str() );
  82. // mShrunk = false;
  83. config_string = getString("max_width_px", mStringArgs);
  84. mMaxWidth = atoi( config_string.c_str() );
  85. config_string = getString("min_width_px", mStringArgs);
  86. mMinWidth = atoi( config_string.c_str() );
  87. mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps");
  88. mStringArgs["[CLIENT_FRAME_RATE_WARNING]"] = getString("client_frame_rate_warning_fps");
  89. mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct");
  90. mStringArgs["[NETWORK_PACKET_LOSS_WARNING]"] = getString("network_packet_loss_warning_pct");
  91. mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms");
  92. mStringArgs["[NETWORK_PING_WARNING]"] = getString("network_ping_warning_ms");
  93. mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps");
  94. mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps");
  95. // childSetAction("minimize", onClickShrink, this);
  96. updateControls(isShrunk()); // if expanded append colon to the labels (EXT-4079)
  97. return TRUE;
  98. }
  99. LLFloaterLagMeter::~LLFloaterLagMeter()
  100. {
  101. // save shrunk status for next time
  102. // gSavedSettings.setBOOL("LagMeterShrunk", mShrunk);
  103. // expand so we save the large window rectangle
  104. if (isShrunk())
  105. {
  106. onClickShrink();
  107. }
  108. }
  109. void LLFloaterLagMeter::draw()
  110. {
  111. determineClient();
  112. determineNetwork();
  113. determineServer();
  114. LLFloater::draw();
  115. }
  116. void LLFloaterLagMeter::determineClient()
  117. {
  118. F32 client_frame_time = LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
  119. bool find_cause = false;
  120. if (!gFocusMgr.getAppHasFocus())
  121. {
  122. mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
  123. mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) );
  124. mClientCause->setText( LLStringUtil::null );
  125. }
  126. else if(client_frame_time >= mClientFrameTimeCritical)
  127. {
  128. mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
  129. mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) );
  130. find_cause = true;
  131. }
  132. else if(client_frame_time >= mClientFrameTimeWarning)
  133. {
  134. mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
  135. mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) );
  136. find_cause = true;
  137. }
  138. else
  139. {
  140. mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
  141. mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) );
  142. mClientCause->setText( LLStringUtil::null );
  143. }
  144. if(find_cause)
  145. {
  146. if(gSavedSettings.getF32("RenderFarClip") > 128)
  147. {
  148. mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) );
  149. }
  150. else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2)
  151. {
  152. mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
  153. }
  154. else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes)
  155. {
  156. mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
  157. }
  158. else
  159. {
  160. mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) );
  161. }
  162. }
  163. }
  164. void LLFloaterLagMeter::determineNetwork()
  165. {
  166. F32 packet_loss = LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean();
  167. F32 ping_time = LLViewerStats::getInstance()->mSimPingStat.getMean();
  168. bool find_cause_loss = false;
  169. bool find_cause_ping = false;
  170. // *FIXME: We can't blame a large ping time on anything in
  171. // particular if the frame rate is low, because a low frame
  172. // rate is a sure recipe for bad ping times right now until
  173. // the network handlers are de-synched from the rendering.
  174. F32 client_frame_time_ms = 1000.0f * LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
  175. if(packet_loss >= mNetworkPacketLossCritical)
  176. {
  177. mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
  178. mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) );
  179. find_cause_loss = true;
  180. }
  181. else if(ping_time >= mNetworkPingCritical)
  182. {
  183. mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
  184. if (client_frame_time_ms < mNetworkPingCritical)
  185. {
  186. mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) );
  187. find_cause_ping = true;
  188. }
  189. }
  190. else if(packet_loss >= mNetworkPacketLossWarning)
  191. {
  192. mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
  193. mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) );
  194. find_cause_loss = true;
  195. }
  196. else if(ping_time >= mNetworkPingWarning)
  197. {
  198. mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
  199. if (client_frame_time_ms < mNetworkPingWarning)
  200. {
  201. mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) );
  202. find_cause_ping = true;
  203. }
  204. }
  205. else
  206. {
  207. mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
  208. mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) );
  209. }
  210. if(find_cause_loss)
  211. {
  212. mNetworkCause->setText( getString("network_packet_loss_cause_msg", mStringArgs) );
  213. }
  214. else if(find_cause_ping)
  215. {
  216. mNetworkCause->setText( getString("network_ping_cause_msg", mStringArgs) );
  217. }
  218. else
  219. {
  220. mNetworkCause->setText( LLStringUtil::null );
  221. }
  222. }
  223. void LLFloaterLagMeter::determineServer()
  224. {
  225. F32 sim_frame_time = LLViewerStats::getInstance()->mSimFrameMsec.getCurrent();
  226. bool find_cause = false;
  227. if(sim_frame_time >= mServerFrameTimeCritical)
  228. {
  229. mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
  230. mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) );
  231. find_cause = true;
  232. }
  233. else if(sim_frame_time >= mServerFrameTimeWarning)
  234. {
  235. mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
  236. mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) );
  237. find_cause = true;
  238. }
  239. else
  240. {
  241. mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
  242. mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) );
  243. mServerCause->setText( LLStringUtil::null );
  244. }
  245. if(find_cause)
  246. {
  247. if(LLViewerStats::getInstance()->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime)
  248. {
  249. mServerCause->setText( getString("server_physics_cause_msg", mStringArgs) );
  250. }
  251. else if(LLViewerStats::getInstance()->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime)
  252. {
  253. mServerCause->setText( getString("server_scripts_cause_msg", mStringArgs) );
  254. }
  255. else if(LLViewerStats::getInstance()->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime)
  256. {
  257. mServerCause->setText( getString("server_net_cause_msg", mStringArgs) );
  258. }
  259. else if(LLViewerStats::getInstance()->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime)
  260. {
  261. mServerCause->setText( getString("server_agent_cause_msg", mStringArgs) );
  262. }
  263. else if(LLViewerStats::getInstance()->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime)
  264. {
  265. mServerCause->setText( getString("server_images_cause_msg", mStringArgs) );
  266. }
  267. else
  268. {
  269. mServerCause->setText( getString("server_generic_cause_msg", mStringArgs) );
  270. }
  271. }
  272. }
  273. void LLFloaterLagMeter::updateControls(bool shrink)
  274. {
  275. // LLFloaterLagMeter * self = (LLFloaterLagMeter*)data;
  276. LLButton * button = getChild<LLButton>("minimize");
  277. S32 delta_width = mMaxWidth -mMinWidth;
  278. LLRect r = getRect();
  279. if(!shrink)
  280. {
  281. setTitle(getString("max_title_msg", mStringArgs) );
  282. // make left edge appear to expand
  283. r.translate(-delta_width, 0);
  284. setRect(r);
  285. reshape(mMaxWidth, getRect().getHeight());
  286. getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) + ":");
  287. getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) + ":");
  288. getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) + ":");
  289. // usually "<<"
  290. button->setLabel( getString("smaller_label", mStringArgs) );
  291. }
  292. else
  293. {
  294. setTitle( getString("min_title_msg", mStringArgs) );
  295. // make left edge appear to collapse
  296. r.translate(delta_width, 0);
  297. setRect(r);
  298. reshape(mMinWidth, getRect().getHeight());
  299. getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) );
  300. getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) );
  301. getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) );
  302. // usually ">>"
  303. button->setLabel( getString("bigger_label", mStringArgs) );
  304. }
  305. // Don't put keyboard focus on the button
  306. button->setFocus(FALSE);
  307. // self->mClientText->setVisible(self->mShrunk);
  308. // self->mClientCause->setVisible(self->mShrunk);
  309. // self->getChildView("client_help")->setVisible( self->mShrunk);
  310. // self->mNetworkText->setVisible(self->mShrunk);
  311. // self->mNetworkCause->setVisible(self->mShrunk);
  312. // self->getChildView("network_help")->setVisible( self->mShrunk);
  313. // self->mServerText->setVisible(self->mShrunk);
  314. // self->mServerCause->setVisible(self->mShrunk);
  315. // self->getChildView("server_help")->setVisible( self->mShrunk);
  316. // self->mShrunk = !self->mShrunk;
  317. }
  318. BOOL LLFloaterLagMeter::isShrunk()
  319. {
  320. return gSavedSettings.getBOOL("LagMeterShrunk");
  321. }
  322. void LLFloaterLagMeter::onClickShrink() // toggle "LagMeterShrunk"
  323. {
  324. bool shrunk = isShrunk();
  325. updateControls(!shrunk);
  326. gSavedSettings.setBOOL("LagMeterShrunk", !shrunk);
  327. }