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

/indra/newview/lltextureview.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1350 lines | 1057 code | 188 blank | 105 comment | 124 complexity | d5484afc42ce98e49f3263a0a089dec5 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lltextureview.cpp
  3. * @brief LLTextureView class implementation
  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 <set>
  28. #include "lltextureview.h"
  29. #include "llrect.h"
  30. #include "llerror.h"
  31. #include "lllfsthread.h"
  32. #include "llui.h"
  33. #include "llimageworker.h"
  34. #include "llrender.h"
  35. #include "lltooltip.h"
  36. #include "llappviewer.h"
  37. #include "llselectmgr.h"
  38. #include "lltexlayer.h"
  39. #include "lltexturecache.h"
  40. #include "lltexturefetch.h"
  41. #include "llviewercontrol.h"
  42. #include "llviewerobject.h"
  43. #include "llviewertexture.h"
  44. #include "llviewertexturelist.h"
  45. #include "llvovolume.h"
  46. #include "llviewerstats.h"
  47. // For avatar texture view
  48. #include "llvoavatarself.h"
  49. #include "lltexlayer.h"
  50. extern F32 texmem_lower_bound_scale;
  51. LLTextureView *gTextureView = NULL;
  52. LLTextureSizeView *gTextureSizeView = NULL;
  53. LLTextureSizeView *gTextureCategoryView = NULL;
  54. #define HIGH_PRIORITY 100000000.f
  55. //static
  56. std::set<LLViewerFetchedTexture*> LLTextureView::sDebugImages;
  57. ////////////////////////////////////////////////////////////////////////////
  58. static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max");
  59. static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max");
  60. static std::string title_string2("State");
  61. static std::string title_string3("Pkt Bnd");
  62. static std::string title_string4(" W x H (Dis) Mem");
  63. static S32 title_x1 = 0;
  64. static S32 title_x2 = 460;
  65. static S32 title_x3 = title_x2 + 40;
  66. static S32 title_x4 = title_x3 + 50;
  67. static S32 texture_bar_height = 8;
  68. ////////////////////////////////////////////////////////////////////////////
  69. class LLTextureBar : public LLView
  70. {
  71. public:
  72. LLPointer<LLViewerFetchedTexture> mImagep;
  73. S32 mHilite;
  74. public:
  75. struct Params : public LLInitParam::Block<Params, LLView::Params>
  76. {
  77. Mandatory<LLTextureView*> texture_view;
  78. Params()
  79. : texture_view("texture_view")
  80. {
  81. changeDefault(mouse_opaque, false);
  82. }
  83. };
  84. LLTextureBar(const Params& p)
  85. : LLView(p),
  86. mHilite(0),
  87. mTextureView(p.texture_view)
  88. {}
  89. virtual void draw();
  90. virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  91. virtual LLRect getRequiredRect(); // Return the height of this object, given the set options.
  92. // Used for sorting
  93. struct sort
  94. {
  95. bool operator()(const LLView* i1, const LLView* i2)
  96. {
  97. LLTextureBar* bar1p = (LLTextureBar*)i1;
  98. LLTextureBar* bar2p = (LLTextureBar*)i2;
  99. LLViewerFetchedTexture *i1p = bar1p->mImagep;
  100. LLViewerFetchedTexture *i2p = bar2p->mImagep;
  101. F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority
  102. F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority
  103. if (pri1 > pri2)
  104. return true;
  105. else if (pri2 > pri1)
  106. return false;
  107. else
  108. return i1p->getID() < i2p->getID();
  109. }
  110. };
  111. struct sort_fetch
  112. {
  113. bool operator()(const LLView* i1, const LLView* i2)
  114. {
  115. LLTextureBar* bar1p = (LLTextureBar*)i1;
  116. LLTextureBar* bar2p = (LLTextureBar*)i2;
  117. LLViewerFetchedTexture *i1p = bar1p->mImagep;
  118. LLViewerFetchedTexture *i2p = bar2p->mImagep;
  119. U32 pri1 = i1p->getFetchPriority() ;
  120. U32 pri2 = i2p->getFetchPriority() ;
  121. if (pri1 > pri2)
  122. return true;
  123. else if (pri2 > pri1)
  124. return false;
  125. else
  126. return i1p->getID() < i2p->getID();
  127. }
  128. };
  129. private:
  130. LLTextureView* mTextureView;
  131. };
  132. void LLTextureBar::draw()
  133. {
  134. if (!mImagep)
  135. {
  136. return;
  137. }
  138. LLColor4 color;
  139. if (mImagep->getID() == LLAppViewer::getTextureFetch()->mDebugID)
  140. {
  141. color = LLColor4::cyan2;
  142. }
  143. else if (mHilite)
  144. {
  145. S32 idx = llclamp(mHilite,1,3);
  146. if (idx==1) color = LLColor4::orange;
  147. else if (idx==2) color = LLColor4::yellow;
  148. else color = LLColor4::pink2;
  149. }
  150. else if (mImagep->mDontDiscard)
  151. {
  152. color = LLColor4::green4;
  153. }
  154. else if (mImagep->getBoostLevel() > LLViewerTexture::BOOST_NONE)
  155. {
  156. color = LLColor4::magenta;
  157. }
  158. else if (mImagep->getDecodePriority() <= 0.0f)
  159. {
  160. color = LLColor4::grey; color[VALPHA] = .7f;
  161. }
  162. else
  163. {
  164. color = LLColor4::white; color[VALPHA] = .7f;
  165. }
  166. // We need to draw:
  167. // The texture UUID or name
  168. // The progress bar for the texture, highlighted if it's being download
  169. // Various numerical stats.
  170. std::string tex_str;
  171. S32 left, right;
  172. S32 top = 0;
  173. S32 bottom = top + 6;
  174. LLColor4 clr;
  175. LLGLSUIDefault gls_ui;
  176. // Name, pixel_area, requested pixel area, decode priority
  177. std::string uuid_str;
  178. mImagep->mID.toString(uuid_str);
  179. uuid_str = uuid_str.substr(0,7);
  180. if (mTextureView->mOrderFetch)
  181. {
  182. tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)",
  183. uuid_str.c_str(),
  184. mImagep->mMaxVirtualSize,
  185. mImagep->mDesiredDiscardLevel,
  186. mImagep->mRequestedDiscardLevel,
  187. mImagep->mFetchPriority,
  188. mImagep->getDecodePriority());
  189. }
  190. else
  191. {
  192. tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)",
  193. uuid_str.c_str(),
  194. mImagep->mMaxVirtualSize,
  195. mImagep->mDesiredDiscardLevel,
  196. mImagep->mRequestedDiscardLevel,
  197. mImagep->getDecodePriority(),
  198. mImagep->mFetchPriority);
  199. }
  200. LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(),
  201. color, LLFontGL::LEFT, LLFontGL::TOP);
  202. // State
  203. // Hack: mirrored from lltexturefetch.cpp
  204. struct { const std::string desc; LLColor4 color; } fetch_state_desc[] = {
  205. { "---", LLColor4::red }, // INVALID
  206. { "INI", LLColor4::white }, // INIT
  207. { "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE
  208. { "DSK", LLColor4::blue }, // CACHE_POST
  209. { "NET", LLColor4::green }, // LOAD_FROM_NETWORK
  210. { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
  211. { "REQ", LLColor4::yellow },// SEND_HTTP_REQ
  212. { "HTP", LLColor4::green }, // WAIT_HTTP_REQ
  213. { "DEC", LLColor4::yellow },// DECODE_IMAGE
  214. { "DEC", LLColor4::green }, // DECODE_IMAGE_UPDATE
  215. { "WRT", LLColor4::purple },// WRITE_TO_CACHE
  216. { "WRT", LLColor4::orange },// WAIT_ON_WRITE
  217. { "END", LLColor4::red }, // DONE
  218. #define LAST_STATE 12
  219. { "CRE", LLColor4::magenta }, // LAST_STATE+1
  220. { "FUL", LLColor4::green }, // LAST_STATE+2
  221. { "BAD", LLColor4::red }, // LAST_STATE+3
  222. { "MIS", LLColor4::red }, // LAST_STATE+4
  223. { "---", LLColor4::white }, // LAST_STATE+5
  224. };
  225. const S32 fetch_state_desc_size = (S32)LL_ARRAY_SIZE(fetch_state_desc);
  226. S32 state =
  227. mImagep->mNeedsCreateTexture ? LAST_STATE+1 :
  228. mImagep->mFullyLoaded ? LAST_STATE+2 :
  229. mImagep->mMinDiscardLevel > 0 ? LAST_STATE+3 :
  230. mImagep->mIsMissingAsset ? LAST_STATE+4 :
  231. !mImagep->mIsFetching ? LAST_STATE+5 :
  232. mImagep->mFetchState;
  233. state = llclamp(state,0,fetch_state_desc_size-1);
  234. LLFontGL::getFontMonospace()->renderUTF8(fetch_state_desc[state].desc, 0, title_x2, getRect().getHeight(),
  235. fetch_state_desc[state].color,
  236. LLFontGL::LEFT, LLFontGL::TOP);
  237. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  238. // Draw the progress bar.
  239. S32 bar_width = 100;
  240. S32 bar_left = 260;
  241. left = bar_left;
  242. right = left + bar_width;
  243. gGL.color4f(0.f, 0.f, 0.f, 0.75f);
  244. gl_rect_2d(left, top, right, bottom);
  245. F32 data_progress = mImagep->mDownloadProgress;
  246. if (data_progress > 0.0f)
  247. {
  248. // Downloaded bytes
  249. right = left + llfloor(data_progress * (F32)bar_width);
  250. if (right > left)
  251. {
  252. gGL.color4f(0.f, 0.f, 1.f, 0.75f);
  253. gl_rect_2d(left, top, right, bottom);
  254. }
  255. }
  256. S32 pip_width = 6;
  257. S32 pip_space = 14;
  258. S32 pip_x = title_x3 + pip_space/2;
  259. // Draw the packet pip
  260. const F32 pip_max_time = 5.f;
  261. F32 last_event = mImagep->mLastPacketTimer.getElapsedTimeF32();
  262. if (last_event < pip_max_time)
  263. {
  264. clr = LLColor4::white;
  265. }
  266. else
  267. {
  268. last_event = mImagep->mRequestDeltaTime;
  269. if (last_event < pip_max_time)
  270. {
  271. clr = LLColor4::green;
  272. }
  273. else
  274. {
  275. last_event = mImagep->mFetchDeltaTime;
  276. if (last_event < pip_max_time)
  277. {
  278. clr = LLColor4::yellow;
  279. }
  280. }
  281. }
  282. if (last_event < pip_max_time)
  283. {
  284. clr.setAlpha(1.f - last_event/pip_max_time);
  285. gGL.color4fv(clr.mV);
  286. gl_rect_2d(pip_x, top, pip_x + pip_width, bottom);
  287. }
  288. pip_x += pip_width + pip_space;
  289. // we don't want to show bind/resident pips for textures using the default texture
  290. if (mImagep->hasGLTexture())
  291. {
  292. // Draw the bound pip
  293. last_event = mImagep->getTimePassedSinceLastBound();
  294. if (last_event < 1.f)
  295. {
  296. clr = mImagep->getMissed() ? LLColor4::red : LLColor4::magenta1;
  297. clr.setAlpha(1.f - last_event);
  298. gGL.color4fv(clr.mV);
  299. gl_rect_2d(pip_x, top, pip_x + pip_width, bottom);
  300. }
  301. }
  302. pip_x += pip_width + pip_space;
  303. {
  304. LLGLSUIDefault gls_ui;
  305. // draw the packet data
  306. // {
  307. // std::string num_str = llformat("%3d/%3d", mImagep->mLastPacket+1, mImagep->mPackets);
  308. // LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, bar_left + 100, getRect().getHeight(), color,
  309. // LLFontGL::LEFT, LLFontGL::TOP);
  310. // }
  311. // draw the image size at the end
  312. {
  313. std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(),
  314. mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0);
  315. LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color,
  316. LLFontGL::LEFT, LLFontGL::TOP);
  317. }
  318. }
  319. }
  320. BOOL LLTextureBar::handleMouseDown(S32 x, S32 y, MASK mask)
  321. {
  322. if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == MASK_ALT)
  323. {
  324. LLAppViewer::getTextureFetch()->mDebugID = mImagep->getID();
  325. return TRUE;
  326. }
  327. return LLView::handleMouseDown(x,y,mask);
  328. }
  329. LLRect LLTextureBar::getRequiredRect()
  330. {
  331. LLRect rect;
  332. rect.mTop = texture_bar_height;
  333. return rect;
  334. }
  335. ////////////////////////////////////////////////////////////////////////////
  336. class LLAvatarTexBar : public LLView
  337. {
  338. public:
  339. struct Params : public LLInitParam::Block<Params, LLView::Params>
  340. {
  341. Mandatory<LLTextureView*> texture_view;
  342. Params()
  343. : texture_view("texture_view")
  344. {
  345. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  346. changeDefault(rect, LLRect(0,0,100,line_height * 4));
  347. }
  348. };
  349. LLAvatarTexBar(const Params& p)
  350. : LLView(p),
  351. mTextureView(p.texture_view)
  352. {}
  353. virtual void draw();
  354. virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  355. virtual LLRect getRequiredRect(); // Return the height of this object, given the set options.
  356. private:
  357. LLTextureView* mTextureView;
  358. };
  359. void LLAvatarTexBar::draw()
  360. {
  361. if (!gSavedSettings.getBOOL("DebugAvatarRezTime")) return;
  362. LLVOAvatarSelf* avatarp = gAgentAvatarp;
  363. if (!avatarp) return;
  364. const S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  365. const S32 v_offset = 0;
  366. const S32 l_offset = 3;
  367. //----------------------------------------------------------------------------
  368. LLGLSUIDefault gls_ui;
  369. LLColor4 color;
  370. U32 line_num = 1;
  371. for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
  372. baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
  373. ++baked_iter)
  374. {
  375. const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
  376. const LLTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
  377. if (!layerset) continue;
  378. const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
  379. if (!layerset_buffer) continue;
  380. LLColor4 text_color = LLColor4::white;
  381. if (layerset_buffer->uploadNeeded())
  382. {
  383. text_color = LLColor4::red;
  384. }
  385. if (layerset_buffer->uploadInProgress())
  386. {
  387. text_color = LLColor4::magenta;
  388. }
  389. std::string text = layerset_buffer->dumpTextureInfo();
  390. LLFontGL::getFontMonospace()->renderUTF8(text, 0, l_offset, v_offset + line_height*line_num,
  391. text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
  392. line_num++;
  393. }
  394. const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
  395. const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
  396. LLColor4 header_color(1.f, 1.f, 1.f, 0.9f);
  397. const std::string texture_timeout_str = texture_timeout ? llformat("%d",texture_timeout) : "Disabled";
  398. const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled";
  399. std::string header_text = llformat("[ Timeout('AvatarBakedTextureUploadTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());
  400. LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, l_offset, v_offset + line_height*line_num,
  401. header_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
  402. line_num++;
  403. std::string section_text = "Avatar Textures Information:";
  404. LLFontGL::getFontMonospace()->renderUTF8(section_text, 0, 0, v_offset + line_height*line_num,
  405. header_color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
  406. }
  407. BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask)
  408. {
  409. return FALSE;
  410. }
  411. LLRect LLAvatarTexBar::getRequiredRect()
  412. {
  413. LLRect rect;
  414. rect.mTop = 100;
  415. if (!gSavedSettings.getBOOL("DebugAvatarRezTime")) rect.mTop = 0;
  416. return rect;
  417. }
  418. ////////////////////////////////////////////////////////////////////////////
  419. class LLGLTexMemBar : public LLView
  420. {
  421. public:
  422. struct Params : public LLInitParam::Block<Params, LLView::Params>
  423. {
  424. Mandatory<LLTextureView*> texture_view;
  425. Params()
  426. : texture_view("texture_view")
  427. {
  428. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  429. changeDefault(rect, LLRect(0,0,100,line_height * 4));
  430. }
  431. };
  432. LLGLTexMemBar(const Params& p)
  433. : LLView(p),
  434. mTextureView(p.texture_view)
  435. {}
  436. virtual void draw();
  437. virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  438. virtual LLRect getRequiredRect(); // Return the height of this object, given the set options.
  439. private:
  440. LLTextureView* mTextureView;
  441. };
  442. void LLGLTexMemBar::draw()
  443. {
  444. S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes);
  445. S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes;
  446. S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes);
  447. S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes;
  448. F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
  449. F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
  450. F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
  451. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  452. S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
  453. F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
  454. F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
  455. U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;
  456. //----------------------------------------------------------------------------
  457. LLGLSUIDefault gls_ui;
  458. LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
  459. LLColor4 color;
  460. std::string text = "";
  461. LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
  462. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  463. text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
  464. total_mem,
  465. max_total_mem,
  466. bound_mem,
  467. max_bound_mem,
  468. LLRenderTarget::sBytesAllocated/(1024*1024),
  469. LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
  470. cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);
  471. //, cache_entries, cache_max_entries
  472. LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
  473. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  474. //----------------------------------------------------------------------------
  475. #if 0
  476. S32 bar_left = 400;
  477. S32 bar_width = 200;
  478. S32 top = line_height*3 - 2 + v_offset;
  479. S32 bottom = top - 6;
  480. S32 left = bar_left;
  481. S32 right = left + bar_width;
  482. F32 bar_scale;
  483. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  484. // GL Mem Bar
  485. left = bar_left;
  486. text = "GL";
  487. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
  488. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  489. left = bar_left+20;
  490. right = left + bar_width;
  491. gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey
  492. gl_rect_2d(left, top, right, bottom);
  493. bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
  494. right = left + llfloor(total_mem * bar_scale);
  495. right = llclamp(right, bar_left, bar_left + bar_width);
  496. color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green :
  497. (total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red;
  498. color[VALPHA] = .75f;
  499. gGL.diffuseColor4fv(color.mV);
  500. gl_rect_2d(left, top, right, bottom); // red/yellow/green
  501. //
  502. bar_left += bar_width + bar_space;
  503. //top = bottom - 2; bottom = top - 6;
  504. // Bound Mem Bar
  505. left = bar_left;
  506. text = "GL";
  507. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
  508. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  509. left = bar_left + 20;
  510. right = left + bar_width;
  511. gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
  512. gl_rect_2d(left, top, right, bottom);
  513. color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green :
  514. (bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red;
  515. color[VALPHA] = .75f;
  516. gGL.diffuseColor4fv(color.mV);
  517. gl_rect_2d(left, top, right, bottom);
  518. #else
  519. S32 left = 0 ;
  520. #endif
  521. //----------------------------------------------------------------------------
  522. text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
  523. gTextureList.getNumImages(),
  524. LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
  525. LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount,
  526. LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
  527. LLLFSThread::sLocal->getPending(),
  528. LLImageRaw::sRawImageCount,
  529. LLAppViewer::getTextureFetch()->getNumHTTPRequests(),
  530. LLAppViewer::getImageDecodeThread()->getPending(),
  531. gTextureList.mCreateTextureList.size());
  532. LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
  533. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  534. left = 550;
  535. F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
  536. F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
  537. color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
  538. color[VALPHA] = text_color[VALPHA];
  539. text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
  540. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2,
  541. color, LLFontGL::LEFT, LLFontGL::TOP);
  542. S32 dx1 = 0;
  543. if (LLAppViewer::getTextureFetch()->mDebugPause)
  544. {
  545. LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, v_offset + line_height,
  546. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  547. dx1 += 8;
  548. }
  549. if (mTextureView->mFreezeView)
  550. {
  551. LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, v_offset + line_height,
  552. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  553. dx1 += 8;
  554. }
  555. if (mTextureView->mOrderFetch)
  556. {
  557. LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, v_offset + line_height,
  558. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  559. }
  560. else
  561. {
  562. LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, v_offset + line_height,
  563. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  564. }
  565. LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, v_offset + line_height,
  566. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  567. LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, v_offset + line_height,
  568. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  569. LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, v_offset + line_height,
  570. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  571. }
  572. BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)
  573. {
  574. return FALSE;
  575. }
  576. LLRect LLGLTexMemBar::getRequiredRect()
  577. {
  578. LLRect rect;
  579. //rect.mTop = 50;
  580. rect.mTop = 0;
  581. return rect;
  582. }
  583. ////////////////////////////////////////////////////////////////////////////
  584. class LLGLTexSizeBar
  585. {
  586. public:
  587. LLGLTexSizeBar(S32 index, S32 left, S32 bottom, S32 right, S32 line_height)
  588. {
  589. mIndex = index ;
  590. mLeft = left ;
  591. mBottom = bottom ;
  592. mRight = right ;
  593. mLineHeight = line_height ;
  594. mTopLoaded = 0 ;
  595. mTopBound = 0 ;
  596. mScale = 1.0f ;
  597. }
  598. void setTop(S32 loaded, S32 bound, F32 scale) {mTopLoaded = loaded ; mTopBound = bound; mScale = scale ;}
  599. void draw();
  600. BOOL handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) ;
  601. private:
  602. S32 mIndex ;
  603. S32 mLeft ;
  604. S32 mBottom ;
  605. S32 mRight ;
  606. S32 mTopLoaded ;
  607. S32 mTopBound ;
  608. S32 mLineHeight ;
  609. F32 mScale ;
  610. };
  611. BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size)
  612. {
  613. if(y > mBottom && (y < mBottom + (S32)(mTopLoaded * mScale) || y < mBottom + (S32)(mTopBound * mScale)))
  614. {
  615. LLImageGL::setCurTexSizebar(mIndex, set_pick_size);
  616. }
  617. return TRUE ;
  618. }
  619. void LLGLTexSizeBar::draw()
  620. {
  621. LLGLSUIDefault gls_ui;
  622. if(LLImageGL::sCurTexSizeBar == mIndex)
  623. {
  624. F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
  625. std::string text;
  626. text = llformat("%d", mTopLoaded) ;
  627. LLFontGL::getFontMonospace()->renderUTF8(text, 0, mLeft, mBottom + (S32)(mTopLoaded * mScale) + mLineHeight,
  628. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  629. text = llformat("%d", mTopBound) ;
  630. LLFontGL::getFontMonospace()->renderUTF8(text, 0, (mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale) + mLineHeight,
  631. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  632. }
  633. F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
  634. F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
  635. gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ;
  636. gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ;
  637. }
  638. ////////////////////////////////////////////////////////////////////////////
  639. LLTextureView::LLTextureView(const LLTextureView::Params& p)
  640. : LLContainerView(p),
  641. mFreezeView(FALSE),
  642. mOrderFetch(FALSE),
  643. mPrintList(FALSE),
  644. mNumTextureBars(0)
  645. {
  646. setVisible(FALSE);
  647. setDisplayChildren(TRUE);
  648. mGLTexMemBar = 0;
  649. mAvatarTexBar = 0;
  650. }
  651. LLTextureView::~LLTextureView()
  652. {
  653. // Children all cleaned up by default view destructor.
  654. delete mGLTexMemBar;
  655. mGLTexMemBar = 0;
  656. delete mAvatarTexBar;
  657. mAvatarTexBar = 0;
  658. }
  659. typedef std::pair<F32,LLViewerFetchedTexture*> decode_pair_t;
  660. struct compare_decode_pair
  661. {
  662. bool operator()(const decode_pair_t& a, const decode_pair_t& b)
  663. {
  664. return a.first > b.first;
  665. }
  666. };
  667. struct KillView
  668. {
  669. void operator()(LLView* viewp)
  670. {
  671. viewp->getParent()->removeChild(viewp);
  672. viewp->die();
  673. }
  674. };
  675. void LLTextureView::draw()
  676. {
  677. if (!mFreezeView)
  678. {
  679. // LLViewerObject *objectp;
  680. // S32 te;
  681. for_each(mTextureBars.begin(), mTextureBars.end(), KillView());
  682. mTextureBars.clear();
  683. if (mGLTexMemBar)
  684. {
  685. removeChild(mGLTexMemBar);
  686. mGLTexMemBar->die();
  687. mGLTexMemBar = 0;
  688. }
  689. if (mAvatarTexBar)
  690. {
  691. removeChild(mAvatarTexBar);
  692. mAvatarTexBar->die();
  693. mAvatarTexBar = 0;
  694. }
  695. typedef std::multiset<decode_pair_t, compare_decode_pair > display_list_t;
  696. display_list_t display_image_list;
  697. if (mPrintList)
  698. {
  699. llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl;
  700. }
  701. for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin();
  702. iter != gTextureList.mImageList.end(); )
  703. {
  704. LLPointer<LLViewerFetchedTexture> imagep = *iter++;
  705. if(!imagep->hasFetcher())
  706. {
  707. continue ;
  708. }
  709. S32 cur_discard = imagep->getDiscardLevel();
  710. S32 desired_discard = imagep->mDesiredDiscardLevel;
  711. if (mPrintList)
  712. {
  713. S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ;
  714. llinfos << imagep->getID()
  715. << "\t" << tex_mem
  716. << "\t" << imagep->getBoostLevel()
  717. << "\t" << imagep->getDecodePriority()
  718. << "\t" << imagep->getWidth()
  719. << "\t" << imagep->getHeight()
  720. << "\t" << cur_discard
  721. << llendl;
  722. }
  723. if (imagep->getID() == LLAppViewer::getTextureFetch()->mDebugID)
  724. {
  725. static S32 debug_count = 0;
  726. ++debug_count; // for breakpoints
  727. }
  728. F32 pri;
  729. if (mOrderFetch)
  730. {
  731. pri = ((F32)imagep->mFetchPriority)/256.f;
  732. }
  733. else
  734. {
  735. pri = imagep->getDecodePriority();
  736. }
  737. pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f);
  738. if (sDebugImages.find(imagep) != sDebugImages.end())
  739. {
  740. pri += 4*HIGH_PRIORITY;
  741. }
  742. if (!mOrderFetch)
  743. {
  744. if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance())
  745. {
  746. struct f : public LLSelectedTEFunctor
  747. {
  748. LLViewerFetchedTexture* mImage;
  749. f(LLViewerFetchedTexture* image) : mImage(image) {}
  750. virtual bool apply(LLViewerObject* object, S32 te)
  751. {
  752. return (mImage == object->getTEImage(te));
  753. }
  754. } func(imagep);
  755. const bool firstonly = true;
  756. bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly);
  757. if (match)
  758. {
  759. pri += 3*HIGH_PRIORITY;
  760. }
  761. }
  762. if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard))
  763. {
  764. LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode();
  765. if (hover_node)
  766. {
  767. LLViewerObject *objectp = hover_node->getObject();
  768. if (objectp)
  769. {
  770. S32 tex_count = objectp->getNumTEs();
  771. for (S32 i = 0; i < tex_count; i++)
  772. {
  773. if (imagep == objectp->getTEImage(i))
  774. {
  775. pri += 2*HIGH_PRIORITY;
  776. break;
  777. }
  778. }
  779. }
  780. }
  781. }
  782. if (pri > 0.f && pri < HIGH_PRIORITY)
  783. {
  784. if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f ||
  785. imagep->mFetchDeltaTime < 0.25f)
  786. {
  787. pri += 1*HIGH_PRIORITY;
  788. }
  789. }
  790. }
  791. if (pri > 0.0f)
  792. {
  793. display_image_list.insert(std::make_pair(pri, imagep));
  794. }
  795. }
  796. if (mPrintList)
  797. {
  798. mPrintList = FALSE;
  799. }
  800. static S32 max_count = 50;
  801. S32 count = 0;
  802. mNumTextureBars = 0 ;
  803. for (display_list_t::iterator iter = display_image_list.begin();
  804. iter != display_image_list.end(); iter++)
  805. {
  806. LLViewerFetchedTexture* imagep = iter->second;
  807. S32 hilite = 0;
  808. F32 pri = iter->first;
  809. if (pri >= 1 * HIGH_PRIORITY)
  810. {
  811. hilite = (S32)((pri+1) / HIGH_PRIORITY) - 1;
  812. }
  813. if ((hilite || count < max_count-10) && (count < max_count))
  814. {
  815. if (addBar(imagep, hilite))
  816. {
  817. count++;
  818. }
  819. }
  820. }
  821. if (mOrderFetch)
  822. sortChildren(LLTextureBar::sort_fetch());
  823. else
  824. sortChildren(LLTextureBar::sort());
  825. LLGLTexMemBar::Params tmbp;
  826. LLRect tmbr;
  827. tmbp.name("gl texmem bar");
  828. tmbp.rect(tmbr);
  829. tmbp.texture_view(this);
  830. mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp);
  831. addChildInBack(mGLTexMemBar);
  832. LLAvatarTexBar::Params atbp;
  833. LLRect atbr;
  834. atbp.name("gl avatartex bar");
  835. atbp.texture_view(this);
  836. atbp.rect(atbr);
  837. mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp);
  838. addChild(mAvatarTexBar);
  839. reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
  840. /*
  841. count = gTextureList.getNumImages();
  842. std::string info_string;
  843. info_string = llformat("Global Info:\nTexture Count: %d", count);
  844. mInfoTextp->setText(info_string);
  845. */
  846. for (child_list_const_iter_t child_iter = getChildList()->begin();
  847. child_iter != getChildList()->end(); ++child_iter)
  848. {
  849. LLView *viewp = *child_iter;
  850. if (viewp->getRect().mBottom < 0)
  851. {
  852. viewp->setVisible(FALSE);
  853. }
  854. }
  855. }
  856. LLContainerView::draw();
  857. }
  858. BOOL LLTextureView::addBar(LLViewerFetchedTexture *imagep, S32 hilite)
  859. {
  860. llassert(imagep);
  861. LLTextureBar *barp;
  862. LLRect r;
  863. mNumTextureBars++;
  864. LLTextureBar::Params tbp;
  865. tbp.name("texture bar");
  866. tbp.rect(r);
  867. tbp.texture_view(this);
  868. barp = LLUICtrlFactory::create<LLTextureBar>(tbp);
  869. barp->mImagep = imagep;
  870. barp->mHilite = hilite;
  871. addChild(barp);
  872. mTextureBars.push_back(barp);
  873. return TRUE;
  874. }
  875. BOOL LLTextureView::handleMouseDown(S32 x, S32 y, MASK mask)
  876. {
  877. if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == (MASK_ALT|MASK_SHIFT))
  878. {
  879. mPrintList = TRUE;
  880. return TRUE;
  881. }
  882. if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == (MASK_CONTROL|MASK_SHIFT))
  883. {
  884. LLAppViewer::getTextureFetch()->mDebugPause = !LLAppViewer::getTextureFetch()->mDebugPause;
  885. return TRUE;
  886. }
  887. if (mask & MASK_SHIFT)
  888. {
  889. mFreezeView = !mFreezeView;
  890. return TRUE;
  891. }
  892. if (mask & MASK_CONTROL)
  893. {
  894. mOrderFetch = !mOrderFetch;
  895. return TRUE;
  896. }
  897. return LLView::handleMouseDown(x,y,mask);
  898. }
  899. BOOL LLTextureView::handleMouseUp(S32 x, S32 y, MASK mask)
  900. {
  901. return FALSE;
  902. }
  903. BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
  904. {
  905. return FALSE;
  906. }
  907. //-----------------------------------------------------------------
  908. LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p)
  909. {
  910. setVisible(FALSE) ;
  911. mTextureSizeBarWidth = 30 ;
  912. }
  913. LLTextureSizeView::~LLTextureSizeView()
  914. {
  915. if(mTextureSizeBar.size())
  916. {
  917. for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
  918. {
  919. delete mTextureSizeBar[i] ;
  920. }
  921. mTextureSizeBar.clear() ;
  922. }
  923. }
  924. void LLTextureSizeView::draw()
  925. {
  926. if(mType == TEXTURE_MEM_OVER_SIZE)
  927. {
  928. drawTextureSizeGraph();
  929. }
  930. else
  931. {
  932. drawTextureCategoryGraph() ;
  933. }
  934. LLView::draw();
  935. }
  936. BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask)
  937. {
  938. if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight)
  939. {
  940. mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ;
  941. }
  942. return TRUE ;
  943. }
  944. //draw real-time texture mem bar over size
  945. void LLTextureSizeView::drawTextureSizeGraph()
  946. {
  947. if(mTextureSizeBar.size() == 0)
  948. {
  949. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  950. mTextureSizeBar.resize(LLImageGL::sTextureLoadedCounter.size()) ;
  951. mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
  952. for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
  953. {
  954. mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
  955. line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
  956. }
  957. }
  958. F32 size_bar_scale = drawTextureSizeDistributionGraph() ;
  959. for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
  960. {
  961. mTextureSizeBar[i]->setTop(LLImageGL::sTextureLoadedCounter[i], LLImageGL::sTextureBoundCounter[i], size_bar_scale) ;
  962. mTextureSizeBar[i]->draw() ;
  963. }
  964. LLImageGL::resetCurTexSizebar();
  965. }
  966. //draw background of texture size bar graph
  967. F32 LLTextureSizeView::drawTextureSizeDistributionGraph()
  968. {
  969. //scale
  970. F32 scale = 1.0f ;
  971. LLGLSUIDefault gls_ui;
  972. {
  973. S32 count = 0 ;
  974. for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++)
  975. {
  976. if(LLImageGL::sTextureLoadedCounter[i] > count)
  977. {
  978. count = LLImageGL::sTextureLoadedCounter[i] ;
  979. }
  980. }
  981. if(count > mTextureSizeBarRect.getHeight())
  982. {
  983. scale = (F32)mTextureSizeBarRect.getHeight() / count ;
  984. }
  985. }
  986. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  987. S32 left = mTextureSizeBarRect.mLeft ;
  988. S32 bottom = mTextureSizeBarRect.mBottom ;
  989. S32 right = mTextureSizeBarRect.mRight ;
  990. S32 top = mTextureSizeBarRect.mTop ;
  991. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  992. //background rect
  993. gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
  994. //--------------------------------------------------
  995. gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
  996. gl_line_2d(left, bottom, right, bottom) ; //x axis
  997. gl_line_2d(left, bottom, left, top) ; //y axis
  998. //ruler
  999. //--------------------------------------------------
  1000. gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
  1001. for(S32 i = bottom + 50 ; i <= top ; i += 50)
  1002. {
  1003. gl_line_2d(left, i, right, i) ;
  1004. }
  1005. //texts
  1006. //--------------------------------------------------
  1007. F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
  1008. std::string text;
  1009. //-------
  1010. //x axis: size label
  1011. text = llformat("%d", 0) ;
  1012. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
  1013. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1014. for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
  1015. {
  1016. text = llformat("%d", (1 << (i / 2)) + ((i & 1) ? ((1 << (i / 2)) >> 1) : 0)) ;
  1017. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
  1018. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1019. }
  1020. text = llformat("(w + h)/2") ;
  1021. LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 10, bottom - line_height / 2,
  1022. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1023. //-------
  1024. //y axis: number label
  1025. for(S32 i = bottom + 50 ; i <= top ; i += 50)
  1026. {
  1027. text = llformat("%d", (S32)((i - bottom) / scale)) ;
  1028. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
  1029. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1030. LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
  1031. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1032. }
  1033. //--------------------------------------------------
  1034. F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
  1035. gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
  1036. text = llformat("Loaded") ;
  1037. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
  1038. loaded_color, LLFontGL::LEFT, LLFontGL::TOP);
  1039. F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
  1040. gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
  1041. text = llformat("Bound") ;
  1042. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
  1043. bound_color, LLFontGL::LEFT, LLFontGL::TOP);
  1044. //--------------------------------------------------
  1045. //title
  1046. text = llformat("Texture Size Distribution") ;
  1047. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
  1048. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1049. return scale ;
  1050. }
  1051. //draw real-time texture mem bar over category
  1052. void LLTextureSizeView::drawTextureCategoryGraph()
  1053. {
  1054. if(mTextureSizeBar.size() == 0)
  1055. {
  1056. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  1057. mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ;
  1058. mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
  1059. for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
  1060. {
  1061. mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
  1062. line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
  1063. }
  1064. }
  1065. F32 size_bar_scale = drawTextureCategoryDistributionGraph() ;
  1066. for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
  1067. {
  1068. U32 k = LLViewerTexture::getIndexFromCategory(i) ;
  1069. mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ;
  1070. mTextureSizeBar[i]->draw() ;
  1071. }
  1072. LLImageGL::resetCurTexSizebar();
  1073. }
  1074. //draw background for TEXTURE_MEM_OVER_CATEGORY
  1075. F32 LLTextureSizeView::drawTextureCategoryDistributionGraph()
  1076. {
  1077. //scale
  1078. F32 scale = 4.0f ;
  1079. LLGLSUIDefault gls_ui;
  1080. {
  1081. S32 count = 0 ;
  1082. for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++)
  1083. {
  1084. S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ;
  1085. if(tmp > count)
  1086. {
  1087. count = tmp ;
  1088. }
  1089. }
  1090. if(count > mTextureSizeBarRect.getHeight() * 0.25f)
  1091. {
  1092. scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ;
  1093. }
  1094. }
  1095. S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
  1096. S32 left = mTextureSizeBarRect.mLeft ;
  1097. S32 bottom = mTextureSizeBarRect.mBottom ;
  1098. S32 right = mTextureSizeBarRect.mRight ;
  1099. S32 top = mTextureSizeBarRect.mTop ;
  1100. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1101. //background rect
  1102. gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
  1103. //--------------------------------------------------
  1104. gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
  1105. gl_line_2d(left, bottom, right, bottom) ; //x axis
  1106. gl_line_2d(left, bottom, left, top) ; //y axis
  1107. //ruler
  1108. //--------------------------------------------------
  1109. gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
  1110. for(S32 i = bottom + 50 ; i <= top ; i += 50)
  1111. {
  1112. gl_line_2d(left, i, right, i) ;
  1113. }
  1114. //texts
  1115. //--------------------------------------------------
  1116. F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
  1117. std::string text;
  1118. //-------
  1119. //x axis: size label
  1120. static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] =
  1121. {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ;
  1122. text = llformat("%s", category[0]) ;
  1123. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
  1124. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1125. for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
  1126. {
  1127. text = llformat("%s", category[i]) ;
  1128. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
  1129. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1130. }
  1131. //-------
  1132. //y axis: number label
  1133. for(S32 i = bottom + 50 ; i <= top ; i += 50)
  1134. {
  1135. text = llformat("%d", (S32)((i - bottom) / scale)) ;
  1136. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
  1137. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1138. LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
  1139. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1140. }
  1141. text = llformat("MB") ;
  1142. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 ,
  1143. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1144. //--------------------------------------------------
  1145. F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
  1146. gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
  1147. text = llformat("Loaded") ;
  1148. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
  1149. loaded_color,
  1150. LLFontGL::LEFT, LLFontGL::TOP);
  1151. F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
  1152. gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
  1153. text = llformat("Bound") ;
  1154. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
  1155. bound_color, LLFontGL::LEFT, LLFontGL::TOP);
  1156. //--------------------------------------------------
  1157. //title
  1158. text = llformat("Texture Category Distribution") ;
  1159. LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
  1160. text_color, LLFontGL::LEFT, LLFontGL::TOP);
  1161. return scale ;
  1162. }