PageRenderTime 55ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/llviewerwindow.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2155 lines | 1535 code | 363 blank | 257 comment | 167 complexity | 6b7f3bab0bbe41db25b1413e2a8947f2 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewerwindow.cpp
  3. * @brief Implementation of the LLViewerWindow class.
  4. *
  5. * $LicenseInfo:firstyear=2001&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 "llviewerwindow.h"
  28. #if LL_WINDOWS
  29. #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
  30. #endif
  31. // system library includes
  32. #include <stdio.h>
  33. #include <iostream>
  34. #include <fstream>
  35. #include <algorithm>
  36. #include <boost/lambda/core.hpp>
  37. #include "llagent.h"
  38. #include "llagentcamera.h"
  39. #include "llfloaterreg.h"
  40. #include "llmeshrepository.h"
  41. #include "llpanellogin.h"
  42. #include "llviewerkeyboard.h"
  43. #include "llviewermenu.h"
  44. #include "llviewquery.h"
  45. #include "llxmltree.h"
  46. #include "llslurl.h"
  47. //#include "llviewercamera.h"
  48. #include "llrender.h"
  49. #include "llvoiceclient.h" // for push-to-talk button handling
  50. //
  51. // TODO: Many of these includes are unnecessary. Remove them.
  52. //
  53. // linden library includes
  54. #include "llaudioengine.h" // mute on minimize
  55. #include "indra_constants.h"
  56. #include "llassetstorage.h"
  57. #include "llerrorcontrol.h"
  58. #include "llfontgl.h"
  59. #include "llmousehandler.h"
  60. #include "llrect.h"
  61. #include "llsky.h"
  62. #include "llstring.h"
  63. #include "llui.h"
  64. #include "lluuid.h"
  65. #include "llview.h"
  66. #include "llxfermanager.h"
  67. #include "message.h"
  68. #include "object_flags.h"
  69. #include "lltimer.h"
  70. #include "timing.h"
  71. #include "llviewermenu.h"
  72. #include "lltooltip.h"
  73. #include "llmediaentry.h"
  74. #include "llurldispatcher.h"
  75. #include "raytrace.h"
  76. // newview includes
  77. #include "llagent.h"
  78. #include "llbox.h"
  79. #include "llchicletbar.h"
  80. #include "llconsole.h"
  81. #include "llviewercontrol.h"
  82. #include "llcylinder.h"
  83. #include "lldebugview.h"
  84. #include "lldir.h"
  85. #include "lldrawable.h"
  86. #include "lldrawpoolalpha.h"
  87. #include "lldrawpoolbump.h"
  88. #include "lldrawpoolwater.h"
  89. #include "llmaniptranslate.h"
  90. #include "llface.h"
  91. #include "llfeaturemanager.h"
  92. #include "llfilepicker.h"
  93. #include "llfirstuse.h"
  94. #include "llfloater.h"
  95. #include "llfloaterbuildoptions.h"
  96. #include "llfloaterbuyland.h"
  97. #include "llfloatercamera.h"
  98. #include "llfloaterland.h"
  99. #include "llfloaterinspect.h"
  100. #include "llfloatermap.h"
  101. #include "llfloaternamedesc.h"
  102. #include "llfloaterpreference.h"
  103. #include "llfloatersnapshot.h"
  104. #include "llfloatertools.h"
  105. #include "llfloaterworldmap.h"
  106. #include "llfocusmgr.h"
  107. #include "llfontfreetype.h"
  108. #include "llgesturemgr.h"
  109. #include "llglheaders.h"
  110. #include "lltooltip.h"
  111. #include "llhudmanager.h"
  112. #include "llhudobject.h"
  113. #include "llhudview.h"
  114. #include "llimagebmp.h"
  115. #include "llimagej2c.h"
  116. #include "llimageworker.h"
  117. #include "llkeyboard.h"
  118. #include "lllineeditor.h"
  119. #include "llmenugl.h"
  120. #include "llmodaldialog.h"
  121. #include "llmorphview.h"
  122. #include "llmoveview.h"
  123. #include "llnavigationbar.h"
  124. #include "llpaneltopinfobar.h"
  125. #include "llpopupview.h"
  126. #include "llpreviewtexture.h"
  127. #include "llprogressview.h"
  128. #include "llresmgr.h"
  129. #include "llselectmgr.h"
  130. #include "llrootview.h"
  131. #include "llrendersphere.h"
  132. #include "llstartup.h"
  133. #include "llstatusbar.h"
  134. #include "llstatview.h"
  135. #include "llsurface.h"
  136. #include "llsurfacepatch.h"
  137. #include "lltexlayer.h"
  138. #include "lltextbox.h"
  139. #include "lltexturecache.h"
  140. #include "lltexturefetch.h"
  141. #include "lltextureview.h"
  142. #include "lltool.h"
  143. #include "lltoolbarview.h"
  144. #include "lltoolcomp.h"
  145. #include "lltooldraganddrop.h"
  146. #include "lltoolface.h"
  147. #include "lltoolfocus.h"
  148. #include "lltoolgrab.h"
  149. #include "lltoolmgr.h"
  150. #include "lltoolmorph.h"
  151. #include "lltoolpie.h"
  152. #include "lltoolselectland.h"
  153. #include "lltrans.h"
  154. #include "lluictrlfactory.h"
  155. #include "llurldispatcher.h" // SLURL from other app instance
  156. #include "llversioninfo.h"
  157. #include "llvieweraudio.h"
  158. #include "llviewercamera.h"
  159. #include "llviewergesture.h"
  160. #include "llviewertexturelist.h"
  161. #include "llviewerinventory.h"
  162. #include "llviewerkeyboard.h"
  163. #include "llviewermedia.h"
  164. #include "llviewermediafocus.h"
  165. #include "llviewermenu.h"
  166. #include "llviewermessage.h"
  167. #include "llviewerobjectlist.h"
  168. #include "llviewerparcelmgr.h"
  169. #include "llviewerregion.h"
  170. #include "llviewershadermgr.h"
  171. #include "llviewerstats.h"
  172. #include "llvoavatarself.h"
  173. #include "llvovolume.h"
  174. #include "llworld.h"
  175. #include "llworldmapview.h"
  176. #include "pipeline.h"
  177. #include "llappviewer.h"
  178. #include "llviewerdisplay.h"
  179. #include "llspatialpartition.h"
  180. #include "llviewerjoystick.h"
  181. #include "llviewernetwork.h"
  182. #include "llpostprocess.h"
  183. #include "llnearbychatbar.h"
  184. #include "llagentui.h"
  185. #include "llwearablelist.h"
  186. #include "llnotifications.h"
  187. #include "llnotificationsutil.h"
  188. #include "llnotificationmanager.h"
  189. #include "llfloaternotificationsconsole.h"
  190. #include "llnearbychat.h"
  191. #include "llwindowlistener.h"
  192. #include "llviewerwindowlistener.h"
  193. #include "llpaneltopinfobar.h"
  194. #if LL_WINDOWS
  195. #include <tchar.h> // For Unicode conversion methods
  196. #endif
  197. //
  198. // Globals
  199. //
  200. void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
  201. extern BOOL gDebugClicks;
  202. extern BOOL gDisplaySwapBuffers;
  203. extern BOOL gDepthDirty;
  204. extern BOOL gResizeScreenTexture;
  205. LLViewerWindow *gViewerWindow = NULL;
  206. LLFrameTimer gAwayTimer;
  207. LLFrameTimer gAwayTriggerTimer;
  208. BOOL gShowOverlayTitle = FALSE;
  209. LLViewerObject* gDebugRaycastObject = NULL;
  210. LLVector3 gDebugRaycastIntersection;
  211. LLVector2 gDebugRaycastTexCoord;
  212. LLVector3 gDebugRaycastNormal;
  213. LLVector3 gDebugRaycastBinormal;
  214. S32 gDebugRaycastFaceHit;
  215. LLVector3 gDebugRaycastStart;
  216. LLVector3 gDebugRaycastEnd;
  217. // HUD display lines in lower right
  218. BOOL gDisplayWindInfo = FALSE;
  219. BOOL gDisplayCameraPos = FALSE;
  220. BOOL gDisplayFOV = FALSE;
  221. BOOL gDisplayBadge = FALSE;
  222. static const U8 NO_FACE = 255;
  223. BOOL gQuietSnapshot = FALSE;
  224. static const F32 MIN_DISPLAY_SCALE = 0.75f;
  225. std::string LLViewerWindow::sSnapshotBaseName;
  226. std::string LLViewerWindow::sSnapshotDir;
  227. std::string LLViewerWindow::sMovieBaseName;
  228. class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>
  229. {
  230. public:
  231. virtual void recordMessage(LLError::ELevel level,
  232. const std::string& message)
  233. {
  234. //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread
  235. // only log warnings to chat console
  236. //if (level == LLError::LEVEL_WARN)
  237. //{
  238. //LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat");
  239. //if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat"))
  240. //{
  241. // LLChat chat;
  242. // chat.mText = message;
  243. // chat.mSourceType = CHAT_SOURCE_SYSTEM;
  244. // chat_floater->addChat(chat, FALSE, FALSE);
  245. //}
  246. //}
  247. }
  248. };
  249. ////////////////////////////////////////////////////////////////////////////
  250. //
  251. // LLDebugText
  252. //
  253. class LLDebugText
  254. {
  255. private:
  256. struct Line
  257. {
  258. Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {}
  259. std::string text;
  260. S32 x,y;
  261. };
  262. LLViewerWindow *mWindow;
  263. typedef std::vector<Line> line_list_t;
  264. line_list_t mLineList;
  265. LLColor4 mTextColor;
  266. void addText(S32 x, S32 y, const std::string &text)
  267. {
  268. mLineList.push_back(Line(text, x, y));
  269. }
  270. void clearText() { mLineList.clear(); }
  271. public:
  272. LLDebugText(LLViewerWindow* window) : mWindow(window) {}
  273. void update()
  274. {
  275. static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ;
  276. std::string wind_vel_text;
  277. std::string wind_vector_text;
  278. std::string rwind_vel_text;
  279. std::string rwind_vector_text;
  280. std::string audio_text;
  281. static const std::string beacon_particle = LLTrans::getString("BeaconParticle");
  282. static const std::string beacon_physical = LLTrans::getString("BeaconPhysical");
  283. static const std::string beacon_scripted = LLTrans::getString("BeaconScripted");
  284. static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch");
  285. static const std::string beacon_sound = LLTrans::getString("BeaconSound");
  286. static const std::string beacon_media = LLTrans::getString("BeaconMedia");
  287. static const std::string particle_hiding = LLTrans::getString("ParticleHiding");
  288. // Draw the statistics in a light gray
  289. // and in a thin font
  290. mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
  291. // Draw stuff growing up from right lower corner of screen
  292. U32 xpos = mWindow->getWorldViewWidthScaled() - 350;
  293. U32 ypos = 64;
  294. const U32 y_inc = 20;
  295. clearText();
  296. if (gSavedSettings.getBOOL("DebugShowTime"))
  297. {
  298. const U32 y_inc2 = 15;
  299. for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin();
  300. iter != gDebugTimers.rend(); ++iter)
  301. {
  302. S32 idx = iter->first;
  303. LLFrameTimer& timer = iter->second;
  304. F32 time = timer.getElapsedTimeF32();
  305. S32 hours = (S32)(time / (60*60));
  306. S32 mins = (S32)((time - hours*(60*60)) / 60);
  307. S32 secs = (S32)((time - hours*(60*60) - mins*60));
  308. std::string label = gDebugTimerLabel[idx];
  309. if (label.empty()) label = llformat("Debug: %d", idx);
  310. addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2;
  311. }
  312. F32 time = gFrameTimeSeconds;
  313. S32 hours = (S32)(time / (60*60));
  314. S32 mins = (S32)((time - hours*(60*60)) / 60);
  315. S32 secs = (S32)((time - hours*(60*60) - mins*60));
  316. addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
  317. }
  318. #if LL_WINDOWS
  319. if (gSavedSettings.getBOOL("DebugShowMemory"))
  320. {
  321. addText(xpos, ypos, llformat("Memory: %d (KB)", LLMemory::getWorkingSetSize() / 1024));
  322. ypos += y_inc;
  323. }
  324. #endif
  325. if (gDisplayCameraPos)
  326. {
  327. std::string camera_view_text;
  328. std::string camera_center_text;
  329. std::string agent_view_text;
  330. std::string agent_left_text;
  331. std::string agent_center_text;
  332. std::string agent_root_center_text;
  333. LLVector3d tvector; // Temporary vector to hold data for printing.
  334. // Update camera center, camera view, wind info every other frame
  335. tvector = gAgent.getPositionGlobal();
  336. agent_center_text = llformat("AgentCenter %f %f %f",
  337. (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
  338. if (isAgentAvatarValid())
  339. {
  340. tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
  341. agent_root_center_text = llformat("AgentRootCenter %f %f %f",
  342. (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
  343. }
  344. else
  345. {
  346. agent_root_center_text = "---";
  347. }
  348. tvector = LLVector4(gAgent.getFrameAgent().getAtAxis());
  349. agent_view_text = llformat("AgentAtAxis %f %f %f",
  350. (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
  351. tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis());
  352. agent_left_text = llformat("AgentLeftAxis %f %f %f",
  353. (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
  354. tvector = gAgentCamera.getCameraPositionGlobal();
  355. camera_center_text = llformat("CameraCenter %f %f %f",
  356. (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
  357. tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis());
  358. camera_view_text = llformat("CameraAtAxis %f %f %f",
  359. (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
  360. addText(xpos, ypos, agent_center_text); ypos += y_inc;
  361. addText(xpos, ypos, agent_root_center_text); ypos += y_inc;
  362. addText(xpos, ypos, agent_view_text); ypos += y_inc;
  363. addText(xpos, ypos, agent_left_text); ypos += y_inc;
  364. addText(xpos, ypos, camera_center_text); ypos += y_inc;
  365. addText(xpos, ypos, camera_view_text); ypos += y_inc;
  366. }
  367. if (gDisplayWindInfo)
  368. {
  369. wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec());
  370. wind_vector_text = llformat("Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]);
  371. rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec());
  372. rwind_vector_text = llformat("RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]);
  373. addText(xpos, ypos, wind_vel_text); ypos += y_inc;
  374. addText(xpos, ypos, wind_vector_text); ypos += y_inc;
  375. addText(xpos, ypos, rwind_vel_text); ypos += y_inc;
  376. addText(xpos, ypos, rwind_vector_text); ypos += y_inc;
  377. }
  378. if (gDisplayWindInfo)
  379. {
  380. if (gAudiop)
  381. {
  382. audio_text= llformat("Audio for wind: %d", gAudiop->isWindEnabled());
  383. }
  384. addText(xpos, ypos, audio_text); ypos += y_inc;
  385. }
  386. if (gDisplayFOV)
  387. {
  388. addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
  389. ypos += y_inc;
  390. }
  391. if (gDisplayBadge)
  392. {
  393. addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
  394. ypos += y_inc * 2;
  395. }
  396. /*if (LLViewerJoystick::getInstance()->getOverrideCamera())
  397. {
  398. addText(xpos + 200, ypos, llformat("Flycam"));
  399. ypos += y_inc;
  400. }*/
  401. if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
  402. {
  403. if (gPipeline.getUseVertexShaders() == 0)
  404. {
  405. addText(xpos, ypos, "Shaders Disabled");
  406. ypos += y_inc;
  407. }
  408. if (gGLManager.mHasATIMemInfo)
  409. {
  410. S32 meminfo[4];
  411. glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
  412. addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f));
  413. ypos += y_inc;
  414. if (gGLManager.mHasVertexBufferObject)
  415. {
  416. glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo);
  417. addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f));
  418. ypos += y_inc;
  419. }
  420. }
  421. else if (gGLManager.mHasNVXMemInfo)
  422. {
  423. S32 free_memory;
  424. glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
  425. addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f));
  426. ypos += y_inc;
  427. }
  428. //show streaming cost/triangle count of known prims in current region OR selection
  429. {
  430. F32 cost = 0.f;
  431. S32 count = 0;
  432. S32 vcount = 0;
  433. S32 object_count = 0;
  434. S32 total_bytes = 0;
  435. S32 visible_bytes = 0;
  436. const char* label = "Region";
  437. if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0)
  438. { //region
  439. LLViewerRegion* region = gAgent.getRegion();
  440. if (region)
  441. {
  442. for (U32 i = 0; i < gObjectList.getNumObjects(); ++i)
  443. {
  444. LLViewerObject* object = gObjectList.getObject(i);
  445. if (object &&
  446. object->getRegion() == region &&
  447. object->getVolume())
  448. {
  449. object_count++;
  450. S32 bytes = 0;
  451. S32 visible = 0;
  452. cost += object->getStreamingCost(&bytes, &visible);
  453. S32 vt = 0;
  454. count += object->getTriangleCount(&vt);
  455. vcount += vt;
  456. total_bytes += bytes;
  457. visible_bytes += visible;
  458. }
  459. }
  460. }
  461. }
  462. else
  463. {
  464. label = "Selection";
  465. cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes);
  466. count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount);
  467. object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
  468. }
  469. addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost));
  470. ypos += y_inc;
  471. addText(xpos, ypos, llformat(" %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects",
  472. count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));
  473. ypos += y_inc;
  474. }
  475. addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024)));
  476. ypos += y_inc;
  477. addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
  478. ypos += y_inc;
  479. addText(xpos, ypos, llformat("%d Mapped Buffers", LLVertexBuffer::sMappedCount));
  480. ypos += y_inc;
  481. addText(xpos, ypos, llformat("%d Vertex Buffer Binds", LLVertexBuffer::sBindCount));
  482. ypos += y_inc;
  483. addText(xpos, ypos, llformat("%d Vertex Buffer Sets", LLVertexBuffer::sSetCount));
  484. ypos += y_inc;
  485. addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount));
  486. ypos += y_inc;
  487. addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
  488. ypos += y_inc;
  489. addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount));
  490. ypos += y_inc;
  491. addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount));
  492. ypos += y_inc;
  493. addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps));
  494. ypos += y_inc;
  495. gPipeline.mTextureMatrixOps = 0;
  496. gPipeline.mMatrixOpCount = 0;
  497. if (gPipeline.mBatchCount > 0)
  498. {
  499. addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize,
  500. gPipeline.mTrianglesDrawn/gPipeline.mBatchCount));
  501. gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize;
  502. gPipeline.mMaxBatchSize = 0;
  503. gPipeline.mBatchCount = 0;
  504. }
  505. ypos += y_inc;
  506. addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls));
  507. LLRender::sUICalls = LLRender::sUIVerts = 0;
  508. ypos += y_inc;
  509. addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount));
  510. ypos += y_inc;
  511. if (!LLSpatialGroup::sPendingQueries.empty())
  512. {
  513. addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size()));
  514. ypos += y_inc;
  515. }
  516. addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars));
  517. ypos += y_inc;
  518. addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount));
  519. ypos += y_inc;
  520. if (gMeshRepo.meshRezEnabled())
  521. {
  522. addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
  523. ypos += y_inc;
  524. addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
  525. LLMeshRepository::sHTTPRetryCount));
  526. ypos += y_inc;
  527. addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
  528. ypos += y_inc;
  529. }
  530. LLVertexBuffer::sBindCount = LLImageGL::sBindCount =
  531. LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount =
  532. gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
  533. }
  534. if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
  535. {
  536. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
  537. ypos += y_inc;
  538. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11]));
  539. ypos += y_inc;
  540. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7]));
  541. ypos += y_inc;
  542. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3]));
  543. ypos += y_inc;
  544. addText(xpos, ypos, "Projection Matrix");
  545. ypos += y_inc;
  546. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15]));
  547. ypos += y_inc;
  548. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11]));
  549. ypos += y_inc;
  550. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7]));
  551. ypos += y_inc;
  552. addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3]));
  553. ypos += y_inc;
  554. addText(xpos, ypos, "View Matrix");
  555. ypos += y_inc;
  556. }
  557. if (gSavedSettings.getBOOL("DebugShowColor"))
  558. {
  559. U8 color[4];
  560. LLCoordGL coord = gViewerWindow->getCurrentMouse();
  561. glReadPixels(coord.mX, coord.mY, 1,1,GL_RGBA, GL_UNSIGNED_BYTE, color);
  562. addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));
  563. ypos += y_inc;
  564. }
  565. if (gSavedSettings.getBOOL("DebugShowPrivateMem"))
  566. {
  567. LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;
  568. addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024));
  569. ypos += y_inc;
  570. addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024));
  571. ypos += y_inc;
  572. }
  573. // only display these messages if we are actually rendering beacons at this moment
  574. if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))
  575. {
  576. if (LLPipeline::getRenderMOAPBeacons(NULL))
  577. {
  578. addText(xpos, ypos, "Viewing media beacons (white)");
  579. ypos += y_inc;
  580. }
  581. if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES))
  582. {
  583. addText(xpos, ypos, particle_hiding);
  584. ypos += y_inc;
  585. }
  586. if (LLPipeline::getRenderParticleBeacons(NULL))
  587. {
  588. addText(xpos, ypos, "Viewing particle beacons (blue)");
  589. ypos += y_inc;
  590. }
  591. if (LLPipeline::getRenderSoundBeacons(NULL))
  592. {
  593. addText(xpos, ypos, "Viewing sound beacons (yellow)");
  594. ypos += y_inc;
  595. }
  596. if (LLPipeline::getRenderScriptedBeacons(NULL))
  597. {
  598. addText(xpos, ypos, beacon_scripted);
  599. ypos += y_inc;
  600. }
  601. else
  602. if (LLPipeline::getRenderScriptedTouchBeacons(NULL))
  603. {
  604. addText(xpos, ypos, beacon_scripted_touch);
  605. ypos += y_inc;
  606. }
  607. if (LLPipeline::getRenderPhysicalBeacons(NULL))
  608. {
  609. addText(xpos, ypos, "Viewing physical object beacons (green)");
  610. ypos += y_inc;
  611. }
  612. }
  613. if(log_texture_traffic)
  614. {
  615. U32 old_y = ypos ;
  616. for(S32 i = LLViewerTexture::BOOST_NONE; i < LLViewerTexture::MAX_GL_IMAGE_CATEGORY; i++)
  617. {
  618. if(gTotalTextureBytesPerBoostLevel[i] > 0)
  619. {
  620. addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, (F32)gTotalTextureBytesPerBoostLevel[i] / (1024 * 1024)));
  621. ypos += y_inc;
  622. }
  623. }
  624. if(ypos != old_y)
  625. {
  626. addText(xpos, ypos, "Network traffic for textures:");
  627. ypos += y_inc;
  628. }
  629. }
  630. if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
  631. {
  632. LLViewerObject* objectp = NULL ;
  633. //objectp = = gAgentCamera.getFocusObject();
  634. LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
  635. if (nodep)
  636. {
  637. objectp = nodep->getObject();
  638. }
  639. if (objectp && !objectp->isDead())
  640. {
  641. S32 num_faces = objectp->mDrawable->getNumFaces() ;
  642. for(S32 i = 0 ; i < num_faces; i++)
  643. {
  644. LLFace* facep = objectp->mDrawable->getFace(i) ;
  645. if(facep)
  646. {
  647. //addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0],
  648. // facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1]));
  649. //ypos += y_inc;
  650. addText(xpos, ypos, llformat("v_size: %.3f: p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea()));
  651. ypos += y_inc;
  652. //const LLTextureEntry *tep = facep->getTextureEntry();
  653. //if(tep)
  654. //{
  655. // addText(xpos, ypos, llformat("scale_s: %.3f: scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ;
  656. // ypos += y_inc;
  657. //}
  658. LLViewerTexture* tex = facep->getTexture() ;
  659. if(tex)
  660. {
  661. addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize()));
  662. ypos += y_inc;
  663. }
  664. }
  665. }
  666. }
  667. }
  668. }
  669. void draw()
  670. {
  671. for (line_list_t::iterator iter = mLineList.begin();
  672. iter != mLineList.end(); ++iter)
  673. {
  674. const Line& line = *iter;
  675. LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
  676. LLFontGL::LEFT, LLFontGL::TOP,
  677. LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
  678. }
  679. mLineList.clear();
  680. }
  681. };
  682. void LLViewerWindow::updateDebugText()
  683. {
  684. mDebugText->update();
  685. }
  686. ////////////////////////////////////////////////////////////////////////////
  687. //
  688. // LLViewerWindow
  689. //
  690. LLViewerWindow::Params::Params()
  691. : title("title"),
  692. name("name"),
  693. x("x"),
  694. y("y"),
  695. width("width"),
  696. height("height"),
  697. min_width("min_width"),
  698. min_height("min_height"),
  699. fullscreen("fullscreen", false),
  700. ignore_pixel_depth("ignore_pixel_depth", false)
  701. {}
  702. BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
  703. {
  704. const char* buttonname = "";
  705. const char* buttonstatestr = "";
  706. S32 x = pos.mX;
  707. S32 y = pos.mY;
  708. x = llround((F32)x / mDisplayScale.mV[VX]);
  709. y = llround((F32)y / mDisplayScale.mV[VY]);
  710. // only send mouse clicks to UI if UI is visible
  711. if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
  712. {
  713. if (down)
  714. {
  715. buttonstatestr = "down" ;
  716. }
  717. else
  718. {
  719. buttonstatestr = "up" ;
  720. }
  721. switch (clicktype)
  722. {
  723. case LLMouseHandler::CLICK_LEFT:
  724. mLeftMouseDown = down;
  725. buttonname = "Left";
  726. break;
  727. case LLMouseHandler::CLICK_RIGHT:
  728. mRightMouseDown = down;
  729. buttonname = "Right";
  730. break;
  731. case LLMouseHandler::CLICK_MIDDLE:
  732. mMiddleMouseDown = down;
  733. buttonname = "Middle";
  734. break;
  735. case LLMouseHandler::CLICK_DOUBLELEFT:
  736. mLeftMouseDown = down;
  737. buttonname = "Left Double Click";
  738. break;
  739. }
  740. LLView::sMouseHandlerMessage.clear();
  741. if (gMenuBarView)
  742. {
  743. // stop ALT-key access to menu
  744. gMenuBarView->resetMenuTrigger();
  745. }
  746. if (gDebugClicks)
  747. {
  748. llinfos << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << llendl;
  749. }
  750. // Make sure we get a corresponding mouseup event, even if the mouse leaves the window
  751. if (down)
  752. mWindow->captureMouse();
  753. else
  754. mWindow->releaseMouse();
  755. // Indicate mouse was active
  756. LLUI::resetMouseIdleTimer();
  757. // Don't let the user move the mouse out of the window until mouse up.
  758. if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
  759. {
  760. mWindow->setMouseClipping(down);
  761. }
  762. LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
  763. if( mouse_captor )
  764. {
  765. S32 local_x;
  766. S32 local_y;
  767. mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
  768. if (LLView::sDebugMouseHandling)
  769. {
  770. llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl;
  771. }
  772. return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
  773. }
  774. // Topmost view gets a chance before the hierarchy
  775. //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
  776. //if (top_ctrl)
  777. //{
  778. // S32 local_x, local_y;
  779. // top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
  780. // if (top_ctrl->pointInView(local_x, local_y))
  781. // {
  782. // return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
  783. // }
  784. // else
  785. // {
  786. // if (down)
  787. // {
  788. // gFocusMgr.setTopCtrl(NULL);
  789. // }
  790. // }
  791. //}
  792. // Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
  793. if( !mRootView->pointInView(x, y) )
  794. {
  795. return TRUE;
  796. }
  797. // Give the UI views a chance to process the click
  798. if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
  799. {
  800. if (LLView::sDebugMouseHandling)
  801. {
  802. llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl;
  803. }
  804. return TRUE;
  805. }
  806. else if (LLView::sDebugMouseHandling)
  807. {
  808. llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
  809. }
  810. }
  811. // Do not allow tool manager to handle mouseclicks if we have disconnected
  812. if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
  813. {
  814. return TRUE;
  815. }
  816. // If we got this far on a down-click, it wasn't handled.
  817. // Up-clicks, though, are always handled as far as the OS is concerned.
  818. BOOL default_rtn = !down;
  819. return default_rtn;
  820. }
  821. BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
  822. {
  823. BOOL down = TRUE;
  824. return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
  825. }
  826. BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
  827. {
  828. // try handling as a double-click first, then a single-click if that
  829. // wasn't handled.
  830. BOOL down = TRUE;
  831. if (handleAnyMouseClick(window, pos, mask,
  832. LLMouseHandler::CLICK_DOUBLELEFT, down))
  833. {
  834. return TRUE;
  835. }
  836. return handleMouseDown(window, pos, mask);
  837. }
  838. BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
  839. {
  840. BOOL down = FALSE;
  841. return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
  842. }
  843. BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
  844. {
  845. S32 x = pos.mX;
  846. S32 y = pos.mY;
  847. x = llround((F32)x / mDisplayScale.mV[VX]);
  848. y = llround((F32)y / mDisplayScale.mV[VY]);
  849. BOOL down = TRUE;
  850. BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
  851. if (handle)
  852. return handle;
  853. // *HACK: this should be rolled into the composite tool logic, not
  854. // hardcoded at the top level.
  855. if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance())
  856. {
  857. // If the current tool didn't process the click, we should show
  858. // the pie menu. This can be done by passing the event to the pie
  859. // menu tool.
  860. LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
  861. // show_context_menu( x, y, mask );
  862. }
  863. return TRUE;
  864. }
  865. BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
  866. {
  867. BOOL down = FALSE;
  868. return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
  869. }
  870. BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
  871. {
  872. BOOL down = TRUE;
  873. LLVoiceClient::getInstance()->middleMouseState(true);
  874. handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
  875. // Always handled as far as the OS is concerned.
  876. return TRUE;
  877. }
  878. LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data)
  879. {
  880. LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE;
  881. const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop");
  882. const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop");
  883. if ( prim_media_dnd_enabled || slurl_dnd_enabled )
  884. {
  885. switch(action)
  886. {
  887. // Much of the handling for these two cases is the same.
  888. case LLWindowCallbacks::DNDA_TRACK:
  889. case LLWindowCallbacks::DNDA_DROPPED:
  890. case LLWindowCallbacks::DNDA_START_TRACKING:
  891. {
  892. bool drop = (LLWindowCallbacks::DNDA_DROPPED == action);
  893. if (slurl_dnd_enabled)
  894. {
  895. LLSLURL dropped_slurl(data);
  896. if(dropped_slurl.isSpatial())
  897. {
  898. if (drop)
  899. {
  900. LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), "clicked", NULL, true );
  901. return LLWindowCallbacks::DND_MOVE;
  902. }
  903. return LLWindowCallbacks::DND_COPY;
  904. }
  905. }
  906. if (prim_media_dnd_enabled)
  907. {
  908. LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ );
  909. LLUUID object_id = pick_info.getObjectID();
  910. S32 object_face = pick_info.mObjectFace;
  911. std::string url = data;
  912. lldebugs << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << llendl;
  913. LLVOVolume *obj = dynamic_cast<LLVOVolume*>(static_cast<LLViewerObject*>(pick_info.getObject()));
  914. if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty())
  915. {
  916. LLTextureEntry *te = obj->getTE(object_face);
  917. // can modify URL if we can modify the object or we have navigate permissions
  918. bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT );
  919. if (te && allow_modify_url )
  920. {
  921. if (drop)
  922. {
  923. // object does NOT have media already
  924. if ( ! te->hasMedia() )
  925. {
  926. // we are allowed to modify the object
  927. if ( obj->permModify() )
  928. {
  929. // Create new media entry
  930. LLSD media_data;
  931. // XXX Should we really do Home URL too?
  932. media_data[LLMediaEntry::HOME_URL_KEY] = url;
  933. media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
  934. media_data[LLMediaEntry::AUTO_PLAY_KEY] = true;
  935. obj->syncMediaData(object_face, media_data, true, true);
  936. // XXX This shouldn't be necessary, should it ?!?
  937. if (obj->getMediaImpl(object_face))
  938. obj->getMediaImpl(object_face)->navigateReload();
  939. obj->sendMediaDataUpdate();
  940. result = LLWindowCallbacks::DND_COPY;
  941. }
  942. }
  943. else
  944. // object HAS media already
  945. {
  946. // URL passes the whitelist
  947. if (te->getMediaData()->checkCandidateUrl( url ) )
  948. {
  949. // just navigate to the URL
  950. if (obj->getMediaImpl(object_face))
  951. {
  952. obj->getMediaImpl(object_face)->navigateTo(url);
  953. }
  954. else
  955. {
  956. // This is very strange. Navigation should
  957. // happen via the Impl, but we don't have one.
  958. // This sends it to the server, which /should/
  959. // trigger us getting it. Hopefully.
  960. LLSD media_data;
  961. media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
  962. obj->syncMediaData(object_face, media_data, true, true);
  963. obj->sendMediaDataUpdate();
  964. }
  965. result = LLWindowCallbacks::DND_LINK;
  966. }
  967. }
  968. LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
  969. mDragHoveredObject = NULL;
  970. }
  971. else
  972. {
  973. // Check the whitelist, if there's media (otherwise just show it)
  974. if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
  975. {
  976. if ( obj != mDragHoveredObject)
  977. {
  978. // Highlight the dragged object
  979. LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
  980. mDragHoveredObject = obj;
  981. LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject);
  982. }
  983. result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK;
  984. }
  985. }
  986. }
  987. }
  988. }
  989. }
  990. break;
  991. case LLWindowCallbacks::DNDA_STOP_TRACKING:
  992. // The cleanup case below will make sure things are unhilighted if necessary.
  993. break;
  994. }
  995. if (prim_media_dnd_enabled &&
  996. result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull())
  997. {
  998. LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
  999. mDragHoveredObject = NULL;
  1000. }
  1001. }
  1002. return result;
  1003. }
  1004. BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
  1005. {
  1006. BOOL down = FALSE;
  1007. LLVoiceClient::getInstance()->middleMouseState(false);
  1008. handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
  1009. // Always handled as far as the OS is concerned.
  1010. return TRUE;
  1011. }
  1012. // WARNING: this is potentially called multiple times per frame
  1013. void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
  1014. {
  1015. S32 x = pos.mX;
  1016. S32 y = pos.mY;
  1017. x = llround((F32)x / mDisplayScale.mV[VX]);
  1018. y = llround((F32)y / mDisplayScale.mV[VY]);
  1019. mMouseInWindow = TRUE;
  1020. // Save mouse point for access during idle() and display()
  1021. LLCoordGL mouse_point(x, y);
  1022. if (mouse_point != mCurrentMousePoint)
  1023. {
  1024. LLUI::resetMouseIdleTimer();
  1025. }
  1026. saveLastMouse(mouse_point);
  1027. mWindow->showCursorFromMouseMove();
  1028. if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME
  1029. && !gDisconnected)
  1030. {
  1031. gAgent.clearAFK();
  1032. }
  1033. }
  1034. void LLViewerWindow::handleMouseLeave(LLWindow *window)
  1035. {
  1036. // Note: we won't get this if we have captured the mouse.
  1037. llassert( gFocusMgr.getMouseCapture() == NULL );
  1038. mMouseInWindow = FALSE;
  1039. LLToolTipMgr::instance().blockToolTips();
  1040. }
  1041. BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
  1042. {
  1043. // User has indicated they want to close, but we may need to ask
  1044. // about modified documents.
  1045. LLAppViewer::instance()->userQuit();
  1046. // Don't quit immediately
  1047. return FALSE;
  1048. }
  1049. void LLViewerWindow::handleQuit(LLWindow *window)
  1050. {
  1051. LLAppViewer::instance()->forceQuit();
  1052. }
  1053. void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height)
  1054. {
  1055. reshape(width, height);
  1056. mResDirty = true;
  1057. }
  1058. // The top-level window has gained focus (e.g. via ALT-TAB)
  1059. void LLViewerWindow::handleFocus(LLWindow *window)
  1060. {
  1061. gFocusMgr.setAppHasFocus(TRUE);
  1062. LLModalDialog::onAppFocusGained();
  1063. gAgent.onAppFocusGained();
  1064. LLToolMgr::getInstance()->onAppFocusGained();
  1065. // See if we're coming in with modifier keys held down
  1066. if (gKeyboard)
  1067. {
  1068. gKeyboard->resetMaskKeys();
  1069. }
  1070. // resume foreground running timer
  1071. // since we artifically limit framerate when not frontmost
  1072. gForegroundTime.unpause();
  1073. }
  1074. // The top-level window has lost focus (e.g. via ALT-TAB)
  1075. void LLViewerWindow::handleFocusLost(LLWindow *window)
  1076. {
  1077. gFocusMgr.setAppHasFocus(FALSE);
  1078. //LLModalDialog::onAppFocusLost();
  1079. LLToolMgr::getInstance()->onAppFocusLost();
  1080. gFocusMgr.setMouseCapture( NULL );
  1081. if (gMenuBarView)
  1082. {
  1083. // stop ALT-key access to menu
  1084. gMenuBarView->resetMenuTrigger();
  1085. }
  1086. // restore mouse cursor
  1087. showCursor();
  1088. getWindow()->setMouseClipping(FALSE);
  1089. // If losing focus while keys are down, reset them.
  1090. if (gKeyboard)
  1091. {
  1092. gKeyboard->resetKeys();
  1093. }
  1094. // pause timer that tracks total foreground running time
  1095. gForegroundTime.pause();
  1096. }
  1097. BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
  1098. {
  1099. // Let the voice chat code check for its PTT key. Note that this never affects event processing.
  1100. LLVoiceClient::getInstance()->keyDown(key, mask);
  1101. if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
  1102. {
  1103. gAgent.clearAFK();
  1104. }
  1105. // *NOTE: We want to interpret KEY_RETURN later when it arrives as
  1106. // a Unicode char, not as a keydown. Otherwise when client frame
  1107. // rate is really low, hitting return sends your chat text before
  1108. // it's all entered/processed.
  1109. if (key == KEY_RETURN && mask == MASK_NONE)
  1110. {
  1111. return FALSE;
  1112. }
  1113. return gViewerKeyboard.handleKey(key, mask, repeated);
  1114. }
  1115. BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
  1116. {
  1117. // Let the voice chat code check for its PTT key. Note that this never affects event processing.
  1118. LLVoiceClient::getInstance()->keyUp(key, mask);
  1119. return FALSE;
  1120. }
  1121. void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
  1122. {
  1123. LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
  1124. return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
  1125. }
  1126. BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
  1127. {
  1128. if (activated)
  1129. {
  1130. mActive = true;
  1131. send_agent_resume();
  1132. gAgent.clearAFK();
  1133. // Unmute audio
  1134. audio_update_volume();
  1135. }
  1136. else
  1137. {
  1138. mActive = false;
  1139. // if the user has chosen to go Away automatically after some time, then go Away when minimizing
  1140. if (gSavedSettings.getS32("AFKTimeout"))
  1141. {
  1142. gAgent.setAFK();
  1143. }
  1144. // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues
  1145. if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
  1146. {
  1147. gAgentCamera.changeCameraToDefault();
  1148. }
  1149. send_agent_pause();
  1150. // Mute audio
  1151. audio_update_volume();
  1152. }
  1153. return TRUE;
  1154. }
  1155. BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
  1156. {
  1157. //if (!activating) gAgentCamera.changeCameraToDefault();
  1158. LLViewerJoystick::getInstance()->setNeedsReset(true);
  1159. return FALSE;
  1160. }
  1161. void LLViewerWindow::handleMenuSelect(LLWindow *window, S32 menu_item)
  1162. {
  1163. }
  1164. BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height)
  1165. {
  1166. // *TODO: Enable similar information output for other platforms? DK 2011-02-18
  1167. #if LL_WINDOWS
  1168. if (gHeadlessClient)
  1169. {
  1170. HWND window_handle = (HWND)window->getPlatformWindow();
  1171. PAINTSTRUCT ps;
  1172. HDC hdc;
  1173. RECT wnd_rect;
  1174. wnd_rect.left = 0;
  1175. wnd_rect.top = 0;
  1176. wnd_rect.bottom = 200;
  1177. wnd_rect.right = 500;
  1178. hdc = BeginPaint(window_handle, &ps);
  1179. //SetBKColor(hdc, RGB(255, 255, 255));
  1180. FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
  1181. std::string temp_str;
  1182. temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
  1183. LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
  1184. LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
  1185. LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
  1186. S32 len = temp_str.length();
  1187. TextOutA(hdc, 0, 0, temp_str.c_str(), len);
  1188. LLVector3d pos_global = gAgent.getPositionGlobal();
  1189. temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
  1190. len = temp_str.length();
  1191. TextOutA(hdc, 0, 25, temp_str.c_str(), len);
  1192. TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61);
  1193. EndPaint(window_handle, &ps);
  1194. return TRUE;
  1195. }
  1196. #endif
  1197. return FALSE;
  1198. }
  1199. void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks)
  1200. {
  1201. handleScrollWheel( clicks );
  1202. }
  1203. void LLViewerWindow::handleWindowBlock(LLWindow *window)
  1204. {
  1205. send_agent_pause();
  1206. }
  1207. void LLViewerWindow::handleWindowUnblock(LLWindow *window)
  1208. {
  1209. send_agent_resume();
  1210. }
  1211. void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
  1212. {
  1213. const S32 SLURL_MESSAGE_TYPE = 0;
  1214. switch (data_type)
  1215. {
  1216. case SLURL_MESSAGE_TYPE:
  1217. // received URL
  1218. std::string url = (const char*)data;
  1219. LLMediaCtrl* web = NULL;
  1220. const bool trusted_browser = false;
  1221. // don't treat slapps coming from external browsers as "clicks" as this would bypass throttling
  1222. if (LLURLDispatcher::dispatch(url, "", web, trusted_browser))
  1223. {
  1224. // bring window to foreground, as it has just been "launched" from a URL
  1225. mWindow->bringToFront();
  1226. }
  1227. break;
  1228. }
  1229. }
  1230. BOOL LLViewerWindow::handleTimerEvent(LLWindow *window)
  1231. {
  1232. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  1233. {
  1234. LLViewerJoystick::getInstance()->updateStatus();
  1235. return TRUE;
  1236. }
  1237. return FALSE;
  1238. }
  1239. BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
  1240. {
  1241. // give a chance to use a joystick after startup (hot-plugging)
  1242. if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
  1243. {
  1244. LLViewerJoystick::getInstance()->init(true);
  1245. return TRUE;
  1246. }
  1247. return FALSE;
  1248. }
  1249. void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
  1250. {
  1251. LLAppViewer::instance()->pingMainloopTimeout(msg);
  1252. }
  1253. void LLViewerWindow::handleResumeWatchdog(LLWindow *window)
  1254. {
  1255. LLAppViewer::instance()->resumeMainloopTimeout();
  1256. }
  1257. void LLViewerWindow::handlePauseWatchdog(LLWindow *window)
  1258. {
  1259. LLAppViewer::instance()->pauseMainloopTimeout();
  1260. }
  1261. //virtual
  1262. std::string LLViewerWindow::translateString(const char* tag)
  1263. {
  1264. return LLTrans::getString( std::string(tag) );
  1265. }
  1266. //virtual
  1267. std::string LLViewerWindow::translateString(const char* tag,
  1268. const std::map<std::string, std::string>& args)
  1269. {
  1270. // LLTrans uses a special subclass of std::string for format maps,
  1271. // but we must use std::map<> in these callbacks, otherwise we create
  1272. // a dependency between LLWindow and LLFormatMapString. So copy the data.
  1273. LLStringUtil::format_map_t args_copy;
  1274. std::map<std::string,std::string>::const_iterator it = args.begin();
  1275. for ( ; it != args.end(); ++it)
  1276. {
  1277. args_copy[it->first] = it->second;
  1278. }
  1279. return LLTrans::getString( std::string(tag), args_copy);
  1280. }
  1281. //
  1282. // Classes
  1283. //
  1284. LLViewerWindow::LLViewerWindow(const Params& p)
  1285. : mWindow(NULL),
  1286. mActive(true),
  1287. mUIVisible(true),
  1288. mWindowRectRaw(0, p.height, p.width, 0),
  1289. mWindowRectScaled(0, p.height, p.width, 0),
  1290. mWorldViewRectRaw(0, p.height, p.width, 0),
  1291. mLeftMouseDown(FALSE),
  1292. mMiddleMouseDown(FALSE),
  1293. mRightMouseDown(FALSE),
  1294. mMouseInWindow( FALSE ),
  1295. mLastMask( MASK_NONE ),
  1296. mToolStored( NULL ),
  1297. mHideCursorPermanent( FALSE ),
  1298. mCursorHidden(FALSE),
  1299. mIgnoreActivate( FALSE ),
  1300. mResDirty(false),
  1301. mStatesDirty(false),
  1302. mCurrResolutionIndex(0),
  1303. // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
  1304. // pass its value right now. Instead, pass it a nullary function that
  1305. // will, when we later need it, return the value of gKeyboard.
  1306. // boost::lambda::var() constructs such a functor on the fly.
  1307. mWindowListener(new LLWindowListener(this, boost::lambda::var(gKeyboard))),
  1308. mViewerWindowListener(new LLViewerWindowListener(this)),
  1309. mProgressView(NULL)
  1310. {
  1311. LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
  1312. LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
  1313. LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
  1314. LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
  1315. LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
  1316. llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
  1317. // Default to application directory.
  1318. LLViewerWindow::sSnapshotBaseName = "Snapshot";
  1319. LLViewerWindow::sMovieBaseName = "SLmovie";
  1320. resetSnapshotLoc();
  1321. // create window
  1322. mWindow = LLWindowManager::createWindow(this,
  1323. p.title, p.name, p.x, p.y, p.width, p.height, 0,
  1324. p.fullscreen,
  1325. gHeadlessClient,
  1326. gSavedSettings.getBOOL("DisableVerticalSync"),
  1327. !gHeadlessClient,
  1328. p.ignore_pixel_depth,
  1329. gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
  1330. if (!LLViewerShaderMgr::sInitialized)
  1331. { //immediately initialize shaders
  1332. LLViewerShaderMgr::sInitialized = TRUE;
  1333. LLViewerShaderMgr::instance()->setShaders();
  1334. }
  1335. if (NULL == mWindow)
  1336. {
  1337. LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate"));
  1338. LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << llendl ;
  1339. ms_sleep(5000) ; //wait for 5 seconds.
  1340. LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
  1341. #if LL_LINUX || LL_SOLARIS
  1342. llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt or README-solaris.txt for further information."
  1343. << llendl;
  1344. #else
  1345. LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
  1346. << LL_ENDL;
  1347. #endif
  1348. LLAppViewer::instance()->fastQuit(1);
  1349. }
  1350. if (!LLAppViewer::instance()->restoreErrorTrap())
  1351. {
  1352. LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
  1353. }
  1354. const bool do_not_enforce = false;
  1355. mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce); // root view not set
  1356. LLCoordScreen scr;
  1357. mWindow->getSize(&scr);
  1358. if(p.fullscreen && ( scr.mX!=p.width || scr.mY!=p.height))
  1359. {
  1360. llwarns << "Fullscreen has forced us in to a different resolution now using "<<scr.mX<<" x "<<scr.mY<<llendl;
  1361. gSavedSettings.setS32("FullScreenWidth",scr.mX);
  1362. gSavedSettings.setS32("FullScreenHeight",scr.mY);
  1363. }
  1364. // Get the real window rect the window was created with (since there are various OS-dependent reasons why
  1365. // the size of a window or fullscreen context may have been adjusted slightly...)
  1366. F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
  1367. mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
  1368. mDisplayScale *= ui_scale_factor;
  1369. LLUI::setScaleFactor(mDisplayScale);
  1370. {
  1371. LLCoordWindow size;
  1372. mWindow->getSize(&size);
  1373. mWindowRectRaw.set(0, size.mY, size.mX, 0);
  1374. mWindowRectScaled.set(0, llround((F32)size.mY / mDisplayScale.mV[VY]), llround((F32)size.mX / mDisplayScale.mV[VX]), 0);
  1375. }
  1376. LLFontManager::initClass();
  1377. //
  1378. // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off
  1379. // stuff like AGP if we think that it'll crash the viewer.
  1380. //
  1381. LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
  1382. LLFeatureManager::getInstance()->init();
  1383. // Initialize OpenGL Renderer
  1384. if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
  1385. !gGLManager.mHasVertexBufferObject)
  1386. {
  1387. gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
  1388. }
  1389. LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
  1390. LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
  1391. gGL.init() ;
  1392. if (LLFeatureManager::getInstance()->isSafe()
  1393. || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
  1394. || (gSavedSettings.getString("LastGPUString") != LLFeatureManager::getInstance()->getGPUString())
  1395. || (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
  1396. {
  1397. LLFeatureManager::getInstance()->applyRecommendedSettings();
  1398. gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
  1399. }
  1400. if (!gGLManager.mHasDepthClamp)
  1401. {
  1402. LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
  1403. }
  1404. // If we crashed while initializng GL stuff last time, disable certain features
  1405. if (gSavedSettings.getBOOL("RenderInitError"))
  1406. {
  1407. mInitAlert = "DisplaySettingsNoShaders";
  1408. LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
  1409. gSavedSettings.setU32("RenderQualityPerformance", 0);
  1410. }
  1411. // Init the image list. Must happen after GL is initialized and before the images that
  1412. // LLViewerWindow needs are requested.
  1413. LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
  1414. gTextureList.init();
  1415. LLViewerTextureManager::init() ;
  1416. gBumpImageList.init();
  1417. // Init font system, but don't actually load the fonts yet
  1418. // because our window isn't onscreen and they take several
  1419. // seconds to parse.
  1420. LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
  1421. mDisplayScale.mV[VX],
  1422. mDisplayScale.mV[VY],
  1423. gDirUtilp->getAppRODataDir(),
  1424. LLUI::getXUIPaths());
  1425. // Create container for all sub-views
  1426. LLView::Params rvp;
  1427. rvp.name("root");
  1428. rvp.rect(mWindowRectScaled);
  1429. rvp.mouse_opaque(false);
  1430. rvp.follows.flags(FOLLOWS_NONE);
  1431. mRootView = LLUICtrlFactory::create<LLRootView>(rvp);
  1432. LLUI::setRootView(mRootView);
  1433. // Make avatar head look forward at start
  1434. mCurrentMousePoint.mX = getWindowWidthScaled() / 2;
  1435. mCurrentMousePoint.mY = getWindowHeightScaled() / 2;
  1436. gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");
  1437. mOverlayTitle = gSavedSettings.getString("OverlayTitle");
  1438. // Can't have spaces in settings.ini strings, so use underscores instead and convert them.
  1439. LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
  1440. // sync the keyboard's setting with the saved setting
  1441. gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
  1442. mDebugText = new LLDebugText(this);
  1443. mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
  1444. }
  1445. void LLViewerWindow::initGLDefaults()
  1446. {
  1447. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  1448. if (!LLGLSLShader::sNoFixedFunction)
  1449. { //initialize fixed function state
  1450. glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
  1451. glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,LLColor4::black.mV);
  1452. glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,LLColor4::white.mV);
  1453. // lights for objects
  1454. glShadeModel( GL_SMOOTH );
  1455. gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
  1456. gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
  1457. }
  1458. glPixelStorei(GL_PACK_ALIGNMENT,1);
  1459. glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  1460. gGL.setAmbientLightColor(LLColor4::black);
  1461. glCullFace(GL_BACK);
  1462. // RN: Need this for translation and stretch manip.
  1463. gBox.prerender();
  1464. }
  1465. struct MainPanel : public LLPanel
  1466. {
  1467. };
  1468. void LLViewerWindow::initBase()
  1469. {
  1470. S32 height = getWindowHeightScaled();
  1471. S32 width = getWindowWidthScaled();
  1472. LLRect full_window(0, height, width, 0);
  1473. ////////////////////
  1474. //
  1475. // Set the gamma
  1476. //
  1477. F32 gamma = gSavedSettings.getF32("RenderGamma");
  1478. if (gamma != 0.0f)
  1479. {
  1480. getWindow()->setGamma(gamma);
  1481. }
  1482. // Create global views
  1483. // Create the floater view at the start so that other views can add children to it.
  1484. // (But wait to add it as a child of the root view so that it will be in front of the
  1485. // other views.)
  1486. MainPanel* main_view = new MainPanel();
  1487. main_view->buildFromFile("main_view.xml");
  1488. main_view->setShape(full_window);
  1489. getRootView()->addChild(main_view);
  1490. // placeholder widget that controls where "world" is rendered
  1491. mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
  1492. mPopupView = main_view->getChild<LLPopupView>("popup_holder");
  1493. mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle();
  1494. mLoginPanelHolder = main_view->getChild<LLView>("login_panel_holder")->getHandle();
  1495. // Create the toolbar view
  1496. // Get a pointer to the toolbar view holder
  1497. LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder");
  1498. // Load the toolbar view from file
  1499. gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance());
  1500. gToolBarView->setShape(panel_holder->getLocalRect());
  1501. // Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI())
  1502. gToolBarView->setVisible(FALSE);
  1503. // Constrain floaters to inside the menu and status bar regions.
  1504. gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
  1505. gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
  1506. gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
  1507. // Console
  1508. llassert( !gConsole );
  1509. LLConsole::Params cp;
  1510. cp.name("console");
  1511. cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
  1512. cp.rect(getChatConsoleRect());
  1513. cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
  1514. cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
  1515. cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
  1516. gConsole = LLUICtrlFactory::create<LLConsole>(cp);
  1517. getRootView()->addChild(gConsole);
  1518. // optionally forward warnings to chat console/chat floater
  1519. // for qa runs and dev builds
  1520. #if !LL_RELEASE_FOR_DOWNLOAD
  1521. LLError::addRecorder(RecordToChatConsole::getInstance());
  1522. #else
  1523. if(gSavedSettings.getBOOL("QAMode"))
  1524. {
  1525. LLError::addRecorder(RecordToChatConsole::getInstance());
  1526. }
  1527. #endif
  1528. gDebugView = getRootView()->getChild<LLDebugView>("DebugView");
  1529. gDebugView->init();
  1530. gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
  1531. // Initialize busy response message when logged in
  1532. LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse));
  1533. // Add the progress bar view (startup view), which overrides everything
  1534. mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
  1535. setShowProgress(FALSE);
  1536. setProgressCancelButtonVisible(FALSE);
  1537. gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder");
  1538. LLMenuGL::sMenuContainer = gMenuHolder;
  1539. }
  1540. void LLViewerWindow::initWorldUI()
  1541. {
  1542. S32 height = mRootView->getRect().getHeight();
  1543. S32 width = mRootView->getRect().getWidth();
  1544. LLRect full_window(0, height, width, 0);
  1545. gIMMgr = LLIMMgr::getInstance();
  1546. //getRootView()->sendChildToFront(gFloaterView);
  1547. //getRootView()->sendChildToFront(gSnapshotFloaterView);
  1548. LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container");
  1549. LLChicletBar* chiclet_bar = LLChicletBar::getInstance();
  1550. chiclet_bar->setShape(chiclet_container->getLocalRect());
  1551. chiclet_bar->setFollowsAll();
  1552. chiclet_container->addChild(chiclet_bar);
  1553. chiclet_container->setVisible(TRUE);
  1554. LLRect morph_view_rect = full_window;
  1555. morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
  1556. morph_view_rect.mTop = full_window.mTop - 32;
  1557. LLMorphView::Params mvp;
  1558. mvp.name("MorphView");
  1559. mvp.rect(morph_view_rect);
  1560. mvp.visible(false);
  1561. gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp);
  1562. getRootView()->addChild(gMorphView);
  1563. LLWorldMapView::initClass();
  1564. // Force gFloaterWorldMap to initialize
  1565. LLFloaterReg::getInstance("world_map");
  1566. // Force gFloaterTools to initialize
  1567. LLFloaterReg::getInstance("build");
  1568. LLFloaterReg::hideInstance("build");
  1569. // Status bar
  1570. LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
  1571. gStatusBar = new LLStatusBar(status_bar_container->getLocalRect());
  1572. gStatusBar->setFollowsAll();
  1573. gStatusBar->setShape(status_bar_container->getLocalRect());
  1574. // sync bg color with menu bar
  1575. gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
  1576. status_bar_container->addChildInBack(gStatusBar);
  1577. status_bar_container->setVisible(TRUE);
  1578. // Navigation bar
  1579. LLPanel* nav_bar_container = getRootView()->getChild<LLPanel>("nav_bar_container");
  1580. LLNavigationBar* navbar = LLNavigationBar::getInstance();
  1581. navbar->setShape(nav_bar_container->getLocalRect());
  1582. navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
  1583. nav_bar_container->addChild(navbar);
  1584. nav_bar_container->setVisible(TRUE);
  1585. if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
  1586. {
  1587. navbar->setVisible(FALSE);
  1588. }
  1589. // Top Info bar
  1590. LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
  1591. LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance();
  1592. topinfo_bar->setShape(topinfo_bar_container->getLocalRect());
  1593. topinfo_bar_container->addChild(topinfo_bar);
  1594. topinfo_bar_container->setVisible(TRUE);
  1595. if (!gSavedSettings.getBOOL("ShowMiniLocationPanel"))
  1596. {
  1597. topinfo_bar->setVisible(FALSE);
  1598. }
  1599. if ( gHUDView == NULL )
  1600. {
  1601. LLRect hud_rect = full_window;
  1602. hud_rect.mBottom += 50;
  1603. if (gMenuBarView && gMenuBarView->isInVisibleChain())
  1604. {
  1605. hud_rect.mTop -= gMenuBarView->getRect().getHeight();
  1606. }
  1607. gHUDView = new LLHUDView(hud_rect);
  1608. getRootView()->addChild(gHUDView);
  1609. }
  1610. LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container");
  1611. LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance();
  1612. panel_ssf_container->addChild(panel_stand_stop_flying);
  1613. panel_ssf_container->setVisible(TRUE);
  1614. // Load and make the toolbars visible
  1615. // Note: we need to load the toolbars only *after* the user is logged in and IW
  1616. if (gToolBarView)
  1617. {
  1618. gToolBarView->loadToolbars();
  1619. gToolBarView->setVisible(TRUE);
  1620. }
  1621. LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
  1622. if (destinations)
  1623. {
  1624. destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
  1625. std::string url = gSavedSettings.getString("DestinationGuideURL");
  1626. url = LLWeb::expandURLSubstitutions(url, LLSD());
  1627. destinations->navigateTo(url, "text/html");
  1628. }
  1629. LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
  1630. if (avatar_picker)
  1631. {
  1632. avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
  1633. std::string url = gSavedSettings.getString("AvatarPickerURL");
  1634. url = LLWeb::expandURLSubstitutions(url, LLSD());
  1635. avatar_picker->navigateTo(url, "text/html");
  1636. }
  1637. }
  1638. // Destroy the UI
  1639. void LLViewerWindow::shutdownViews()
  1640. {
  1641. // clean up warning logger
  1642. LLError::removeRecorder(RecordToChatConsole::getInstance());
  1643. llinfos << "Warning logger is cleaned." << llendl ;
  1644. delete mDebugText;
  1645. mDebugText = NULL;
  1646. llinfos << "DebugText deleted." << llendl ;
  1647. // Cleanup global views
  1648. if (gMorphView)
  1649. {
  1650. gMorphView->setVisible(FALSE);
  1651. }
  1652. llinfos << "Global views cleaned." << llendl ;
  1653. // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
  1654. // will crump with LL_ERRS.
  1655. LLModalDialog::shutdownModals();
  1656. llinfos << "LLModalDialog shut down." << llendl;
  1657. // destroy the nav bar, not currently part of gViewerWindow
  1658. // *TODO: Make LLNavigationBar part of gViewerWindow
  1659. if (LLNavigationBar::instanceExists())
  1660. {
  1661. delete LLNavigationBar::getInstance();
  1662. }
  1663. llinfos << "LLNavigationBar destroyed." << llendl ;
  1664. // destroy menus after instantiating navbar above, as it needs
  1665. // access to gMenuHolder
  1666. cleanup_menus();
  1667. llinfos << "menus destroyed." << llendl ;
  1668. // Delete all child views.
  1669. delete mRootView;
  1670. mRootView = NULL;
  1671. llinfos << "RootView deleted." << llendl ;
  1672. // Automatically deleted as children of mRootView. Fix the globals.
  1673. gStatusBar = NULL;
  1674. gIMMgr = NULL;
  1675. gToolTipView = NULL;
  1676. gToolBarView = NULL;
  1677. gFloaterView = NULL;
  1678. gMorphView = NULL;
  1679. gHUDView = NULL;
  1680. }
  1681. void LLViewerWindow::shutdownGL()
  1682. {
  1683. //--------------------------------------------------------
  1684. // Shutdown GL cleanly. Order is very important here.
  1685. //--------------------------------------------------------
  1686. LLFontGL::destroyDefaultFonts();
  1687. LLFontManager::cleanupClass();
  1688. stop_glerror();
  1689. gSky.cleanup();
  1690. stop_glerror();
  1691. LLWearableList::instance().cleanup() ;
  1692. gTextureList.shutdown();
  1693. stop_glerror();
  1694. gBumpImageList.shutdown();
  1695. stop_glerror();
  1696. LLWorldMapView::cleanupTextures();
  1697. llinfos << "Cleaning up pipeline" << llendl;
  1698. gPipeline.cleanup();
  1699. stop_glerror();
  1700. LLViewerTextureManager::cleanup() ;
  1701. LLImageGL::cleanupClass() ;
  1702. llinfos << "All textures and llimagegl images are destroyed!" << llendl ;
  1703. llinfos << "Cleaning up select manager" << llendl;
  1704. LLSelectMgr::getInstance()->cleanup();
  1705. llinfos << "Stopping GL during shutdown" << llendl;
  1706. stopGL(FALSE);
  1707. stop_glerror();
  1708. gGL.shutdown();
  1709. LLVertexBuffer::cleanupClass();
  1710. llinfos << "LLVertexBuffer cleaned." << llendl ;
  1711. }
  1712. // shutdownViews() and shutdownGL() need to be called first
  1713. LLViewerWindow::~LLViewerWindow()
  1714. {
  1715. llinfos << "Destroying Window" << llendl;
  1716. destroyWindow();
  1717. delete mDebugText;
  1718. mDebugText = NULL;
  1719. }
  1720. void LLViewerWindow::setCursor( ECursorType c )
  1721. {
  1722. mWindow->setCursor( c );
  1723. }
  1724. void LLViewerWindow::showCursor()
  1725. {
  1726. mWindow->showCursor();
  1727. mCursorHidden = FALSE;
  1728. }
  1729. void LLViewerWindow::hideCursor()
  1730. {
  1731. // And hide the cursor
  1732. mWindow->hideCursor();
  1733. mCursorHidden = TRUE;
  1734. }
  1735. void LLViewerWindow::sendShapeToSim()
  1736. {
  1737. LLMessageSystem* msg = gMessageSystem;
  1738. if(!msg) return;
  1739. msg->newMessageFast(_PREHASH_AgentHeightWidth);
  1740. msg->nextBlockFast(_PREHASH_AgentData);
  1741. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  1742. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  1743. msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
  1744. msg->nextBlockFast(_PREHASH_HeightWidthBlock);
  1745. msg->addU32Fast(_PREHASH_GenCounter, 0);
  1746. U16 height16 = (U16) mWorldViewRectRaw.getHeight();
  1747. U16 width16 = (U16) mWorldViewRectRaw.getWidth();
  1748. msg->addU16Fast(_PREHASH_Height, height16);
  1749. msg->addU16Fast(_PREHASH_Width, width16);
  1750. gAgent.sendReliableMessage();
  1751. }
  1752. // Must be called after window is created to set up agent
  1753. // camera variables and UI variables.
  1754. void LLViewerWindow::reshape(S32 width, S32 height)
  1755. {
  1756. // Destroying the window at quit time generates spurious
  1757. // reshape messages. We don't care about these, and we
  1758. // don't want to send messages because the message system
  1759. // may have been destructed.
  1760. if (!LLApp::isExiting())
  1761. {
  1762. gWindowResized = TRUE;
  1763. // update our window rectangle
  1764. mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width;
  1765. mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height;
  1766. //glViewport(0, 0, width, height );
  1767. if (height > 0)
  1768. {
  1769. LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
  1770. LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
  1771. }
  1772. calcDisplayScale();
  1773. BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
  1774. LLUI::setScaleFactor(mDisplayScale);
  1775. // update our window rectangle
  1776. mWindowRectScaled.mRight = mWindowRectScaled.mLeft + llround((F32)width / mDisplayScale.mV[VX]);
  1777. mWindowRectScaled.mTop = mWindowRectScaled.mBottom + llround((F32)height / mDisplayScale.mV[VY]);
  1778. setup2DViewport();
  1779. // Inform lower views of the change
  1780. // round up when converting coordinates to make sure there are no gaps at edge of window
  1781. LLView::sForceReshape = display_scale_changed;
  1782. mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
  1783. LLView::sForceReshape = FALSE;
  1784. // clear font width caches
  1785. if (display_scale_changed)
  1786. {
  1787. LLHUDObject::reshapeAll();
  1788. }
  1789. sendShapeToSim();
  1790. // store new settings for the mode we are in, regardless
  1791. BOOL maximized = mWindow->getMaximized();
  1792. gSavedSettings.setBOOL("WindowMaximized", maximized)